class Gem::SpecificationRecord

常量

NOT_FOUND

表示“未找到”存根的哨兵对象

公共类方法

dirs_from(paths) 点击切换源代码
# File rubygems/specification_record.rb, line 5
def self.dirs_from(paths)
  paths.map do |path|
    File.join(path, "specifications")
  end
end
from_path(path) 点击切换源代码
# File rubygems/specification_record.rb, line 11
def self.from_path(path)
  new(dirs_from([path]))
end
new(dirs) 点击切换源代码
# File rubygems/specification_record.rb, line 15
def initialize(dirs)
  @all = nil
  @stubs = nil
  @stubs_by_name = {}
  @spec_with_requirable_file = {}
  @active_stub_with_requirable_file = {}

  @dirs = dirs
end

公共实例方法

add_spec(spec) 点击切换源代码

spec 添加到记录中,保持集合的正确排序。

# File rubygems/specification_record.rb, line 78
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() 点击切换源代码

返回记录中所有规范的列表

# File rubygems/specification_record.rb, line 32
def all
  @all ||= stubs.map(&:to_spec)
end
all=(specs) 点击切换源代码

将记录已知的规范设置为 specs

# File rubygems/specification_record.rb, line 101
def all=(specs)
  @stubs_by_name = specs.group_by(&:name)
  @all = @stubs = specs
end
all_names() 点击切换源代码

按排序顺序返回记录中所有规范的完整名称。

# File rubygems/specification_record.rb, line 109
def all_names
  all.map(&:full_name)
end
each() { |x| ... } 点击切换源代码

枚举每个已知的规范。

# File rubygems/specification_record.rb, line 118
def each
  return enum_for(:each) unless block_given?

  all.each do |x|
    yield x
  end
end
find_active_stub_by_path(path) 点击切换源代码

返回记录中已激活的,且包含匹配 path 的文件的最佳规范。

# File rubygems/specification_record.rb, line 173
def find_active_stub_by_path(path)
  stub = @active_stub_with_requirable_file[path] ||= stubs.find do |s|
    s.activated? && s.contains_requirable_file?(path)
  end || NOT_FOUND

  stub.this
end
find_all_by_name(name, *requirements) 点击切换源代码

返回记录中匹配 name 和可选的 requirements 的每个规范。

# File rubygems/specification_record.rb, line 129
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) 点击切换源代码

返回记录中包含匹配 path 的文件的最佳规范。

# File rubygems/specification_record.rb, line 148
def find_by_path(path)
  path = path.dup.freeze
  spec = @spec_with_requirable_file[path] ||= stubs.find do |s|
    s.contains_requirable_file? path
  end || NOT_FOUND

  spec.to_spec
end
find_inactive_by_path(path) 点击切换源代码

返回记录中未激活的,且包含匹配 path 的文件的最佳规范。

# File rubygems/specification_record.rb, line 161
def find_inactive_by_path(path)
  stub = stubs.find do |s|
    next if s.activated?
    s.contains_requirable_file? path
  end
  stub&.to_spec
end
latest_spec_for(name) 点击切换源代码

返回记录中 gem name 的最新安装规范。

# File rubygems/specification_record.rb, line 192
def latest_spec_for(name)
  latest_specs(true).find {|installed_spec| installed_spec.name == name }
end
latest_specs(prerelease) 点击切换源代码

返回记录中的最新规范,如果 prerelease 为 true,则可选地包括预发布规范。

# File rubygems/specification_record.rb, line 185
def latest_specs(prerelease)
  Gem::Specification._latest_specs stubs, prerelease
end
remove_spec(spec) 点击切换源代码

从记录中删除 spec

# File rubygems/specification_record.rb, line 92
def remove_spec(spec)
  all.delete spec.to_spec
  stubs.delete spec
  (@stubs_by_name[spec.name] || []).delete spec
end
stubs() 点击切换源代码

为记录中的每个规范返回一个 Gem::StubSpecification

# File rubygems/specification_record.rb, line 39
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) 点击切换源代码

为记录中名为 name 的每个规范返回一个 Gem::StubSpecification,仅返回匹配 Gem.platforms 的存根

# File rubygems/specification_record.rb, line 53
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) 点击切换源代码

在记录中查找与模式匹配的存根规范,可以选择过滤掉不匹配当前平台的规范

# File rubygems/specification_record.rb, line 67
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

私有实例方法

installed_stubs(pattern) 点击切换源代码
# File rubygems/specification_record.rb, line 198
def installed_stubs(pattern)
  map_stubs(pattern) do |path, base_dir, gems_dir|
    Gem::StubSpecification.gemspec_stub(path, base_dir, gems_dir)
  end
end
map_stubs(pattern) { |path, base_dir, gems_dir| ... } 点击切换源代码
# File rubygems/specification_record.rb, line 204
def map_stubs(pattern)
  @dirs.flat_map do |dir|
    base_dir = File.dirname dir
    gems_dir = File.join base_dir, "gems"
    Gem::Specification.gemspec_stubs_in(dir, pattern) {|path| yield path, base_dir, gems_dir }
  end
end