Class: Gem::SourceIndex
- Inherits:
-
Object
- Object
- Gem::SourceIndex
- Extended by:
- UserInteraction
- Includes:
- Enumerable, UserInteraction
- Defined in:
- lib/rubygems/source_index.rb
Overview
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. |
Instance Attribute Summary (collapse)
-
- (Object) gems
readonly
:nodoc:.
-
- (Object) spec_dirs
Directories to use to refresh this SourceIndex when calling refresh!.
Class Method Summary (collapse)
-
+ (Object) from_gems_in(*spec_dirs)
Creates a new SourceIndex from the ruby format gem specifications in spec_dirs.
-
+ (Object) from_installed_gems(*deprecated)
Factory method to construct a source index instance for a given path.
-
+ (Object) installed_spec_directories
Returns a list of directories from Gem.path that contain specifications.
-
+ (Object) load_specification(file_name)
Loads a ruby-format specification from file_name and returns the loaded spec.
Instance Method Summary (collapse)
-
- (Object) ==(other)
:nodoc:.
-
- (Object) add_spec(gem_spec, name = gem_spec.full_name)
Add a gem specification to the source index.
-
- (Object) add_specs(*gem_specs)
Add gem specifications to the source index.
-
- (Object) all_gems
TODO: remove method.
- - (Object) dump
-
- (Object) each(&block)
Iterate over the specifications in the source index.
-
- (Object) find_name(gem_name, requirement = Gem::Requirement.default)
Find a gem by an exact match on the short name.
-
- (Object) gem_signature(gem_full_name)
The signature for the given gem specification.
-
- (Object) index_signature
The signature for the source index.
-
- (SourceIndex) initialize(specifications = {})
constructor
Constructs a source index instance from the provided specifications, which is a Hash of gem full names and Gem::Specifications.
-
- (Object) latest_specs
Returns an Array specifications for the latest released versions of each gem in this index.
-
- (Object) load_gems_in(*spec_dirs)
Reconstruct the source index from the specifications in spec_dirs.
-
- (Object) outdated
Returns an Array of Gem::Specifications that are not up to date.
- - (Object) prerelease_gems
-
- (Object) prerelease_specs
An array including only the prerelease gemspecs.
-
- (Object) refresh!
Replaces the gems in the source index from specifications in the directories this source index was created from.
- - (Object) released_gems
-
- (Object) released_specs
An array including only the released gemspecs.
-
- (Object) remove_spec(full_name)
Remove a gem specification named full_name.
-
- (Object) search(gem_pattern, platform_only = false)
Search for a gem by Gem::Dependency gem_pattern.
- - (Object) size (also: #length)
-
- (Object) specification(full_name)
The gem specification given a full gem spec name.
-
- (Object) update(source_uri, all)
Updates this SourceIndex from source_uri.
Methods included from UserInteraction
Methods included from DefaultUserInteraction
ui, #ui, #ui=, ui=, use_ui, #use_ui
Methods included from Enumerable
Constructor Details
- (SourceIndex) initialize(specifications = {})
Constructs a source index instance from the provided specifications, which is a Hash of gem full names and Gem::Specifications. -- TODO merge @gems and @prerelease_gems and provide a separate method #prerelease_gems
92 93 94 95 96 |
# File 'lib/rubygems/source_index.rb', line 92 def initialize(specifications={}) @gems = {} specifications.each{ |full_name, spec| add_spec spec } @spec_dirs = nil end |
Instance Attribute Details
- (Object) gems (readonly)
:nodoc:
27 28 29 |
# File 'lib/rubygems/source_index.rb', line 27 def gems @gems end |
- (Object) spec_dirs
Directories to use to refresh this SourceIndex when calling refresh!
32 33 34 |
# File 'lib/rubygems/source_index.rb', line 32 def spec_dirs @spec_dirs end |
Class Method Details
+ (Object) from_gems_in(*spec_dirs)
Creates a new SourceIndex from the ruby format gem specifications in spec_dirs.
69 70 71 72 73 |
# File 'lib/rubygems/source_index.rb', line 69 def from_gems_in(*spec_dirs) source_index = new source_index.spec_dirs = spec_dirs source_index.refresh! end |
+ (Object) from_installed_gems(*deprecated)
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 |
50 51 52 53 54 55 56 |
# File 'lib/rubygems/source_index.rb', line 50 def from_installed_gems(*deprecated) if deprecated.empty? from_gems_in(*installed_spec_directories) else from_gems_in(*deprecated) # HACK warn end end |
+ (Object) installed_spec_directories
Returns a list of directories from Gem.path that contain specifications.
61 62 63 |
# File 'lib/rubygems/source_index.rb', line 61 def installed_spec_directories Gem.path.collect { |dir| File.join(dir, "specifications") } end |
+ (Object) load_specification(file_name)
Loads a ruby-format specification from file_name and returns the loaded spec.
79 80 81 |
# File 'lib/rubygems/source_index.rb', line 79 def load_specification(file_name) Gem::Specification.load file_name end |
Instance Method Details
- (Object) ==(other)
:nodoc:
384 385 386 |
# File 'lib/rubygems/source_index.rb', line 384 def ==(other) # :nodoc: self.class === other and @gems == other.gems end |
- (Object) add_spec(gem_spec, name = gem_spec.full_name)
Add a gem specification to the source index.
183 184 185 186 187 |
# File 'lib/rubygems/source_index.rb', line 183 def add_spec(gem_spec, name = gem_spec.full_name) # No idea why, but the Indexer wants to insert them using original_name # instead of full_name. So we make it an optional arg. @gems[name] = gem_spec end |
- (Object) add_specs(*gem_specs)
Add gem specifications to the source index.
192 193 194 195 196 |
# File 'lib/rubygems/source_index.rb', line 192 def add_specs(*gem_specs) gem_specs.each do |spec| add_spec spec end end |
- (Object) all_gems
TODO: remove method
99 100 101 |
# File 'lib/rubygems/source_index.rb', line 99 def all_gems @gems end |
- (Object) dump
388 389 390 |
# File 'lib/rubygems/source_index.rb', line 388 def dump Marshal.dump(self) end |
- (Object) each(&block)
Iterate over the specifications in the source index.
208 209 210 |
# File 'lib/rubygems/source_index.rb', line 208 def each(&block) # :yields: gem.full_name, gem @gems.each(&block) end |
- (Object) find_name(gem_name, requirement = Gem::Requirement.default)
Find a gem by an exact match on the short name.
246 247 248 249 |
# File 'lib/rubygems/source_index.rb', line 246 def find_name(gem_name, requirement = Gem::Requirement.default) dep = Gem::Dependency.new gem_name, requirement search dep end |
- (Object) gem_signature(gem_full_name)
The signature for the given gem specification.
232 233 234 235 236 |
# File 'lib/rubygems/source_index.rb', line 232 def gem_signature(gem_full_name) require 'digest' Digest::SHA256.new.hexdigest(@gems[gem_full_name].to_yaml).to_s end |
- (Object) index_signature
The signature for the source index. Changes in the signature indicate a change in the index.
223 224 225 226 227 |
# File 'lib/rubygems/source_index.rb', line 223 def index_signature require 'digest' Digest::SHA256.new.hexdigest(@gems.keys.sort.join(',')).to_s end |
- (Object) latest_specs
Returns an Array specifications for the latest released versions of each gem in this index.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/rubygems/source_index.rb', line 133 def latest_specs result = Hash.new { |h,k| h[k] = [] } latest = {} sort.each do |_, spec| name = spec.name curr_ver = spec.version prev_ver = latest.key?(name) ? latest[name].version : nil next if curr_ver.prerelease? next unless prev_ver.nil? or curr_ver >= prev_ver or latest[name].platform != Gem::Platform::RUBY if prev_ver.nil? or (curr_ver > prev_ver and spec.platform == Gem::Platform::RUBY) then result[name].clear latest[name] = spec end if spec.platform != Gem::Platform::RUBY then result[name].delete_if do |result_spec| result_spec.platform == spec.platform end end result[name] << spec end # TODO: why is this a hash while @gems is an array? Seems like # structural similarity would be good. result.values.flatten end |
- (Object) load_gems_in(*spec_dirs)
Reconstruct the source index from the specifications in spec_dirs.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/rubygems/source_index.rb', line 114 def load_gems_in(*spec_dirs) @gems.clear spec_dirs.reverse_each do |spec_dir| spec_files = Dir.glob File.join(spec_dir, '*.gemspec') spec_files.each do |spec_file| gemspec = Gem::Specification.load spec_file add_spec gemspec if gemspec end end self end |
- (Object) outdated
Returns an Array of Gem::Specifications that are not up to date.
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'lib/rubygems/source_index.rb', line 319 def outdated outdateds = [] latest_specs.each do |local| dependency = Gem::Dependency.new local.name, ">= #{local.version}" begin fetcher = Gem::SpecFetcher.fetcher remotes = fetcher.find_matching dependency remotes = remotes.map { |(_, version, _), _| version } rescue Gem::RemoteFetcher::FetchError => e raise unless fetcher.warn_legacy e do require 'rubygems/source_info_cache' specs = Gem::SourceInfoCache.search_with_source dependency, true remotes = specs.map { |spec,| spec.version } end end latest = remotes.sort.last outdateds << local.name if latest and local.version < latest end outdateds end |
- (Object) prerelease_gems
103 104 105 |
# File 'lib/rubygems/source_index.rb', line 103 def prerelease_gems @gems.reject{ |name, gem| !gem.version.prerelease? } end |
- (Object) prerelease_specs
An array including only the prerelease gemspecs
169 170 171 |
# File 'lib/rubygems/source_index.rb', line 169 def prerelease_specs prerelease_gems.values end |
- (Object) refresh!
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).
311 312 313 314 |
# File 'lib/rubygems/source_index.rb', line 311 def refresh! raise 'source index not created from disk' if @spec_dirs.nil? load_gems_in(*@spec_dirs) end |
- (Object) released_gems
107 108 109 |
# File 'lib/rubygems/source_index.rb', line 107 def released_gems @gems.reject{ |name, gem| gem.version.prerelease? } end |
- (Object) released_specs
An array including only the released gemspecs
176 177 178 |
# File 'lib/rubygems/source_index.rb', line 176 def released_specs released_gems.values end |
- (Object) remove_spec(full_name)
Remove a gem specification named full_name.
201 202 203 |
# File 'lib/rubygems/source_index.rb', line 201 def remove_spec(full_name) @gems.delete full_name end |
- (Object) search(gem_pattern, platform_only = false)
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.
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 |
# File 'lib/rubygems/source_index.rb', line 260 def search(gem_pattern, platform_only = false) requirement = nil only_platform = false # TODO - Remove support and warning for legacy arguments after 2008/11 unless Gem::Dependency === gem_pattern warn "#{Gem.location_of_caller.join ':'}:Warning: Gem::SourceIndex#search support for #{gem_pattern.class} patterns is deprecated, use #find_name" end case gem_pattern when Regexp then requirement = platform_only || Gem::Requirement.default when Gem::Dependency then only_platform = platform_only requirement = gem_pattern.requirement gem_pattern = if Regexp === gem_pattern.name then gem_pattern.name elsif gem_pattern.name.empty? then // else /^#{Regexp.escape gem_pattern.name}$/ end else requirement = platform_only || Gem::Requirement.default gem_pattern = /#{gem_pattern}/i end unless Gem::Requirement === requirement then requirement = Gem::Requirement.create requirement end specs = all_gems.values.select do |spec| spec.name =~ gem_pattern and requirement.satisfied_by? spec.version end if only_platform then specs = specs.select do |spec| Gem::Platform.match spec.platform end end specs.sort_by { |s| s.sort_obj } end |
- (Object) size Also known as: length
238 239 240 |
# File 'lib/rubygems/source_index.rb', line 238 def size @gems.size end |
- (Object) specification(full_name)
The gem specification given a full gem spec name.
215 216 217 |
# File 'lib/rubygems/source_index.rb', line 215 def specification(full_name) @gems[full_name] end |
- (Object) update(source_uri, all)
Updates this SourceIndex from source_uri. If all is false, only the latest gems are fetched.
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 |
# File 'lib/rubygems/source_index.rb', line 351 def update(source_uri, all) source_uri = URI.parse source_uri unless URI::Generic === source_uri source_uri.path += '/' unless source_uri.path =~ /\/$/ use_incremental = false begin gem_names = fetch_quick_index source_uri, all remove_extra gem_names missing_gems = find_missing gem_names return false if missing_gems.size.zero? say "Missing metadata for #{missing_gems.size} gems" if missing_gems.size > 0 and Gem.configuration.really_verbose use_incremental = missing_gems.size <= Gem.configuration.bulk_threshold rescue Gem::OperationNotSupportedError => ex alert_error "Falling back to bulk fetch: #{ex.}" if Gem.configuration.really_verbose use_incremental = false end if use_incremental then update_with_missing(source_uri, missing_gems) else new_index = fetch_bulk_index(source_uri) @gems.replace(new_index.gems) end true end |