class Bundler::Source::Rubygems
常量
- API_REQUEST_SIZE
每次 API 请求获取 X 个 gem
属性
remotes[读写]
公共类方法
from_lock(options) 点击以切换源代码
# File bundler/source/rubygems.rb, line 94 def self.from_lock(options) options["remotes"] = Array(options.delete("remote")).reverse new(options.merge("from_lockfile" => true)) end
new(options = {}) 点击以切换源代码
# File bundler/source/rubygems.rb, line 15 def initialize(options = {}) @options = options @remotes = [] @dependency_names = [] @allow_remote = false @allow_cached = false @allow_local = options["allow_local"] || false @checksum_store = Checksum::Store.new Array(options["remotes"]).reverse_each {|r| add_remote(r) } @lockfile_remotes = @remotes if options["from_lockfile"] end
公共实例方法
add_remote(source) 点击以切换源代码
# File bundler/source/rubygems.rb, line 239 def add_remote(source) uri = normalize_uri(source) @remotes.unshift(uri) unless @remotes.include?(uri) end
cache(spec, custom_path = nil) 点击以切换源代码
# File bundler/source/rubygems.rb, line 214 def cache(spec, custom_path = nil) cached_path = Bundler.settings[:cache_all_platforms] ? fetch_gem_if_possible(spec) : cached_gem(spec) raise GemNotFound, "Missing gem file '#{spec.file_name}'." unless cached_path return if File.dirname(cached_path) == Bundler.app_cache.to_s Bundler.ui.info " * #{File.basename(cached_path)}" FileUtils.cp(cached_path, Bundler.app_cache(custom_path)) rescue Errno::EACCES => e Bundler.ui.debug(e) raise InstallError, e.message end
cached!() 点击以切换源代码
# File bundler/source/rubygems.rb, line 54 def cached! return unless File.exist?(cache_path) return if @allow_cached @specs = nil @allow_cached = true end
cached_built_in_gem(spec, local: false) 点击以切换源代码
# File bundler/source/rubygems.rb, line 225 def cached_built_in_gem(spec, local: false) cached_path = cached_gem(spec) if cached_path.nil? && !local remote_spec = remote_specs.search(spec).first if remote_spec cached_path = fetch_gem(remote_spec) spec.remote = remote_spec.remote else Bundler.ui.warn "#{spec.full_name} is built in to Ruby, and can't be cached because your Gemfile doesn't have any sources that contain it." end end cached_path end
caches() 点击以切换源代码
# File bundler/source/rubygems.rb, line 29 def caches @caches ||= [cache_path, *Bundler.rubygems.gem_cache] end
can_lock?(spec) 点击以切换源代码
调用父类方法
Bundler::Source#can_lock?
# File bundler/source/rubygems.rb, line 85 def can_lock?(spec) return super unless multiple_remotes? include?(spec.source) end
dependency_api_available?() 点击以切换源代码
# File bundler/source/rubygems.rb, line 306 def dependency_api_available? @allow_remote && api_fetchers.any? end
dependency_names_to_double_check() 点击以切换源代码
# File bundler/source/rubygems.rb, line 291 def dependency_names_to_double_check names = [] remote_specs.each do |spec| case spec when EndpointSpecification, Gem::Specification, StubSpecification, LazySpecification names.concat(spec.runtime_dependencies.map(&:name)) when RemoteSpecification # from the full index return nil else raise "unhandled spec type (#{spec.inspect})" end end names end
double_check_for(unmet_dependency_names) 点击以切换源代码
# File bundler/source/rubygems.rb, line 271 def double_check_for(unmet_dependency_names) return unless dependency_api_available? unmet_dependency_names = unmet_dependency_names.call unless unmet_dependency_names.nil? if api_fetchers.size <= 1 # can't do this when there are multiple fetchers because then we might not fetch from _all_ # of them unmet_dependency_names -= remote_specs.spec_names # avoid re-fetching things we've already gotten end return if unmet_dependency_names.empty? end Bundler.ui.debug "Double checking for #{unmet_dependency_names || "all specs (due to the size of the request)"} in #{self}" fetch_names(api_fetchers, unmet_dependency_names, remote_specs) specs.use remote_specs end
eql?(other) 点击以切换源代码
# File bundler/source/rubygems.rb, line 67 def eql?(other) other.is_a?(Rubygems) && other.credless_remotes == credless_remotes end
也别名为:==
fetchers() 点击以切换源代码
# File bundler/source/rubygems.rb, line 267 def fetchers @fetchers ||= remote_fetchers.values.freeze end
hash() 点击以切换源代码
# File bundler/source/rubygems.rb, line 63 def hash @remotes.hash end
identifier() 点击以切换源代码
# File bundler/source/rubygems.rb, line 123 def identifier if remotes.empty? "locally installed gems" else "rubygems repository #{remote_names}" end end
也别名为:name, to_gemfile
include?(o) 点击以切换源代码
# File bundler/source/rubygems.rb, line 73 def include?(o) o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty? end
install(spec, options = {}) 点击以切换源代码
# File bundler/source/rubygems.rb, line 150 def install(spec, options = {}) if (spec.default_gem? && !cached_built_in_gem(spec, local: options[:local])) || (installed?(spec) && !options[:force]) print_using_message "Using #{version_message(spec, options[:previous_spec])}" return nil # no post-install message end if spec.remote # Check for this spec from other sources uris = [spec.remote, *remotes_for_spec(spec)].map(&:anonymized_uri).uniq Installer.ambiguous_gems << [spec.name, *uris] if uris.length > 1 end path = fetch_gem_if_possible(spec, options[:previous_spec]) raise GemNotFound, "Could not find #{spec.file_name} for installation" unless path return if Bundler.settings[:no_install] install_path = rubygems_dir bin_path = Bundler.system_bindir require_relative "../rubygems_gem_installer" installer = Bundler::RubyGemsGemInstaller.at( path, security_policy: Bundler.rubygems.security_policies[Bundler.settings["trust-policy"]], install_dir: install_path.to_s, bin_dir: bin_path.to_s, ignore_dependencies: true, wrappers: true, env_shebang: true, build_args: options[:build_args], bundler_extension_cache_path: extension_cache_path(spec) ) if spec.remote s = begin installer.spec rescue Gem::Package::FormatError Bundler.rm_rf(path) raise rescue Gem::Security::Exception => e raise SecurityError, "The gem #{File.basename(path, ".gem")} can't be installed because " \ "the security policy didn't allow it, with the message: #{e.message}" end spec.__swap__(s) end spec.source.checksum_store.register(spec, installer.gem_checksum) message = "Installing #{version_message(spec, options[:previous_spec])}" message += " with native extensions" if spec.extensions.any? Bundler.ui.confirm message installed_spec = installer.install spec.full_gem_path = installed_spec.full_gem_path spec.loaded_from = installed_spec.loaded_from spec.base_dir = installed_spec.base_dir spec.post_install_message end
local!() 点击以切换源代码
# File bundler/source/rubygems.rb, line 40 def local! return if @allow_local @specs = nil @allow_local = true end
local_only!() 点击以切换源代码
# File bundler/source/rubygems.rb, line 33 def local_only! @specs = nil @allow_local = true @allow_cached = false @allow_remote = false end
multiple_remotes?() 点击以切换源代码
# File bundler/source/rubygems.rb, line 77 def multiple_remotes? @remotes.size > 1 end
no_remotes?() 点击以切换源代码
# File bundler/source/rubygems.rb, line 81 def no_remotes? @remotes.size == 0 end
options() 点击以切换源代码
# File bundler/source/rubygems.rb, line 90 def options { "remotes" => @remotes.map(&:to_s) } end
remote!() 点击以切换源代码
# File bundler/source/rubygems.rb, line 47 def remote! return if @allow_remote @specs = nil @allow_remote = true end
remote_fetchers() 点击以切换源代码
# File bundler/source/rubygems.rb, line 260 def remote_fetchers @remote_fetchers ||= remotes.to_h do |uri| remote = Source::Rubygems::Remote.new(uri) [remote, Bundler::Fetcher.new(remote)] end.freeze end
spec_names() 点击以切换源代码
# File bundler/source/rubygems.rb, line 244 def spec_names if dependency_api_available? remote_specs.spec_names else [] end end
specs() 点击以切换源代码
# File bundler/source/rubygems.rb, line 133 def specs @specs ||= begin # remote_specs usually generates a way larger Index than the other # sources, and large_idx.merge! small_idx is way faster than # small_idx.merge! large_idx. index = @allow_remote ? remote_specs.dup : Index.new index.merge!(cached_specs) if @allow_cached index.merge!(installed_specs) if @allow_local # complete with default specs, only if not already available in the # index through remote, cached, or installed specs index.use(default_specs) if @allow_local index end end
to_lock() 点击以切换源代码
# File bundler/source/rubygems.rb, line 99 def to_lock out = String.new("GEM\n") lockfile_remotes.reverse_each do |remote| out << " remote: #{remote}\n" end out << " specs:\n" end
to_s() 点击以切换源代码
# File bundler/source/rubygems.rb, line 107 def to_s if remotes.empty? "locally installed gems" elsif @allow_remote && @allow_cached && @allow_local "rubygems repository #{remote_names}, cached gems or installed locally" elsif @allow_remote && @allow_local "rubygems repository #{remote_names} or installed locally" elsif @allow_remote "rubygems repository #{remote_names}" elsif @allow_cached && @allow_local "cached gems or installed locally" else "locally installed gems" end end
unmet_deps() 点击以切换源代码
# File bundler/source/rubygems.rb, line 252 def unmet_deps if dependency_api_available? remote_specs.unmet_dependency_names else [] end end
受保护的实例方法
api_fetchers() 点击以切换源代码
# File bundler/source/rubygems.rb, line 389 def api_fetchers fetchers.select(&:api_fetcher?) end
cache_path() 点击以切换源代码
# File bundler/source/rubygems.rb, line 453 def cache_path Bundler.app_cache end
cached_gem(spec) 点击以切换源代码
# File bundler/source/rubygems.rb, line 327 def cached_gem(spec) global_cache_path = download_cache_path(spec) caches << global_cache_path if global_cache_path possibilities = caches.map {|p| package_path(p, spec) } possibilities.find {|p| File.exist?(p) } end
cached_specs() 点击以切换源代码
# File bundler/source/rubygems.rb, line 375 def cached_specs @cached_specs ||= begin idx = Index.new Dir["#{cache_path}/*.gem"].each do |gemfile| s ||= Bundler.rubygems.spec_from_gem(gemfile) s.source = self idx << s end idx end end
credless_remotes() 点击以切换源代码
# File bundler/source/rubygems.rb, line 316 def credless_remotes remotes.map(&method(:remove_auth)) end
default_cache_path_for(dir) 点击以切换源代码
# File bundler/source/rubygems.rb, line 449 def default_cache_path_for(dir) "#{dir}/cache" end
default_specs() 点击以切换源代码
# File bundler/source/rubygems.rb, line 366 def default_specs @default_specs ||= Index.build do |idx| Bundler.rubygems.default_specs.each do |spec| spec.source = self idx << spec end end end
fetch_gem(spec, previous_spec = nil) 点击以切换源代码
# File bundler/source/rubygems.rb, line 426 def fetch_gem(spec, previous_spec = nil) spec.fetch_platform cache_path = download_cache_path(spec) || default_cache_path_for(rubygems_dir) gem_path = package_path(cache_path, spec) return gem_path if File.exist?(gem_path) SharedHelpers.filesystem_access(cache_path) do |p| FileUtils.mkdir_p(p) end download_gem(spec, cache_path, previous_spec) gem_path end
fetch_gem_if_possible(spec, previous_spec = nil) 点击以切换源代码
# File bundler/source/rubygems.rb, line 418 def fetch_gem_if_possible(spec, previous_spec = nil) if spec.remote fetch_gem(spec, previous_spec) else cached_gem(spec) end end
fetch_names(fetchers, dependency_names, index) 点击以切换源代码
# File bundler/source/rubygems.rb, line 405 def fetch_names(fetchers, dependency_names, index) fetchers.each do |f| if dependency_names Bundler.ui.info "Fetching gem metadata from #{URICredentialsFilter.credential_filtered_uri(f.uri)}", Bundler.ui.debug? index.use f.specs_with_retry(dependency_names, self) Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over else Bundler.ui.info "Fetching source index from #{URICredentialsFilter.credential_filtered_uri(f.uri)}" index.use f.specs_with_retry(nil, self) end end end
installed?(spec) 点击以切换源代码
# File bundler/source/rubygems.rb, line 441 def installed?(spec) installed_specs[spec].any? && !spec.deleted_gem? end
installed_specs() 点击以切换源代码
# File bundler/source/rubygems.rb, line 356 def installed_specs @installed_specs ||= Index.build do |idx| Bundler.rubygems.installed_specs.reverse_each do |spec| spec.source = self next if spec.ignored? idx << spec end end end
normalize_uri(uri) 点击以切换源代码
# File bundler/source/rubygems.rb, line 339 def normalize_uri(uri) uri = URINormalizer.normalize_suffix(uri.to_s) require_relative "../vendored_uri" uri = Gem::URI(uri) raise ArgumentError, "The source must be an absolute URI. For example:\n" \ "source 'https://rubygems.org.cn'" if !uri.absolute? || (uri.is_a?(Gem::URI::HTTP) && uri.host.nil?) uri end
package_path(cache_path, spec) 点击以切换源代码
# File bundler/source/rubygems.rb, line 335 def package_path(cache_path, spec) "#{cache_path}/#{spec.file_name}" end
remote_names() 点击以切换源代码
# File bundler/source/rubygems.rb, line 312 def remote_names remotes.map(&:to_s).join(", ") end
remote_specs() 点击以切换源代码
# File bundler/source/rubygems.rb, line 393 def remote_specs @remote_specs ||= Index.build do |idx| index_fetchers = fetchers - api_fetchers if index_fetchers.empty? fetch_names(api_fetchers, dependency_names, idx) else fetch_names(fetchers, nil, idx) end end end
remotes_for_spec(spec) 点击以切换源代码
# File bundler/source/rubygems.rb, line 320 def remotes_for_spec(spec) specs.search_all(spec.name).inject([]) do |uris, s| uris << s.remote if s.remote uris end end
remove_auth(remote) 点击以切换源代码
# File bundler/source/rubygems.rb, line 348 def remove_auth(remote) if remote.user || remote.password remote.dup.tap {|uri| uri.user = uri.password = nil }.to_s else remote.to_s end end
rubygems_dir() 点击以切换源代码
# File bundler/source/rubygems.rb, line 445 def rubygems_dir Bundler.bundle_path end
私有实例方法
download_cache_path(spec) 点击以切换源代码
返回调用 Rubygems::Source 对象的全局缓存路径。
请注意,Source
确定路径的子目录。我们在全局缓存路径中使用此子目录,以便将来自不同来源的具有相同名称(以及可能不同的版本)的 gem 保存到各自的子目录,而不会相互覆盖。
@param [Gem::Specification] specification
@return [Pathname] 全局缓存路径。
# File bundler/source/rubygems.rb, line 493 def download_cache_path(spec) return unless Bundler.feature_flag.global_gem_cache? return unless remote = spec.remote return unless cache_slug = remote.cache_slug Bundler.user_cache.join("gems", cache_slug) end
download_gem(spec, download_cache_path, previous_spec = nil) 点击以切换源代码
检查所请求的 spec 是否存在于全局缓存中。如果存在,我们会将其复制到下载路径;如果不存在,我们会下载它。
@param [Specification] spec
the spec we want to download or retrieve from the cache.
@param [String] download_cache_path
the local directory the .gem will end up in.
@param [Specification] previous_spec
the spec previously locked
# File bundler/source/rubygems.rb, line 475 def download_gem(spec, download_cache_path, previous_spec = nil) uri = spec.remote.uri Bundler.ui.confirm("Fetching #{version_message(spec, previous_spec)}") gem_remote_fetcher = remote_fetchers.fetch(spec.remote).gem_remote_fetcher Bundler.rubygems.download_gem(spec, uri, download_cache_path, gem_remote_fetcher) end
extension_cache_slug(spec) 点击以切换源代码
# File bundler/source/rubygems.rb, line 501 def extension_cache_slug(spec) return unless remote = spec.remote remote.cache_slug end
lockfile_remotes() 点击以切换源代码
# File bundler/source/rubygems.rb, line 459 def lockfile_remotes @lockfile_remotes || credless_remotes end