Class Gem::SourceIndex
In: lib/rubygems/source_index.rb
Parent: Object

The SourceIndex object indexes all the gems available from a particular source (e.g. a list of gem directories, or a remote source). A SourceIndex maps a gem full name to a gem specification.

NOTE:The class used to be named Cache, but that became confusing when cached source fetchers where introduced. The constant Gem::Cache is an alias for this class to allow old YAMLized source index objects to load properly.

Methods

Included Modules

Enumerable

Attributes

spec_dirs  [RW]  Directories to use to refresh this SourceIndex when calling refresh!

Public Class methods

Creates a new SourceIndex from the ruby format gem specifications in spec_dirs.

[Source]

    # File lib/rubygems/source_index.rb, line 66
66:   def self.from_gems_in(*spec_dirs)
67:     new spec_dirs
68:   end

Factory method to construct a source index instance for a given path.

deprecated:If supplied, from_installed_gems will act just like from_gems_in. This argument is deprecated and is provided just for backwards compatibility, and should not generally be used.
return:SourceIndex instance

[Source]

    # File lib/rubygems/source_index.rb, line 45
45:   def self.from_installed_gems(*deprecated)
46:     if deprecated.empty?
47:       from_gems_in(*installed_spec_directories)
48:     else
49:       warn "NOTE: from_installed_gems(arg) is deprecated. From #{caller.first}"
50:       from_gems_in(*deprecated) # HACK warn
51:     end
52:   end

Returns a list of directories from Gem.path that contain specifications.

[Source]

    # File lib/rubygems/source_index.rb, line 57
57:   def self.installed_spec_directories
58:     # TODO: move to Gem::Utils
59:     Gem.path.collect { |dir| File.join(dir, "specifications") }
60:   end

Loads a ruby-format specification from file_name and returns the loaded spec.

[Source]

    # File lib/rubygems/source_index.rb, line 74
74:   def self.load_specification(file_name)
75:     Gem::Deprecate.skip_during do
76:       Gem::Specification.load Gem::Path.new(file_name)
77:     end
78:   end

Constructs a source index instance from the provided specifications, which is a Hash of gem full names and Gem::Specifications.

[Source]

     # File lib/rubygems/source_index.rb, line 84
 84:   def initialize specs_or_dirs = []
 85:     @gems = {}
 86:     @spec_dirs = nil
 87: 
 88:     case specs_or_dirs
 89:     when Hash then
 90:       specs_or_dirs.each do |full_name, spec|
 91:         add_spec spec
 92:       end
 93:     when Array, String then
 94:       self.spec_dirs = Array(specs_or_dirs)
 95:       refresh!
 96:     else
 97:       arg = specs_or_dirs.inspect
 98:       warn "NOTE: SourceIndex.new(#{arg}) is deprecated; From #{caller.first}."
 99:     end
100:   end

Public Instance methods

Add a gem specification to the source index.

[Source]

     # File lib/rubygems/source_index.rb, line 186
186:   def add_spec(gem_spec, name = gem_spec.full_name)
187:     # No idea why, but the Indexer wants to insert them using original_name
188:     # instead of full_name. So we make it an optional arg.
189:     @gems[name] = gem_spec
190:   end

Add gem specifications to the source index.

[Source]

     # File lib/rubygems/source_index.rb, line 195
195:   def add_specs(*gem_specs)
196:     Gem::Deprecate.skip_during do
197:       gem_specs.each do |spec|
198:         add_spec spec
199:       end
200:     end
201:   end

[Source]

     # File lib/rubygems/source_index.rb, line 102
102:   def all_gems
103:     gems
104:   end

[Source]

     # File lib/rubygems/source_index.rb, line 350
350:   def dump
351:     Marshal.dump(self)
352:   end

Iterate over the specifications in the source index.

[Source]

     # File lib/rubygems/source_index.rb, line 213
213:   def each(&block) # :yields: gem.full_name, gem
214:     @gems.each(&block)
215:   end

Find a gem by an exact match on the short name.

[Source]

     # File lib/rubygems/source_index.rb, line 251
251:   def find_name(gem_name, requirement = Gem::Requirement.default)
252:     dep = Gem::Dependency.new gem_name, requirement
253: 
254:     Gem::Deprecate.skip_during do
255:       search dep
256:     end
257:   end

The signature for the given gem specification.

[Source]

     # File lib/rubygems/source_index.rb, line 237
237:   def gem_signature(gem_full_name)
238:     require 'digest'
239: 
240:     Digest::SHA256.new.hexdigest(@gems[gem_full_name].to_yaml).to_s
241:   end

The signature for the source index. Changes in the signature indicate a change in the index.

[Source]

     # File lib/rubygems/source_index.rb, line 228
228:   def index_signature
229:     require 'digest'
230: 
231:     Digest::SHA256.new.hexdigest(@gems.keys.sort.join(',')).to_s
232:   end

Returns an Array specifications for the latest released versions of each gem in this index.

[Source]

     # File lib/rubygems/source_index.rb, line 138
