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. |
spec_dirs | [RW] | Directories to use to refresh this SourceIndex when calling refresh! |
Creates a new SourceIndex from the ruby format gem specifications in spec_dirs.
# File lib/rubygems/source_index.rb, line 64 64: def from_gems_in(*spec_dirs) 65: source_index = new 66: source_index.spec_dirs = spec_dirs 67: source_index.refresh! 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 |
# File lib/rubygems/source_index.rb, line 45 45: def from_installed_gems(*deprecated) 46: if deprecated.empty? 47: from_gems_in(*installed_spec_directories) 48: else 49: from_gems_in(*deprecated) # HACK warn 50: end 51: end
Returns a list of directories from Gem.path that contain specifications.
# File lib/rubygems/source_index.rb, line 56 56: def installed_spec_directories 57: Gem.path.collect { |dir| File.join(dir, "specifications") } 58: end
Loads a ruby-format specification from file_name and returns the loaded spec.
# File lib/rubygems/source_index.rb, line 74 74: def load_specification(file_name) 75: Gem::Specification.load file_name 76: end
Constructs a source index instance from the provided specifications, which is a Hash of gem full names and Gem::Specifications.
# File lib/rubygems/source_index.rb, line 87 87: def initialize(specifications={}) 88: @gems = {} 89: specifications.each{ |full_name, spec| add_spec spec } 90: @spec_dirs = nil 91: end
Add a gem specification to the source index.
# File lib/rubygems/source_index.rb, line 178 178: def add_spec(gem_spec, name = gem_spec.full_name) 179: # No idea why, but the Indexer wants to insert them using original_name 180: # instead of full_name. So we make it an optional arg. 181: @gems[name] = gem_spec 182: end
Add gem specifications to the source index.
# File lib/rubygems/source_index.rb, line 187 187: def add_specs(*gem_specs) 188: gem_specs.each do |spec| 189: add_spec spec 190: end 191: end
Iterate over the specifications in the source index.
# File lib/rubygems/source_index.rb, line 203 203: def each(&block) # :yields: gem.full_name, gem 204: @gems.each(&block) 205: end
Find a gem by an exact match on the short name.
# File lib/rubygems/source_index.rb, line 241 241: def find_name(gem_name, requirement = Gem::Requirement.default) 242: dep = Gem::Dependency.new gem_name, requirement 243: search dep 244: end
The signature for the given gem specification.
# File lib/rubygems/source_index.rb, line 227 227: def gem_signature(gem_full_name) 228: require 'digest' 229: 230: Digest::SHA256.new.hexdigest(@gems[gem_full_name].to_yaml).to_s 231: end
The signature for the source index. Changes in the signature indicate a change in the index.
# File lib/rubygems/source_index.rb, line 218 218: def index_signature 219: require 'digest' 220: 221: Digest::SHA256.new.hexdigest(@gems.keys.sort.join(',')).to_s 222: end
Returns an Array specifications for the latest released versions of each gem in this index.
# File lib/rubygems/source_index.rb, line 128 128: def latest_specs 129: result = Hash.new { |h,k| h[k] = [] } 130: latest = {} 131: 132: sort.each do |_, spec| 133: name = spec.name 134: curr_ver = spec.version 135: prev_ver = latest.key?(name) ? latest[name].version : nil 136: 137: next if curr_ver.prerelease? 138: next unless prev_ver.nil? or curr_ver >= prev_ver or 139: latest[name].platform != Gem::Platform::RUBY 140: 141: if prev_ver.nil? or 142: (curr_ver > prev_ver and spec.platform == Gem::Platform::RUBY) then 143: result[name].clear 144: latest[name] = spec 145: end 146: 147: if spec.platform != Gem::Platform::RUBY then 148: result[name].delete_if do |result_spec| 149: result_spec.platform == spec.platform 150: end 151: end 152: 153: result[name] << spec 154: end 155: 156: # TODO: why is this a hash while @gems is an array? Seems like 157: # structural similarity would be good. 158: result.values.flatten 159: end
Reconstruct the source index from the specifications in spec_dirs.
# File lib/rubygems/source_index.rb, line 109 109: def load_gems_in(*spec_dirs) 110: @gems.clear 111: 112: spec_dirs.reverse_each do |spec_dir| 113: spec_files = Dir.glob File.join(spec_dir, '*.gemspec') 114: 115: spec_files.each do |spec_file| 116: gemspec = Gem::Specification.load spec_file 117: add_spec gemspec if gemspec 118: end 119: end 120: 121: self 122: end
Returns an Array of Gem::Specifications that are not up to date.
# File lib/rubygems/source_index.rb, line 314 314: def outdated 315: outdateds = [] 316: 317: latest_specs.each do |local| 318: dependency = Gem::Dependency.new local.name, ">= #{local.version}" 319: 320: fetcher = Gem::SpecFetcher.fetcher 321: remotes = fetcher.find_matching dependency 322: remotes = remotes.map { |(_, version, _), _| version } 323: 324: latest = remotes.sort.last 325: 326: outdateds << local.name if latest and local.version < latest 327: end 328: 329: outdateds 330: end
# File lib/rubygems/source_index.rb, line 98 98: def prerelease_gems 99: @gems.reject{ |name, gem| !gem.version.prerelease? } 100: end
An array including only the prerelease gemspecs
# File lib/rubygems/source_index.rb, line 164 164: def prerelease_specs 165: prerelease_gems.values 166: 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).
# File lib/rubygems/source_index.rb, line 306 306: def refresh! 307: raise 'source index not created from disk' if @spec_dirs.nil? 308: load_gems_in(*@spec_dirs) 309: end
# File lib/rubygems/source_index.rb, line 102 102: def released_gems 103: @gems.reject{ |name, gem| gem.version.prerelease? } 104: end
An array including only the released gemspecs
# File lib/rubygems/source_index.rb, line 171 171: def released_specs 172: released_gems.values 173: end
Remove a gem specification named full_name.
# File lib/rubygems/source_index.rb, line 196 196: def remove_spec(full_name) 197: @gems.delete full_name 198: 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.
# File lib/rubygems/source_index.rb, line 255 255: def search(gem_pattern, platform_only = false) 256: requirement = nil 257: only_platform = false 258: 259: # TODO - Remove support and warning for legacy arguments after 2008/11 260: unless Gem::Dependency === gem_pattern 261: warn "#{Gem.location_of_caller.join ':'}:Warning: Gem::SourceIndex#search support for #{gem_pattern.class} patterns is deprecated, use #find_name" 262: end 263: 264: case gem_pattern 265: when Regexp then 266: requirement = platform_only || Gem::Requirement.default 267: when Gem::Dependency then 268: only_platform = platform_only 269: requirement = gem_pattern.requirement 270: gem_pattern = if Regexp === gem_pattern.name then 271: gem_pattern.name 272: elsif gem_pattern.name.empty? then 273: // 274: else 275: /^#{Regexp.escape gem_pattern.name}$/ 276: end 277: else 278: requirement = platform_only || Gem::Requirement.default 279: gem_pattern = /^#{gem_pattern}/i 280: end 281: 282: unless Gem::Requirement === requirement then 283: requirement = Gem::Requirement.create requirement 284: end 285: 286: specs = all_gems.values.select do |spec| 287: spec.name =~ gem_pattern and 288: requirement.satisfied_by? spec.version 289: end 290: 291: if only_platform then 292: specs = specs.select do |spec| 293: Gem::Platform.match spec.platform 294: end 295: end 296: 297: specs.sort_by { |s| s.sort_obj } 298: end
The gem specification given a full gem spec name.
# File lib/rubygems/source_index.rb, line 210 210: def specification(full_name) 211: @gems[full_name] 212: end