Class | Gem::GemPathSearcher |
In: |
lib/rubygems/gem_path_searcher.rb
|
Parent: | Object |
GemPathSearcher has the capability to find loadable files inside gems. It generates data up front to speed up searches later.
Initialise the data we need to make searches later.
# File lib/rubygems/gem_path_searcher.rb, line 10 10: def initialize 11: # We want a record of all the installed gemspecs, in the order we wish to 12: # examine them. 13: # TODO: remove this stupid method 14: @gemspecs = init_gemspecs 15: 16: # Map gem spec to glob of full require_path directories. Preparing this 17: # information may speed up searches later. 18: @lib_dirs = {} 19: 20: @gemspecs.each do |spec| 21: @lib_dirs[spec.object_id] = lib_dirs_for spec 22: end 23: end
Look in all the installed gems until a matching glob is found. Return the gemspec of the gem where it was found. If no match is found, return nil.
The gems are searched in alphabetical order, and in reverse version order.
For example:
find('log4r') # -> (log4r-1.1 spec) find('log4r.rb') # -> (log4r-1.1 spec) find('rake/rdoctask') # -> (rake-0.4.12 spec) find('foobarbaz') # -> nil
Matching paths can have various suffixes (’.rb’, ’.so’, and others), which may or may not already be attached to file. This method doesn‘t care about the full filename that matches; only that there is a match.
# File lib/rubygems/gem_path_searcher.rb, line 45 45: def find(glob) 46: # HACK violation of encapsulation 47: @gemspecs.find do |spec| 48: # TODO: inverted responsibility 49: matching_file? spec, glob 50: end 51: end
# File lib/rubygems/gem_path_searcher.rb, line 53 53: def find_active(glob) 54: # HACK violation of encapsulation 55: @gemspecs.find do |spec| 56: # TODO: inverted responsibility 57: spec.loaded? and matching_file? spec, glob 58: end 59: end
# File lib/rubygems/gem_path_searcher.rb, line 72 72: def find_in_unresolved(glob) 73: # HACK violation 74: specs = Gem.unresolved_deps.values.map { |dep| 75: Gem.source_index.search dep, true 76: }.flatten 77: 78: specs.select do |spec| 79: # TODO: inverted responsibility 80: matching_file? spec, glob 81: end || [] 82: end
# File lib/rubygems/gem_path_searcher.rb, line 84 84: def find_in_unresolved_tree glob 85: # HACK violation 86: # TODO: inverted responsibility 87: specs = Gem.unresolved_deps.values.map { |dep| 88: Gem.source_index.search dep, true 89: }.flatten 90: 91: specs.reverse_each do |spec| 92: trails = matching_paths(spec, glob) 93: next if trails.empty? 94: return trails.map(&:reverse).sort.first.reverse 95: end 96: 97: [] 98: end
Return a list of all installed gemspecs, sorted by alphabetical order and in reverse version order. (bar-2, bar-1, foo-2)
# File lib/rubygems/gem_path_searcher.rb, line 134 134: def init_gemspecs 135: specs = Gem.source_index.map { |_, spec| spec } 136: 137: specs.sort { |a, b| 138: names = a.name <=> b.name 139: next names if names.nonzero? 140: b.version <=> a.version 141: } 142: end
Returns library directories glob for a gemspec. For example,
'/usr/local/lib/ruby/gems/1.8/gems/foobar-1.0/{lib,ext}'
# File lib/rubygems/gem_path_searcher.rb, line 148 148: def lib_dirs_for(spec) 149: "#{spec.full_gem_path}/{#{spec.require_paths.join(',')}}" if 150: spec.require_paths 151: end
Returns files matching path in spec.
# File lib/rubygems/gem_path_searcher.rb, line 124 124: def matching_files(spec, path) 125: return [] unless @lib_dirs[spec.object_id] # case no paths 126: glob = File.join @lib_dirs[spec.object_id], "#{path}#{Gem.suffix_pattern}" 127: Dir[glob].select { |f| File.file? f.untaint } 128: end
# File lib/rubygems/gem_path_searcher.rb, line 108 108: def matching_paths(spec, path) 109: trails = [] 110: 111: spec.traverse do |from_spec, dep, to_spec, trail| 112: next unless to_spec.conflicts.empty? 113: trails << trail unless matching_files(to_spec, path).empty? 114: end 115: 116: trails 117: end