Class: Gem::SourceIndex
- Inherits:
-
Object
- Object
- Gem::SourceIndex
- Extended by:
- Forwardable, 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.
Constant Summary collapse
- INCREMENTAL_THRESHHOLD =
50
Class Method Summary collapse
-
.from_gems_in(*spec_dirs) ⇒ Object
Factory method to construct a source index instance for a given path.
-
.from_installed_gems(*deprecated) ⇒ Object
Factory method to construct a source index instance for a given path.
-
.installed_spec_directories ⇒ Object
Return a list of directories in the current gem path that contain specifications.
-
.load_specification(file_name) ⇒ Object
Load a specification from a file (eval’d Ruby code).
Instance Method Summary collapse
-
#add_spec(gem_spec) ⇒ Object
Add a gem specification to the source index.
-
#each(&block) ⇒ Object
Iterate over the specifications in the source index.
-
#find_name(gem_name, version_requirement = Version::Requirement.new(">= 0")) ⇒ 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.
-
#latest_specs ⇒ Object
Returns a Hash of name => Specification of the latest versions of each gem in this index.
-
#load_gems_in(*spec_dirs) ⇒ Object
Reconstruct the source index from the list of source directories.
-
#outdated ⇒ Object
Returns an Array of Gem::Specifications that are not up to date.
-
#refresh! ⇒ Object
Refresh the source index from the local file system.
-
#remove_spec(full_name) ⇒ Object
Remove a gem specification named
full_name
. -
#search(gem_pattern, version_requirement = Version::Requirement.new(">= 0")) ⇒ Object
Search for a gem by short name pattern and optional version.
-
#specification(full_name) ⇒ Object
The gem specification given a full gem spec name.
- #update(source_uri) ⇒ Object
Methods included from DefaultUserInteraction
#ui, ui, #ui=, ui=, #use_ui, use_ui
Constructor Details
#initialize(specifications = {}) ⇒ SourceIndex
Constructs a source index instance from the provided specifications
- specifications
- Hash
-
hash of [Gem name, Gem::Specification] pairs
118 119 120 |
# File 'lib/rubygems/source_index.rb', line 118 def initialize(specifications={}) @gems = specifications end |
Class Method Details
.from_gems_in(*spec_dirs) ⇒ Object
Factory method to construct a source index instance for a
given path.
- spec_dirs
-
List of directories to search for specifications. Each directory should have a “specifications” subdirectory containing the gem specifications.
- return
-
SourceIndex instance
80 81 82 |
# File 'lib/rubygems/source_index.rb', line 80 def from_gems_in(*spec_dirs) self.new.load_gems_in(*spec_dirs) 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
51 52 53 54 55 56 57 |
# File 'lib/rubygems/source_index.rb', line 51 def from_installed_gems(*deprecated) if deprecated.empty? from_gems_in(*installed_spec_directories) else from_gems_in(*deprecated) end end |
.installed_spec_directories ⇒ Object
Return a list of directories in the current gem path that contain specifications.
- return
-
List of directory paths (all ending in “../specifications”).
65 66 67 |
# File 'lib/rubygems/source_index.rb', line 65 def installed_spec_directories Gem.path.collect { |dir| File.join(dir, "specifications") } end |
.load_specification(file_name) ⇒ Object
Load a specification from a file (eval’d Ruby code)
- file_name
- String
-
The .gemspec file
- return
-
Specification instance or nil if an error occurs
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/rubygems/source_index.rb', line 89 def load_specification(file_name) begin spec_code = File.read(file_name).untaint gemspec = eval(spec_code) if gemspec.is_a?(Gem::Specification) gemspec.loaded_from = file_name return gemspec end alert_warning "File '#{file_name}' does not evaluate to a gem specification" rescue SyntaxError => e alert_warning e alert_warning spec_code rescue Exception => e alert_warning(e.inspect.to_s + "\n" + spec_code) alert_warning "Invalid .gemspec format in '#{file_name}'" end return nil end |
Instance Method Details
#add_spec(gem_spec) ⇒ Object
Add a gem specification to the source index.
152 153 154 |
# File 'lib/rubygems/source_index.rb', line 152 def add_spec(gem_spec) @gems[gem_spec.full_name] = gem_spec end |
#each(&block) ⇒ Object
Iterate over the specifications in the source index.
- &block
- yields gem.full_name, Gem::Specification
165 166 167 |
# File 'lib/rubygems/source_index.rb', line 165 def each(&block) @gems.each(&block) end |
#find_name(gem_name, version_requirement = Version::Requirement.new(">= 0")) ⇒ Object
Find a gem by an exact match on the short name.
188 189 190 |
# File 'lib/rubygems/source_index.rb', line 188 def find_name(gem_name, version_requirement=Version::Requirement.new(">= 0")) search(/^#{gem_name}$/, version_requirement) end |
#gem_signature(gem_full_name) ⇒ Object
The signature for the given gem specification.
181 182 183 |
# File 'lib/rubygems/source_index.rb', line 181 def gem_signature(gem_full_name) Digest::SHA256.new(@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.
176 177 178 |
# File 'lib/rubygems/source_index.rb', line 176 def index_signature Digest::SHA256.new(@gems.keys.sort.join(',')).to_s end |
#latest_specs ⇒ Object
Returns a Hash of name => Specification of the latest versions of each gem in this index.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/rubygems/source_index.rb', line 136 def latest_specs thin = {} each do |full_name, spec| name = spec.name if thin.has_key? name then thin[name] = spec if spec.version > thin[name].version else thin[name] = spec end end thin end |
#load_gems_in(*spec_dirs) ⇒ Object
Reconstruct the source index from the list of source directories.
124 125 126 127 128 129 130 131 132 |
# File 'lib/rubygems/source_index.rb', line 124 def load_gems_in(*spec_dirs) @gems.clear specs = Dir.glob File.join("{#{spec_dirs.join(',')}}", "*.gemspec") specs.each do |file_name| gemspec = self.class.load_specification(file_name.untaint) add_spec(gemspec) if gemspec end self end |
#outdated ⇒ Object
Returns an Array of Gem::Specifications that are not up to date.
226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/rubygems/source_index.rb', line 226 def outdated remotes = Gem::SourceInfoCache.search(//) outdateds = [] latest_specs.each do |_, local| name = local.name remote = remotes.select { |spec| spec.name == name }. sort_by { |spec| spec.version }. last outdateds << name if remote and local.version < remote.version end outdateds end |
#refresh! ⇒ Object
Refresh the source index from the local file system.
- return
-
Returns a pointer to itself.
220 221 222 |
# File 'lib/rubygems/source_index.rb', line 220 def refresh! load_gems_in(self.class.installed_spec_directories) end |
#remove_spec(full_name) ⇒ Object
Remove a gem specification named full_name
.
157 158 159 |
# File 'lib/rubygems/source_index.rb', line 157 def remove_spec(full_name) @gems.delete(full_name) end |
#search(gem_pattern, version_requirement = Version::Requirement.new(">= 0")) ⇒ Object
Search for a gem by short name pattern and optional version
- gem_name
- String
-
a partial for the (short) name of the gem, or
- Regex
-
a pattern to match against the short name
- version_requirement
- String | default=Version::Requirement.new(“>= 0”)
-
version to
find
- return
- Array
-
list of Gem::Specification objects in sorted (version)
order. Empty if not found.
204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/rubygems/source_index.rb', line 204 def search(gem_pattern, version_requirement=Version::Requirement.new(">= 0")) gem_pattern = /#{ gem_pattern }/i if String === gem_pattern version_requirement = Gem::Version::Requirement.create(version_requirement) result = [] @gems.each do |full_spec_name, spec| next unless spec.name =~ gem_pattern result << spec if version_requirement.satisfied_by?(spec.version) end result = result.sort result end |
#specification(full_name) ⇒ Object
The gem specification given a full gem spec name.
170 171 172 |
# File 'lib/rubygems/source_index.rb', line 170 def specification(full_name) @gems[full_name] end |
#update(source_uri) ⇒ Object
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/rubygems/source_index.rb', line 239 def update(source_uri) use_incremental = false begin gem_names = fetch_quick_index source_uri remove_extra gem_names missing_gems = find_missing gem_names use_incremental = missing_gems.size <= INCREMENTAL_THRESHHOLD rescue Gem::OperationNotSupportedError => ex 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 self end |