Class: Gem::SourceIndex
- Inherits:
-
Object
- Object
- Gem::SourceIndex
- Includes:
- Enumerable
- Defined in:
- lib/yard/rubygems/backports/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
-
#gems ⇒ Object
readonly
:nodoc:.
-
#spec_dirs ⇒ Object
Directories to use to refresh this SourceIndex when calling refresh!.
Class Method Summary collapse
-
.from_gems_in(*spec_dirs) ⇒ Object
Creates a new SourceIndex from the ruby format gem specifications in
spec_dirs
. -
.from_installed_gems(*deprecated) ⇒ Object
Factory method to construct a source index instance for a given path.
-
.installed_spec_directories ⇒ Object
Returns a list of directories from Gem.path that contain specifications.
-
.load_specification(file_name) ⇒ Object
Loads a ruby-format specification from
file_name
and returns the loaded spec.
Instance Method Summary collapse
-
#==(other) ⇒ Object
:nodoc:.
-
#add_spec(gem_spec, name = gem_spec.full_name) ⇒ Object
Add a gem specification to the source index.
-
#add_specs(*gem_specs) ⇒ Object
Add gem specifications to the source index.
-
#all_gems ⇒ Object
TODO: remove method.
- #dump ⇒ Object
-
#each(&block) ⇒ Object
Iterate over the specifications in the source index.
-
#find_name(gem_name, requirement = Gem::Requirement.default) ⇒ Object
Find a gem by an exact match on the short name.
-
#gem_signature(gem_full_name) ⇒ Object
The signature for the given gem specification.
-
#index_signature ⇒ Object
The signature for the source index.
-
#initialize(specifications = {}) ⇒ SourceIndex
constructor
Constructs a source index instance from the provided specifications, which is a Hash of gem full names and Gem::Specifications.
-
#latest_specs(include_prerelease = false) ⇒ Object
Returns an Array specifications for the latest released versions of each gem in this index.
-
#load_gems_in(*spec_dirs) ⇒ Object
Reconstruct the source index from the specifications in
spec_dirs
. -
#old_initialize ⇒ Object
Undef old methods.
-
#outdated ⇒ Object
Returns an Array of Gem::Specifications that are not up to date.
- #prerelease_gems ⇒ Object
-
#prerelease_specs ⇒ Object
An array including only the prerelease gemspecs.
-
#refresh! ⇒ Object
Replaces the gems in the source index from specifications in the directories this source index was created from.
- #released_gems ⇒ Object
-
#released_specs ⇒ Object
An array including only the released gemspecs.
-
#remove_spec(full_name) ⇒ Object
Remove a gem specification named
full_name
. -
#search(gem_pattern, platform_only = false) ⇒ Object
Search for a gem by Gem::Dependency
gem_pattern
. - #size ⇒ Object (also: #length)
-
#specification(full_name) ⇒ Object
The gem specification given a full gem spec name.
Constructor Details
#initialize(specifications = {}) ⇒ SourceIndex
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
102 103 104 105 106 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 102 def initialize(specifications = {}) @gems = {} specifications.each {|_full_name, spec| add_spec spec } @spec_dirs = nil end |
Instance Attribute Details
#gems ⇒ Object (readonly)
:nodoc:
34 35 36 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 34 def gems @gems end |
#spec_dirs ⇒ Object
Directories to use to refresh this SourceIndex when calling refresh!
39 40 41 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 39 def spec_dirs @spec_dirs end |
Class Method Details
.from_gems_in(*spec_dirs) ⇒ Object
Creates a new SourceIndex from the ruby format gem specifications in spec_dirs
.
80 81 82 83 84 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 80 def from_gems_in(*spec_dirs) source_index = new source_index.spec_dirs = spec_dirs source_index.refresh! end |
.from_installed_gems(*deprecated) ⇒ Object
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
61 62 63 64 65 66 67 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 61 def from_installed_gems(*deprecated) if deprecated.empty? from_gems_in(*installed_spec_directories) else from_gems_in(*deprecated) # HACK: warn end end |
.installed_spec_directories ⇒ Object
Returns a list of directories from Gem.path that contain specifications.
72 73 74 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 72 def installed_spec_directories Gem.path.collect {|dir| File.join(dir, "specifications") } end |
.load_specification(file_name) ⇒ Object
Loads a ruby-format specification from file_name
and returns the loaded spec.
90 91 92 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 90 def load_specification(file_name) Gem::Specification.load file_name end |
Instance Method Details
#==(other) ⇒ Object
:nodoc:
348 349 350 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 348 def ==(other) # :nodoc: self.class === other && @gems == other.gems end |
#add_spec(gem_spec, name = gem_spec.full_name) ⇒ Object
Add a gem specification to the source index.
193 194 195 196 197 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 193 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 |
#add_specs(*gem_specs) ⇒ Object
Add gem specifications to the source index.
202 203 204 205 206 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 202 def add_specs(*gem_specs) gem_specs.each do |spec| add_spec spec end end |
#all_gems ⇒ Object
TODO: remove method
109 110 111 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 109 def all_gems @gems end |
#dump ⇒ Object
352 353 354 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 352 def dump Marshal.dump(self) end |
#each(&block) ⇒ Object
Iterate over the specifications in the source index.
218 219 220 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 218 def each(&block) # :yields: gem.full_name, gem @gems.each(&block) end |
#find_name(gem_name, requirement = Gem::Requirement.default) ⇒ Object
Find a gem by an exact match on the short name.
256 257 258 259 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 256 def find_name(gem_name, requirement = Gem::Requirement.default) dep = Gem::Dependency.new gem_name, requirement search dep end |
#gem_signature(gem_full_name) ⇒ Object
The signature for the given gem specification.
242 243 244 245 246 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 242 def gem_signature(gem_full_name) require 'digest' Digest::SHA256.new.hexdigest(@gems[gem_full_name].to_yaml).to_s end |
#index_signature ⇒ Object
The signature for the source index. Changes in the signature indicate a change in the index.
233 234 235 236 237 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 233 def index_signature require 'digest' Digest::SHA256.new.hexdigest(@gems.keys.sort.join(',')).to_s end |
#latest_specs(include_prerelease = false) ⇒ Object
Returns an Array specifications for the latest released versions of each gem in this index.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 143 def latest_specs(include_prerelease = false) 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 !include_prerelease && curr_ver.prerelease? next unless prev_ver.nil? || curr_ver >= prev_ver || latest[name].platform != Gem::Platform::RUBY if prev_ver.nil? || (curr_ver > prev_ver && spec.platform == Gem::Platform::RUBY) result[name].clear latest[name] = spec end if spec.platform != Gem::Platform::RUBY 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 |
#load_gems_in(*spec_dirs) ⇒ Object
Reconstruct the source index from the specifications in spec_dirs
.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 124 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 |
#old_initialize ⇒ Object
Undef old methods
23 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 23 alias old_initialize initialize |
#outdated ⇒ Object
Returns an Array of Gem::Specifications that are not up to date.
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 330 def outdated outdateds = [] latest_specs.each do |local| dependency = Gem::Dependency.new local.name, ">= #{local.version}" fetcher = Gem::SpecFetcher.fetcher remotes = fetcher.find_matching dependency remotes = remotes.map {|(_, version, _), _| version } latest = remotes.sort.last outdateds << local.name if latest && local.version < latest end outdateds end |
#prerelease_gems ⇒ Object
113 114 115 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 113 def prerelease_gems @gems.reject {|_name, gem| !gem.version.prerelease? } end |
#prerelease_specs ⇒ Object
An array including only the prerelease gemspecs
179 180 181 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 179 def prerelease_specs prerelease_gems.values end |
#refresh! ⇒ Object
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).
322 323 324 325 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 322 def refresh! raise 'source index not created from disk' if @spec_dirs.nil? load_gems_in(*@spec_dirs) end |
#released_gems ⇒ Object
117 118 119 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 117 def released_gems @gems.reject {|_name, gem| gem.version.prerelease? } end |
#released_specs ⇒ Object
An array including only the released gemspecs
186 187 188 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 186 def released_specs released_gems.values end |
#remove_spec(full_name) ⇒ Object
Remove a gem specification named full_name
.
211 212 213 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 211 def remove_spec(full_name) @gems.delete full_name end |
#search(gem_pattern, platform_only = false) ⇒ Object
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.
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 304 305 306 307 308 309 310 311 312 313 314 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 270 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 gem_pattern.name elsif gem_pattern.name.empty? // else /^#{Regexp.escape gem_pattern.name}$/ end else requirement = platform_only || Gem::Requirement.default gem_pattern = /#{gem_pattern}/i end unless Gem::Requirement === requirement requirement = Gem::Requirement.create requirement end specs = all_gems.values.select do |spec| spec.name =~ gem_pattern && requirement.satisfied_by?(spec.version) end if only_platform specs = specs.select do |spec| Gem::Platform.match spec.platform end end specs.sort_by(&:sort_obj) end |
#size ⇒ Object Also known as: length
248 249 250 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 248 def size @gems.size end |
#specification(full_name) ⇒ Object
The gem specification given a full gem spec name.
225 226 227 |
# File 'lib/yard/rubygems/backports/source_index.rb', line 225 def specification(full_name) @gems[full_name] end |