Class: Gem::SpecificationRecord
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Instance Chain:
self,
Enumerable
|
|
| Inherits: | Object |
| Defined in: | lib/rubygems/specification_record.rb |
Constant Summary
-
NOT_FOUND =
private
# File 'lib/rubygems/specification_record.rb', line 64
Sentinel object to represent "not found" stubs
Struct.new(:to_spec, :this).new
Class Method Summary
-
.abi_scoped_spec_dir?(dir) ⇒ Boolean
Whether dir is an ABI-scoped spec dir (.../specifications/<ruby_abi>).
-
.dirs_from(paths)
Specificationdirectories for each path: the flatspecificationsdir and the ABI-scopedspecifications/subdir. -
.dirs_with_abi(dirs)
Ensure ABI-scoped subdirectories are present in
dirs. - .from_path(path)
- .new(dirs) ⇒ SpecificationRecord constructor
-
.specification_dir_for(spec, base_dir)
The spec dir for
specunderbase_dir: the ABI-scoped subdir for content-addressed specs, the flatspecificationsdir otherwise.
Instance Attribute Summary
-
#all
rw
Returns the list of all specifications in the record.
-
#all=(specs)
rw
Sets the specs known by the record to
specs.
Instance Method Summary
-
#add_spec(spec)
Adds
specto the record, keeping the collection properly sorted. -
#all_names
Return full names of all specs in the record in sorted order.
-
#each
Enumerate every known spec.
-
#find_active_stub_by_path(path)
Return the best specification in the record that contains the file matching path, among those already activated.
-
#find_all_by_name(name, *requirements)
Returns every spec in the record that matches
nameand optionalrequirements. -
#find_by_path(path)
Return the best specification in the record that contains the file matching path.
-
#find_inactive_by_path(path)
Return the best specification in the record that contains the file matching path amongst the specs that are not activated.
-
#find_unloaded_by_path(path)
Return the best specification that contains the file matching path amongst the specs that are not loaded.
-
#latest_spec_for(name)
Return the latest installed spec in the record for gem
name. -
#latest_specs(prerelease)
Return the latest specs in the record, optionally including prerelease specs if
prereleaseis true. -
#remove_spec(spec)
Removes
specfrom the record. -
#stubs
Returns a
StubSpecificationfor every specification in the record. -
#stubs_for(name)
Returns a
StubSpecificationfor every specification in the record namednameonly returns stubs that match platforms -
#stubs_for_pattern(pattern, match_platform = true)
Finds stub specifications matching a pattern in the record, optionally filtering out specs not matching the current platform.
- #installed_stubs(pattern) private
- #map_stubs(pattern) private
Constructor Details
.new(dirs) ⇒ SpecificationRecord
# File 'lib/rubygems/specification_record.rb', line 53
def initialize(dirs) @all = nil @stubs = nil @stubs_by_name = {} @spec_with_requirable_file = {} @active_stub_with_requirable_file = {} @dirs = dirs end
Class Method Details
.abi_scoped_spec_dir?(dir) ⇒ Boolean
Whether Gem.dir is an ABI-scoped spec dir
(.../specifications/<ruby_abi>). Requires the parent to be
named specifications to avoid false positives.
# File 'lib/rubygems/specification_record.rb', line 21
def self.abi_scoped_spec_dir?(dir) Gem::ContentAddress.valid_ruby_abi?(File.basename(dir)) && File.basename(File.dirname(dir)) == "specifications" end
.dirs_from(paths)
Specification directories for each path: the flat specifications
dir and the ABI-scoped specifications/ subdir.
.dirs_with_abi(dirs)
Ensure ABI-scoped subdirectories are present in dirs. No-op when
dirs already includes them (e.g. MRI); expands flat-only dirs
.from_path(path)
[ GitHub ].specification_dir_for(spec, base_dir)
The spec dir for spec under base_dir: the ABI-scoped subdir for
content-addressed specs, the flat specifications dir otherwise.
# File 'lib/rubygems/specification_record.rb', line 29
def self.specification_dir_for(spec, base_dir) dir = File.join(base_dir, "specifications") dir = File.join(dir, spec.ruby_abi) if Gem::ContentAddress.content_addressed?(spec) dir end
Instance Attribute Details
#all (rw)
Returns the list of all specifications in the record
# File 'lib/rubygems/specification_record.rb', line 70
def all @all ||= stubs.map(&:to_spec) end
#all=(specs) (rw)
Sets the specs known by the record to specs.
# File 'lib/rubygems/specification_record.rb', line 139
def all=(specs) @stubs_by_name = specs.group_by(&:name) @all = @stubs = specs end
Instance Method Details
#add_spec(spec)
Adds spec to the record, keeping the collection properly sorted.
# File 'lib/rubygems/specification_record.rb', line 116
def add_spec(spec) return if all.include? spec all << spec stubs << spec (@stubs_by_name[spec.name] ||= []) << spec Gem::Specification._resort!(@stubs_by_name[spec.name]) Gem::Specification._resort!(stubs) end
#all_names
Return full names of all specs in the record in sorted order.
# File 'lib/rubygems/specification_record.rb', line 147
def all_names all.map(&:full_name) end
#each
Enumerate every known spec.
# File 'lib/rubygems/specification_record.rb', line 156
def each return enum_for(:each) unless block_given? all.each do |x| yield x end end
#find_active_stub_by_path(path)
Return the best specification in the record that contains the file matching Gem.path, among those already activated.
#find_all_by_name(name, *requirements)
Returns every spec in the record that matches name and optional requirements.
# File 'lib/rubygems/specification_record.rb', line 167
def find_all_by_name(name, *requirements) req = Gem::Requirement.create(*requirements) env_req = Gem.env_requirement(name) matches = stubs_for(name).find_all do |spec| req.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version) end.map(&:to_spec) if name == "bundler" && !req.specific? require_relative "bundler_version_finder" Gem::BundlerVersionFinder.prioritize!(matches) end matches end
#find_by_path(path)
Return the best specification in the record that contains the file matching Gem.path.
#find_inactive_by_path(path)
Return the best specification in the record that contains the file matching Gem.path amongst the specs that are not activated.
#find_unloaded_by_path(path)
Return the best specification that contains the file matching Gem.path amongst the specs that are not loaded. This method is different than #find_inactive_by_path as it will filter out loaded specs by their name.
# File 'lib/rubygems/specification_record.rb', line 200
def find_unloaded_by_path(path) stub = stubs.find do |s| next if Gem.loaded_specs[s.name] s.contains_requirable_file? path end stub&.to_spec end
#installed_stubs(pattern) (private)
[ GitHub ]# File 'lib/rubygems/specification_record.rb', line 249
def installed_stubs(pattern) map_stubs(pattern) do |path, base_dir, gems_dir| Gem::StubSpecification.gemspec_stub(path, base_dir, gems_dir) end end
#latest_spec_for(name)
Return the latest installed spec in the record for gem name.
# File 'lib/rubygems/specification_record.rb', line 243
def latest_spec_for(name) latest_specs(true).find {|installed_spec| installed_spec.name == name } end
#latest_specs(prerelease)
Return the latest specs in the record, optionally including prerelease
specs if prerelease is true.
# File 'lib/rubygems/specification_record.rb', line 236
def latest_specs(prerelease) Gem::Specification._latest_specs stubs, prerelease end
#map_stubs(pattern) (private)
[ GitHub ]# File 'lib/rubygems/specification_record.rb', line 255
def map_stubs(pattern) @dirs.flat_map do |dir| base_dir = File.dirname dir base_dir = File.dirname base_dir if self.class.abi_scoped_spec_dir?(dir) gems_dir = File.join base_dir, "gems" Gem::Specification.gemspec_stubs_in(dir, pattern) {|path| yield path, base_dir, gems_dir } end end
#remove_spec(spec)
Removes spec from the record.
#stubs
Returns a StubSpecification for every specification in the record
# File 'lib/rubygems/specification_record.rb', line 77
def stubs @stubs ||= begin pattern = "*.gemspec" stubs = stubs_for_pattern(pattern, false) @stubs_by_name = stubs.select {|s| Gem::Platform.match_spec? s }.group_by(&:name) stubs end end
#stubs_for(name)
Returns a StubSpecification for every specification in the record
named name only returns stubs that match Gem.platforms
# File 'lib/rubygems/specification_record.rb', line 91
def stubs_for(name) if @stubs @stubs_by_name[name] || [] else @stubs_by_name[name] ||= stubs_for_pattern("#{name}-*.gemspec").select do |s| s.name == name end end end
#stubs_for_pattern(pattern, match_platform = true)
Finds stub specifications matching a pattern in the record, optionally filtering out specs not matching the current platform
# File 'lib/rubygems/specification_record.rb', line 105
def stubs_for_pattern(pattern, match_platform = true) installed_stubs = installed_stubs(pattern) installed_stubs.select! {|s| Gem::Platform.match_spec? s } if match_platform stubs = installed_stubs + Gem::Specification.default_stubs(pattern) Gem::Specification._resort!(stubs) stubs end