138:   def latest_specs(include_prerelease=false)
139:     result = Hash.new { |h,k| h[k] = [] }
140:     latest = {}
141: 
142:     sort.each do |_, spec|
143:       name = spec.name
144:       curr_ver = spec.version
145:       prev_ver = latest.key?(name) ? latest[name].version : nil
146: 
147:       next if !include_prerelease && curr_ver.prerelease?
148:       next unless prev_ver.nil? or curr_ver >= prev_ver or
149:                   latest[name].platform != Gem::Platform::RUBY
150: 
151:       if prev_ver.nil? or
152:          (curr_ver > prev_ver and spec.platform == Gem::Platform::RUBY) then
153:         result[name].clear
154:         latest[name] = spec
155:       end
156: 
157:       if spec.platform != Gem::Platform::RUBY then
158:         result[name].delete_if do |result_spec|
159:           result_spec.platform == spec.platform
160:         end
161:       end
162: 
163:       result[name] << spec
164:     end
165: 
166:     result.values.flatten
167:   end
length()

Alias for size

Reconstruct the source index from the specifications in spec_dirs.

[Source]

     # File lib/rubygems/source_index.rb, line 117
117:   def load_gems_in(*spec_dirs)
118:     @gems.clear
119: 
120:     spec_dirs.reverse_each do |spec_dir|
121:       spec_files = Dir[File.join(spec_dir, "*.gemspec")]
122: 
123:       spec_files.each do |spec_file|
124:         gemspec = Gem::Deprecate.skip_during do
125:           Gem::Specification.load spec_file
126:         end
127:         add_spec gemspec if gemspec
128:       end
129:     end
130: 
131:     self
132:   end

Returns an Array of Gem::Specifications that are not up to date.

[Source]

     # File lib/rubygems/source_index.rb, line 328
328:   def outdated
329:     outdateds = []
330: 
331:     latest_specs.each do |local|
332:       dependency = Gem::Dependency.new local.name, ">= #{local.version}"
333: 
334:       fetcher = Gem::SpecFetcher.fetcher
335:       remotes = fetcher.find_matching dependency
336:       remotes = remotes.map { |(_, version, _), _| version }
337: 
338:       latest = remotes.sort.last
339: 
340:       outdateds << local.name if latest and local.version < latest
341:     end
342: 
343:     outdateds
344:   end

[Source]

     # File lib/rubygems/source_index.rb, line 106
106:   def prerelease_gems
107:     @gems.reject { |name, gem| !gem.version.prerelease? }
108:   end

An array including only the prerelease gemspecs

[Source]

     # File lib/rubygems/source_index.rb, line 172
172:   def prerelease_specs
173:     prerelease_gems.values
174:   end

Replaces the gems in the source index from specifications in the directories this source index was created from. Raises an exception if this source index wasn‘t created from a directory (via from_gems_in or from_installed_gems, or having spec_dirs set).

[Source]

     # File lib/rubygems/source_index.rb, line 320
320:   def refresh!
321:     raise 'source index not created from disk' if @spec_dirs.nil?
322:     load_gems_in(*@spec_dirs)
323:   end

[Source]

     # File lib/rubygems/source_index.rb, line 110
110:   def released_gems
111:     @gems.reject { |name, gem| gem.version.prerelease? }
112:   end

An array including only the released gemspecs

[Source]

     # File lib/rubygems/source_index.rb, line 179
179:   def released_specs
180:     released_gems.values
181:   end

Remove a gem specification named full_name.

[Source]

     # File lib/rubygems/source_index.rb, line 206
206:   def remove_spec(full_name)
207:     @gems.delete full_name
208:   end

Search for a gem by Gem::Dependency gem_pattern. If only_platform is true, only gems matching Gem::Platform.local will be returned. An Array of matching Gem::Specification objects is returned.

For backwards compatibility, a String or Regexp pattern may be passed as gem_pattern, and a Gem::Requirement for platform_only. This behavior is deprecated and will be removed.

[Source]

     # File lib/rubygems/source_index.rb, line 268
268:   def search(gem_pattern, platform_or_requirement = false)
269:     requirement = nil
270:     only_platform = false # FIX: WTF is this?!?
271: 
272:     # TODO - Remove support and warning for legacy arguments after 2008/11
273:     unless Gem::Dependency === gem_pattern
274:       warn "#{Gem.location_of_caller.join ':'}:Warning: Gem::SourceIndex#search support for #{gem_pattern.class} patterns is deprecated, use #find_name"
275:     end
276: 
277:     case gem_pattern
278:     when Regexp then
279:       requirement = platform_or_requirement || Gem::Requirement.default
280:     when Gem::Dependency then
281:       only_platform = platform_or_requirement
282:       requirement = gem_pattern.requirement
283: 
284:       gem_pattern = if Regexp === gem_pattern.name then
285:                       gem_pattern.name
286:                     elsif gem_pattern.name.empty? then
287:                       //
288:                     else
289:                       /^#{Regexp.escape gem_pattern.name}$/
290:                     end
291:     else
292:       requirement = platform_or_requirement || Gem::Requirement.default
293:       gem_pattern = /#{gem_pattern}/i
294:     end
295: 
296:     unless Gem::Requirement === requirement then
297:       requirement = Gem::Requirement.create requirement
298:     end
299: 
300:     specs = @gems.values.select do |spec|
301:       spec.name =~ gem_pattern and
302:         requirement.satisfied_by? spec.version
303:     end
304: 
305:     if only_platform then
306:       specs = specs.select do |spec|
307:         Gem::Platform.match spec.platform
308:       end
309:     end
310: 
311:     specs.sort_by { |s| s.sort_obj }
312:   end

[Source]

     # File lib/rubygems/source_index.rb, line 243
243:   def size
244:     @gems.size
245:   end

The gem specification given a full gem spec name.

[Source]

     # File lib/rubygems/source_index.rb, line 220
220:   def specification(full_name)
221:     @gems[full_name]
222:   end

[Validate]