module Bundler::Plugin::API::Source

此类提供了构建源插件的基础。这里的所有方法都是构建源插件所必需的(除了“uri_hash`、`gem_install_dir`;它们是辅助方法)。

尽可能为方法提供了默认值,这些默认值有望能够工作。但是,所有源插件都必须覆盖“fetch_gemspec_files”和“install”。也没有为“remote!”、“cache!”和“unlock!”提供默认值。

默认值应适用于大多数情况,但仍然可以(最好应该)根据插件的需要安全地覆盖它们(只要它们的行为符合预期)。在覆盖“initialize”时,您应该首先调用 super。

如果需要,插件应覆盖“hash”、“==”和“eql?”方法,以便能够匹配表示相同源的对象,但这些对象可能在不同的情况下创建(例如,从 Gemfile 和 lockfile 中)。默认值仅检查类和 URI,但详细的源插件可能需要更多的比较(例如,对分支或标记进行 Git 检查)。

@!attribute [r] uri

@return [String] the remote specified with `source` block in Gemfile

@!attribute [r] options

@return [String] options passed during initialization (either from
  lockfile or Gemfile)

@!attribute [r] name

@return [String] name that can be used to uniquely identify a source

@!attribute [rw] dependency_names

@return [Array<String>] Names of dependencies that the source should
  try to resolve. It is not necessary to use this list internally. This
  is present to be compatible with `Definition` and is used by
  rubygems source.

属性

checksum_store[R]
dependency_names[RW]
name[R]
options[R]
uri[R]

公共类方法

new(opts) 点击以切换源
# File bundler/plugin/api/source.rb, line 45
def initialize(opts)
  @options = opts
  @dependency_names = []
  @uri = opts["uri"]
  @type = opts["type"]
  @name = opts["name"] || "#{@type} at #{@uri}"
  @checksum_store = Checksum::Store.new
end

公共实例方法

==(other) 点击以切换源

这将检查两个源对象是否代表同一个源。

比较应仅在可以从 Gemfile 传递的选项中推断出的属性上进行,而不是在用于将 gem 固定到特定版本的属性上进行(例如,Git 源应在分支和标记上进行比较,而不是在提交哈希上)。

源对象是从 Gemfile 和 lockfile 中构造的。为了使源收敛,它们必须匹配。

这同样适用于“eql?”和“hash”

# File bundler/plugin/api/source.rb, line 214
def ==(other)
  other.is_a?(self.class) && uri == other.uri
end
也别名为:eql?
add_dependency_names(names) 点击以切换源

由定义使用。

注意:如果您不知道自己在做什么,请不要覆盖。

# File bundler/plugin/api/source.rb, line 259
def add_dependency_names(names)
  @dependencies |= Array(names)
end
app_cache_dirname() 点击以切换源

当调用cache时,插件期望缓存 gem 的目录名称。

此名称也与缓存中的目录匹配以进行修剪

这由“app_cache_path”使用

# File bundler/plugin/api/source.rb, line 178
def app_cache_dirname
  base_name = File.basename(Gem::URI.parse(uri).normalize.path)
  "#{base_name}-#{uri_hash}"
end
app_cache_path(custom_path = nil) 点击以切换源

插件应缓存 gem 的完整路径,以便以后可以安装。

注意:如果您不知道自己在做什么,请不要覆盖。

# File bundler/plugin/api/source.rb, line 238
def app_cache_path(custom_path = nil)
  @app_cache_path ||= Bundler.app_cache(custom_path).join(app_cache_dirname)
end
cache(spec, custom_path = nil) 点击以切换源

在缓存期间调用此方法,以保存源可以解析到的 gem 的副本,该副本由“app_cache_app”提供的路径提供,以便可以从缓存中重新安装它们,而无需查询远程(即远程的替代方法)。

它与应用程序一起存储,并且当调用“cached!”时,源插件应尝试仅从此缓存中提供规范和安装。

此缓存与可以在“cache_path”(来自API)的子路径下完成的内部缓存不同。这可以被认为是 bundler 的缓存。

# File bundler/plugin/api/source.rb, line 194
def cache(spec, custom_path = nil)
  new_cache_path = app_cache_path(custom_path)

  FileUtils.rm_rf(new_cache_path)
  FileUtils.cp_r(install_path, new_cache_path)
  FileUtils.rm_rf(app_cache_path.join(".git"))
  FileUtils.touch(app_cache_path.join(".bundlecache"))
end
cached!() 点击以切换源

设置内部表示以从应用程序缓存中获取 gem/规范。

当调用此方法时,源应尝试从“app_cache_path”提供的路径中获取规范并进行安装。

# File bundler/plugin/api/source.rb, line 162
def cached!
end
can_lock?(spec) 点击以切换源

注意:如果您不知道自己在做什么,请不要覆盖。

# File bundler/plugin/api/source.rb, line 264
def can_lock?(spec)
  spec.source == self
end
double_check_for(*) 点击以切换源

@private 此API关于源可能不稳定,并且目前我们希望插件在“#specs”中下载所有规范,因此我们实现该方法是为了兼容性目的,并将其保持未记录(并且不支持)覆盖它)

# File bundler/plugin/api/source.rb, line 318
def double_check_for(*); end
eql?(other)

当覆盖“eql?”时,请保留“==”方法的文档字符串中提到的行为。

别名为:==
fetch_gemspec_files() 点击以切换源

默认的“spec”方法使用此方法来构造此源插件可以安装的 gem 和版本的 Specification 对象。

注意:如果覆盖了 spec 方法,则此函数不是必需的

@return [Array<String>] 可以安装的 gem 的 gemspec 文件的路径

be installed
# File bundler/plugin/api/source.rb, line 62
def fetch_gemspec_files
  []
end
gem_install_dir() 点击以切换源

注意:如果您不知道自己在做什么,请不要覆盖。

# File bundler/plugin/api/source.rb, line 300
def gem_install_dir
  Bundler.install_path
end
hash() 点击以切换源

当覆盖“hash”时,请保留“==”方法的文档字符串中提到的行为,即,通过上述比较相等的两个方法应具有相同的哈希值。

# File bundler/plugin/api/source.rb, line 225
def hash
  [self.class, uri].hash
end
identifier()
别名为:to_s
include?(other) 点击以切换源

注意:如果您不知道自己在做什么,请不要覆盖。

# File bundler/plugin/api/source.rb, line 291
def include?(other)
  other == self
end
install(spec, opts) 点击以切换源

在适当的路径下安装由规范指定的 gem。“install_path”提供了一个足够好的默认值,如果源只能满足一个 gem,但不是绑定的。

@return [String] 安装后消息(如果有)

# File bundler/plugin/api/source.rb, line 82
def install(spec, opts)
  raise MalformattedPlugin, "Source plugins need to override the install method."
end
install_path() 点击以切换源

安装单个 gem 的默认安装路径。如果源服务多个 gem,则它的用途不大,并且源应使用其自己的路径。

# File bundler/plugin/api/source.rb, line 107
def install_path
  @install_path ||=
    begin
      base_name = File.basename(Gem::URI.parse(uri).normalize.path)

      gem_install_dir.join("#{base_name}-#{uri_hash[0..11]}")
    end
end
installed?() 点击以切换源

一个辅助方法,如果内部未使用,则不是必需的。

# File bundler/plugin/api/source.rb, line 230
def installed?
  File.directory?(install_path)
end
local!() 点击以切换源

设置内部表示以在本地获取 gem/规范。

调用此方法后,源应尝试从本地系统获取规范并进行安装。

# File bundler/plugin/api/source.rb, line 148
def local!
end
options_to_lock() 点击以切换源

要保存在 lockfile 中的选项,以便源插件稍后能够检出相同版本的 gem。

从 lock 文件创建源插件时会传递这些选项。

@return [Hash]

# File bundler/plugin/api/source.rb, line 73
def options_to_lock
  {}
end
post_install(spec, disable_exts = false) 点击以切换源

它为提供的规范构建扩展,生成 bin 并安装它们。

它依赖于“spec.loaded_from”来获取 full_gem_path。源插件应设置该属性。

在插件将 gem 放置在正确的安装位置后,应在“install”中调用此方法。

它还会运行Gem钩子“pre_install”、“post_build”和“post_install”

注意:如果您不知道自己在做什么,请不要覆盖。

# File bundler/plugin/api/source.rb, line 98
def post_install(spec, disable_exts = false)
  opts = { env_shebang: false, disable_extensions: disable_exts }
  installer = Bundler::Source::Path::Installer.new(spec, opts)
  installer.post_install
end
remote!() 点击以切换源

设置内部表示以从远程获取 gem/规范。

调用此方法后,源应尝试从远程路径获取规范并进行安装。

# File bundler/plugin/api/source.rb, line 155
def remote!
end
root() 点击以切换源

它用于获取 full_gem_path。

spec 的 loaded_from 路径将根据此路径展开,以获取 full_gem_path

注意:如果您不知道自己在做什么,请不要覆盖。

# File bundler/plugin/api/source.rb, line 309
def root
  Bundler.root
end
spec_names() 点击以切换源

由定义使用。

注意:如果您不知道自己在做什么,请不要覆盖。

# File bundler/plugin/api/source.rb, line 252
def spec_names
  specs.spec_names
end
specs() 点击以切换源

解析 gemspec 文件以查找可以由源满足的 gem 的规范。

需要记住的几个重要点

- If the gems are not installed then it shall return specs for all
the gems it can satisfy
- If gem is installed (that is to be detected by the plugin itself)
then it shall return at least the specs that are installed.
- The `loaded_from` for each of the specs shall be correct (it is
used to find the load path)

@return [Bundler::Index] 包含规范的索引

# File bundler/plugin/api/source.rb, line 128
def specs
  files = fetch_gemspec_files

  Bundler::Index.build do |index|
    files.each do |file|
      next unless spec = Bundler.load_gemspec(file)
      spec.installed_by_version = Gem::VERSION

      spec.source = self
      Bundler.rubygems.validate(spec)

      index << spec
    end
  end
end
to_lock() 点击以切换源

生成要输入到 lockfile 中的内容。保存类型和远程,还会调用“options_to_lock”。

Plugin应使用“options_to_lock”将信息保存在 lockfile 中,而不是覆盖此信息。

注意:如果您不知道自己在做什么,请不要覆盖。

# File bundler/plugin/api/source.rb, line 275
def to_lock
  out = String.new("#{LockfileParser::PLUGIN}\n")
  out << "  remote: #{@uri}\n"
  out << "  type: #{@type}\n"
  options_to_lock.each do |opt, value|
    out << "  #{opt}: #{value}\n"
  end
  out << "  specs:\n"
end
to_s() 点击以切换源
# File bundler/plugin/api/source.rb, line 285
def to_s
  "plugin source for #{@type} with uri #{@uri}"
end
也别名为:identifier
unlock!() 点击以切换源

调用此方法以更新规范和安装。

如果源插件是从 lockfile 加载的还是以其他方式加载的,它应刷新缓存/规范(例如,git 源可以进行新的克隆)。

# File bundler/plugin/api/source.rb, line 169
def unlock!
end
unmet_deps() 点击以切换源

由定义使用。

注意:如果您不知道自己在做什么,请不要覆盖。

# File bundler/plugin/api/source.rb, line 245
def unmet_deps
  specs.unmet_dependency_names
end
uri_hash() 点击以切换源
# File bundler/plugin/api/source.rb, line 295
def uri_hash
  SharedHelpers.digest(:SHA1).hexdigest(uri)
end