Class: LibGems::GemPathSearcher

Inherits:
Object
  • Object
show all
Defined in:
lib/libgems/gem_path_searcher.rb

Overview

LibGemsPathSearcher has the capability to find loadable files inside gems. It generates data up front to speed up searches later.

Instance Method Summary collapse

Constructor Details

#initializeGemPathSearcher

Initialise the data we need to make searches later.



10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/libgems/gem_path_searcher.rb', line 10

def initialize
  # We want a record of all the installed gemspecs, in the order we wish to
  # examine them.
  @gemspecs = init_gemspecs

  # Map gem spec to glob of full require_path directories.  Preparing this
  # information may speed up searches later.
  @lib_dirs = {}

  @gemspecs.each do |spec|
    @lib_dirs[spec.object_id] = lib_dirs_for spec
  end
end

Instance Method Details

#find(path) ⇒ Object

Look in all the installed gems until a matching path 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.



44
45
46
# File 'lib/libgems/gem_path_searcher.rb', line 44

def find(path)
  @gemspecs.find do |spec| matching_file? spec, path end
end

#find_all(path) ⇒ Object

Works like #find, but finds all gemspecs matching path.



51
52
53
54
55
# File 'lib/libgems/gem_path_searcher.rb', line 51

def find_all(path)
  @gemspecs.select do |spec|
    matching_file? spec, path
  end
end

#init_gemspecsObject

Return a list of all installed gemspecs, sorted by alphabetical order and in reverse version order. (bar-2, bar-1, foo-2)



80
81
82
83
84
85
86
87
88
# File 'lib/libgems/gem_path_searcher.rb', line 80

def init_gemspecs
  specs = LibGems.source_index.map { |_, spec| spec }

  specs.sort { |a, b|
    names = a.name <=> b.name
    next names if names.nonzero?
    b.version <=> a.version
  }
end

#lib_dirs_for(spec) ⇒ Object

Returns library directories glob for a gemspec. For example,

'/usr/local/lib/ruby/gems/1.8/gems/foobar-1.0/{lib,ext}'


94
95
96
97
# File 'lib/libgems/gem_path_searcher.rb', line 94

def lib_dirs_for(spec)
  "#{spec.full_gem_path}/{#{spec.require_paths.join(',')}}" if
    spec.require_paths
end

#matching_file?(spec, path) ⇒ Boolean

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

Returns:

  • (Boolean)


61
62
63
# File 'lib/libgems/gem_path_searcher.rb', line 61

def matching_file?(spec, path)
  !matching_files(spec, path).empty?
end

#matching_files(spec, path) ⇒ Object

Returns files matching path in spec. – Some of the intermediate results are cached in @lib_dirs for speed.



70
71
72
73
74
# File 'lib/libgems/gem_path_searcher.rb', line 70

def matching_files(spec, path)
  return [] unless @lib_dirs[spec.object_id] # case no paths
  glob = File.join @lib_dirs[spec.object_id], "#{path}#{LibGems.suffix_pattern}"
  Dir[glob].select { |f| File.file? f.untaint }
end