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.

Methods

Public Class methods

Initialise the data we need to make searches later.

[Source]

    # 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

Public Instance methods

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.

[Source]

    # 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

[Source]

    # 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

Works like find, but finds all gemspecs matching glob.

[Source]

    # File lib/rubygems/gem_path_searcher.rb, line 64
64:   def find_all(glob)
65:     # HACK violation of encapsulation
66:     @gemspecs.select do |spec|
67:       # TODO: inverted responsibility
68:       matching_file? spec, glob
69:     end || []
70:   end

[Source]

    # 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

[Source]

    # 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)

[Source]

     # 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}'

[Source]

     # 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

Attempts to find a matching path using the require_paths of the given spec.

[Source]

     # File lib/rubygems/gem_path_searcher.rb, line 104
104:   def matching_file?(spec, path)
105:     not matching_files(spec, path).empty?
106:   end

Returns files matching path in spec.

[Source]

     # 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

[Source]

     # 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

[Validate]