模块 Gem
RubyGems 是用于发布和管理第三方库的 Ruby 标准。
有关用户文档,请参阅
-
gem help
和gem help [命令]
有关 gem 开发人员文档,请参阅
-
Gem::Version
,了解版本依赖项说明
更多 RubyGems 文档可以在以下位置找到
-
RubyGems API(也可以从
gem server
获取)
RubyGems 插件¶ ↑
RubyGems 将在每个已安装 gem 的最新版本或 $LOAD_PATH 中加载插件。插件必须命名为 “rubygems_plugin”(.rb、.so 等),并放置在 gem 的 require_path 的根目录。插件安装在特殊位置,并在启动时加载。
有关插件示例,请参阅 Graph gem,它添加了 gem graph
命令。
RubyGems 默认值,打包¶ ↑
RubyGems 默认值存储在 lib/rubygems/defaults.rb 中。如果您正在打包 RubyGems 或实现 Ruby,您可以更改 RubyGems 的默认值。
对于 RubyGems 打包程序,请提供 lib/rubygems/defaults/operating_system.rb 并覆盖 lib/rubygems/defaults.rb 中的任何默认值。
对于 Ruby 实现者,请提供 lib/rubygems/defaults/#{RUBY_ENGINE}.rb 并覆盖 lib/rubygems/defaults.rb 中的任何默认值。
如果您需要 RubyGems 在安装或卸载时执行额外的工作,您的默认值覆盖文件可以设置安装前/后和卸载钩子。请参阅 Gem::pre_install
、Gem::pre_uninstall
、Gem::post_install
、Gem::post_uninstall
。
缺陷¶ ↑
您可以在 GitHub 上将缺陷提交到 RubyGems 错误跟踪器
鸣谢¶ ↑
RubyGems 目前由 Eric Hodel 维护。
RubyGems 最初由以下人员在 RubyConf 2003 上开发
-
Rich Kilmer – rich(at)infoether.com
-
Chad Fowler – chad(at)chadfowler.com
-
David Black – dblack(at)wobblini.net
-
Paul Brannan – paul(at)atdesk.com
-
Jim Weirich – jim(at)weirichhouse.org
贡献者
-
Gavin Sinclair – gsinclair(at)soyabean.com.au
-
George Marrows – george.marrows(at)ntlworld.com
-
Dick Davies – rasputnik(at)hellooperator.net
-
Mauricio Fernandez – batsman.geo(at)yahoo.com
-
Simon Strandgaard – neoneye(at)adslhome.dk
-
Dave Glasser – glasser(at)mit.edu
-
Paul Duncan – pabs(at)pablotron.org
-
Ville Aine – vaine(at)cs.helsinki.fi
-
Eric Hodel – drbrain(at)segment7.net
-
Daniel Berger – djberg96(at)gmail.com
-
Phil Hagelberg – technomancy(at)gmail.com
-
Ryan Davis – ryand-ruby(at)zenspider.com
-
Evan Phoenix – evan(at)fallingsnow.net
-
Steve Klabnik – steve(at)steveklabnik.com
(如果您的名字遗漏了,请告诉我们!)
许可证¶ ↑
有关权限,请参阅 LICENSE.txt。
谢谢!
- RubyGems 团队
提供 3 种方法来声明某些内容何时要被弃用。
+deprecate(name, repl, year, month)+
Indicate something may be removed on/after a certain date.
+rubygems_deprecate(name, replacement=:none)+
Indicate something will be removed in the next major RubyGems version, and (optionally) a replacement for it.
rubygems_deprecate_command
:
Indicate a RubyGems command (in +lib/rubygems/commands/*.rb+) will be removed in the next RubyGems version.
还提供 skip_during
用于暂时关闭弃用警告。这旨在用于测试套件,因此如果需要确保 stderr 为空,则弃用警告不会导致测试失败。
deprecate
和 rubygems_deprecate
的用法示例
class Legacy def self.some_class_method # ... end def some_instance_method # ... end def some_old_method # ... end extend Gem::Deprecate deprecate :some_instance_method, "X.z", 2011, 4 rubygems_deprecate :some_old_method, "Modern#some_new_method" class << self extend Gem::Deprecate deprecate :some_class_method, :none, 2011, 4 end end
rubygems_deprecate_command
的用法示例
class Gem::Commands::QueryCommand < Gem::Command extend Gem::Deprecate rubygems_deprecate_command # ... end
skip_during
的用法示例
class TestSomething < Gem::Testcase def test_some_thing_with_deprecations Gem::Deprecate.skip_during do actual_stdout, actual_stderr = capture_output do Gem.something_deprecated end assert_empty actual_stdout assert_equal(expected, actual_stderr) end end end
常量
属性
RubyGems 发行商(如操作系统软件包管理器)可以通过将此设置为 gem update --system 上打印给最终用户的错误消息,而不是实际更新来禁用 RubyGems 更新。
RubyGems 是否应该增强内置的 ‘require`,以自动检查所需的路径是否存在于已安装的 gem 中,并自动激活它们并将它们添加到 `$LOAD_PATH` 中。
在 Gem::DependencyInstaller
安装一组 gems 后要运行的钩子列表
GemDependencyAPI 对象,在调用 .use_gemdeps 时设置。其中包含来自 Gemfile 的所有信息。
按名称键控的已加载 Gem::Specification
的 Hash
在 Gem::Installer#install
提取文件并构建扩展后要运行的钩子列表
在 Gem::Installer#install
完成安装后要运行的钩子列表
在 Gem::Specification.reset
运行后要运行的钩子列表。
在 Gem::Uninstaller#uninstall
完成安装后要运行的钩子列表
在 Gem::Installer#install
执行任何工作之前要运行的钩子列表
在 Gem::Specification.reset
运行之前要运行的钩子列表。
在 Gem::Uninstaller#uninstall
执行任何工作之前要运行的钩子列表
公共类方法
来源
# File lib/rubygems.rb, line 592 def self.activated_gem_paths @activated_gem_paths ||= 0 end
来自已激活 gem 的 +$LOAD_PATH+ 中的路径数。用于在 require
期间优先考虑 -I
和 ENV['RUBYLIB']
条目。
来源
# File lib/rubygems.rb, line 599 def self.add_to_load_path(*paths) @activated_gem_paths = activated_gem_paths + paths.size # gem directories must come after -I and ENV['RUBYLIB'] $LOAD_PATH.insert(Gem.load_path_insert_index, *paths) end
将路径列表添加到 $LOAD_PATH 的适当位置。
来源
# File lib/rubygems.rb, line 238 def self.bin_path(name, exec_name = nil, *requirements) requirements = Gem::Requirement.default if requirements.empty? find_spec_for_exe(name, exec_name, requirements).bin_file exec_name end
Find
查找 gem name
的可执行文件的完整路径。如果未给出 exec_name
,将引发异常,否则将返回指定的可执行文件的路径。requirements
允许您指定特定的 gem 版本。
来源
# File lib/rubygems.rb, line 299 def self.bindir(install_dir=Gem.dir) return File.join install_dir, "bin" unless install_dir.to_s == Gem.default_dir.to_s Gem.default_bindir end
gem 可执行文件要安装到的路径。
来源
# File lib/rubygems/defaults.rb, line 147 def self.cache_home @cache_home ||= ENV["XDG_CACHE_HOME"] || File.join(Gem.user_home, ".cache") end
用户缓存目录的标准位置的路径。
来源
# File lib/rubygems.rb, line 1270 def clear_default_specs @path_to_default_spec_map.clear end
清除与默认 gem 相关的变量。它是用于测试的
来源
# File lib/rubygems.rb, line 317 def self.clear_paths @paths = nil @user_home = nil Gem::Specification.reset Gem::Security.reset if defined?(Gem::Security) end
重置 dir
和 path
值。下次请求 dir
或 path
时,将从头开始计算这些值。这主要用于单元测试以提供测试隔离。
来源
# File lib/rubygems/defaults.rb, line 133 def self.config_file @config_file ||= find_config_file end
用户 .gemrc 文件的标准位置的路径。
来源
# File lib/rubygems/defaults.rb, line 114 def self.config_home @config_home ||= ENV["XDG_CONFIG_HOME"] || File.join(Gem.user_home, ".config") end
用户配置目录的标准位置的路径。
来源
# File lib/rubygems.rb, line 327 def self.configuration @configuration ||= Gem::ConfigFile.new [] end
gems 的标准配置对象。
来源
# File lib/rubygems.rb, line 335 def self.configuration=(config) @configuration = config end
使用给定的配置对象(实现 ConfigFile
协议)作为标准配置对象。
来源
# File lib/rubygems/defaults.rb, line 154 def self.data_home @data_home ||= ENV["XDG_DATA_HOME"] || File.join(Gem.user_home, ".local", "share") end
用户数据目录的标准位置的路径。
来源
# File lib/rubygems/defaults.rb, line 204 def self.default_bindir RbConfig::CONFIG["bindir"] end
二进制文件的默认目录
来源
# File lib/rubygems/defaults.rb, line 228 def self.default_cert_path default_cert_path = File.join Gem.user_home, ".gem", "gem-public_cert.pem" unless File.exist?(default_cert_path) default_cert_path = File.join Gem.data_home, "gem", "gem-public_cert.pem" end default_cert_path end
默认签名证书链路径
来源
# File lib/rubygems/defaults.rb, line 37 def self.default_dir @default_dir ||= File.join(RbConfig::CONFIG["rubylibprefix"], "gems", RbConfig::CONFIG["ruby_version"]) end
如果在环境中未指定备用值,则使用的默认主目录路径
来源
# File lib/rubygems/defaults.rb, line 186 def self.default_exec_format exec_format = begin RbConfig::CONFIG["ruby_install_name"].sub("ruby", "%s") rescue StandardError "%s" end unless exec_format.include?("%s") raise Gem::Exception, "[BUG] invalid exec_format #{exec_format.inspect}, no %s" end exec_format end
从 Ruby 的安装名称推断出其 --program-prefix 和 --program-suffix
来源
# File lib/rubygems/defaults.rb, line 48 def self.default_ext_dir_for(base_dir) nil end
返回指定 RubyGems 基本目录的二进制扩展目录,如果无法确定此类目录,则返回 nil。
默认情况下,二进制扩展与其 Ruby 对应物并排位于同一位置,因此返回 nil
来源
# File lib/rubygems/defaults.rb, line 215 def self.default_key_path default_key_path = File.join Gem.user_home, ".gem", "gem-private_key.pem" unless File.exist?(default_key_path) default_key_path = File.join Gem.data_home, "gem", "gem-private_key.pem" end default_key_path end
默认签名密钥路径
来源
# File lib/rubygems/defaults.rb, line 175 def self.default_path path = [] path << user_dir if user_home && File.exist?(user_home) path << default_dir path << vendor_dir if vendor_dir && File.directory?(vendor_dir) path end
默认 gem 加载路径
来源
# File lib/rubygems/defaults.rb, line 55 def self.default_rubygems_dirs nil # default to standard layout end
RubyGems 的 .rb 文件和 bin 文件安装的路径
来源
# File lib/rubygems/defaults.rb, line 15 def self.default_sources %w[https://rubygems.org.cn/] end
RubyGems 自带的默认源的 Array
来源
# File lib/rubygems/defaults.rb, line 23 def self.default_spec_cache_dir default_spec_cache_dir = File.join Gem.user_home, ".gem", "specs" unless File.exist?(default_spec_cache_dir) default_spec_cache_dir = File.join Gem.cache_home, "gem", "specs" end default_spec_cache_dir end
如果在环境中未指定备用值,则使用的默认 spec 目录路径
来源
# File lib/rubygems/defaults.rb, line 62 def self.default_specifications_dir @default_specifications_dir ||= File.join(Gem.default_dir, "specifications", "default") end
默认 gem 的 specification 文件路径。
来源
# File lib/rubygems.rb, line 342 def self.deflate(data) require "zlib" Zlib::Deflate.deflate data end
来源
# File lib/rubygems.rb, line 703 def self.done_installing(&hook) @done_installing_hooks << hook end
添加一个 post-installs 钩子,当 Gem::DependencyInstaller#install
完成时,会将 Gem::DependencyInstaller
和已安装规范列表传递给该钩子
来源
# File lib/rubygems.rb, line 977 def self.dynamic_library_suffixes @dynamic_library_suffixes ||= suffixes - [".rb"] end
动态库 require-able 路径的后缀。
来源
# File lib/rubygems.rb, line 441 def self.ensure_default_gem_subdirectories(dir = Gem.dir, mode = nil) ensure_subdirectories(dir, mode, REPOSITORY_DEFAULT_GEM_SUBDIRECTORIES) end
静默确保 Gem
目录 dir
包含所有用于处理默认 gem 的正确子目录。如果我们由于权限问题而无法创建目录,那么我们将静默继续。
如果给定了 mode
,则将使用此模式创建缺少的目录。
永远不会创建世界可写目录。
来源
# File lib/rubygems.rb, line 428 def self.ensure_gem_subdirectories(dir = Gem.dir, mode = nil) ensure_subdirectories(dir, mode, REPOSITORY_SUBDIRECTORIES) end
静默确保 Gem
目录 dir
包含所有正确的子目录。如果我们由于权限问题而无法创建目录,那么我们将静默继续。
如果给定了 mode
,则将使用此模式创建缺少的目录。
永远不会创建世界可写目录。
来源
# File lib/rubygems.rb, line 845 def self.env_requirement(gem_name) @env_requirements_by_name ||= {} @env_requirements_by_name[gem_name] ||= begin req = ENV["GEM_REQUIREMENT_#{gem_name.upcase}"] || ">= 0" Gem::Requirement.create(req) end end
来源
# File lib/rubygems/defaults.rb, line 121 def self.find_config_file gemrc = File.join Gem.user_home, ".gemrc" if File.exist? gemrc gemrc else File.join Gem.config_home, "gem", "gemrc" end end
查找用户的配置文件
来源
# File lib/rubygems.rb, line 1255 def find_default_spec(path) @path_to_default_spec_map[path] end
从 path
Find
默认 gem 的 Gem::Specification
来源
# File lib/rubygems.rb, line 492 def self.find_files(glob, check_load_path=true) files = [] files = find_files_from_load_path glob if check_load_path gem_specifications = @gemdeps ? Gem.loaded_specs.values : Gem::Specification.stubs files.concat gem_specifications.flat_map {|spec| spec.matches_for_glob("#{glob}#{Gem.suffix_pattern}") } # $LOAD_PATH might contain duplicate entries or reference # the spec dirs directly, so we prune. files.uniq! if check_load_path files end
返回与 glob
匹配的路径列表,gem 可以使用这些路径来从其他 gem 中选取功能。例如
Gem.find_files('rdoc/discover').each do |path| load path end
如果 check_load_path
为 true(默认值),则 find_files
还会搜索 $LOAD_PATH 中的文件以及 gem。
请注意,即使 find_files
返回来自同一 gem 的不同版本的所有文件。另请参阅 find_latest_files
来源
# File lib/rubygems.rb, line 529 def self.find_latest_files(glob, check_load_path=true) files = [] files = find_files_from_load_path glob if check_load_path files.concat Gem::Specification.latest_specs(true).flat_map {|spec| spec.matches_for_glob("#{glob}#{Gem.suffix_pattern}") } # $LOAD_PATH might contain duplicate entries or reference # the spec dirs directly, so we prune. files.uniq! if check_load_path files end
返回与 glob
匹配的最新 gem 中的路径列表,gem 可以使用这些路径来从其他 gem 中选取功能。例如
Gem.find_latest_files('rdoc/discover').each do |path| load path end
如果 check_load_path
为 true(默认值),则 find_latest_files
还会搜索 $LOAD_PATH 中的文件以及 gem。
与 find_files
不同,find_latest_files
将仅返回来自 gem 最新版本的文件。
来源
# File lib/rubygems.rb, line 1262 def find_unresolved_default_spec(path) default_spec = @path_to_default_spec_map[path] default_spec if default_spec && loaded_specs[default_spec.name] != default_spec end
从 path
Find
默认 gem 的未解析 Gem::Specification
来源
# File lib/rubygems.rb, line 223 def self.finish_resolve(request_set=Gem::RequestSet.new) request_set.import Gem::Specification.unresolved_deps.values request_set.import Gem.loaded_specs.values.map {|s| Gem::Dependency.new(s.name, s.version) } request_set.resolve_current.each do |s| s.full_spec.activate end end
来源
# File lib/rubygems.rb, line 1047 def self.freebsd_platform? RbConfig::CONFIG["host_os"].to_s.include?("bsd") end
此平台是 FreeBSD 吗
来源
# File lib/rubygems.rb, line 564 def self.host @host ||= Gem::DEFAULT_HOST end
获取默认的 RubyGems API 主机。这通常是 https://rubygems.org.cn
。
来源
# File lib/rubygems.rb, line 570 def self.host=(host) @host = host end
Set
默认的 RubyGems API 主机。
来源
# File lib/rubygems.rb, line 553 def self.install(name, version = Gem::Requirement.default, *options) require_relative "rubygems/dependency_installer" inst = Gem::DependencyInstaller.new(*options) inst.install name, version inst.installed_gems end
顶级安装辅助方法。允许您以交互方式安装 gem
% irb >> Gem.install "minitest" Fetching: minitest-5.14.0.gem (100%) => [#<Gem::Specification:0x1013b4528 @name="minitest", ...>]
来源
# File lib/rubygems.rb, line 1033 def self.java_platform? RUBY_PLATFORM == "java" end
这是一个 java 平台吗?
来源
# File lib/rubygems.rb, line 870 def self.latest_rubygems_version latest_version_for("rubygems-update") || raise("Can't find 'rubygems-update' in any repo. Check `gem source list`.") end
返回 RubyGems 的最新发行版本。
来源
# File lib/rubygems.rb, line 857 def self.latest_spec_for(name) dependency = Gem::Dependency.new name fetcher = Gem::SpecFetcher.fetcher spec_tuples, = fetcher.spec_for_dependency dependency spec, = spec_tuples.last spec end
返回 gem name
的最新发行版本规范。
来源
# File lib/rubygems.rb, line 878 def self.latest_version_for(name) latest_spec_for(name)&.version end
返回 gem name
的最新发行版本的版本
来源
# File lib/rubygems.rb, line 1082 def self.load_env_plugins load_plugin_files find_files_from_load_path("rubygems_plugin") end
Find
$LOAD_PATH 中的所有“rubygems_plugin”文件并加载它们
来源
# File lib/rubygems.rb, line 578 def self.load_path_insert_index $LOAD_PATH.each_with_index do |path, i| return i if path.instance_variable_defined?(:@gem_prelude_index) end index = $LOAD_PATH.index RbConfig::CONFIG["sitelibdir"] index || 0 end
将激活的 gem 路径插入到 $LOAD_PATH 中的索引。默认情况下,激活的 gem 的路径插入到 site lib 目录之前。
来源
# File lib/rubygems.rb, line 1073 def self.load_plugins Gem.path.each do |gem_path| load_plugin_files Gem::Util.glob_files_in_dir("*#{Gem.plugin_suffix_pattern}", plugindir(gem_path)) end end
Find
标准位置中的 rubygems 插件文件并加载它们
来源
# File lib/rubygems.rb, line 624 def self.load_safe_marshal return if @safe_marshal_loaded require_relative "rubygems/safe_marshal" @safe_marshal_loaded = true end
来源
来源
# File lib/rubygems.rb, line 646 def self.location_of_caller(depth = 1) caller[depth] =~ /(.*?):(\d+).*?$/i file = $1 lineno = $2.to_i [file, lineno] end
此方法的调用者的调用者的文件名和行号。
depth
是它应该在调用堆栈中向上移动多少层。
例如,
def a; Gem.location_of_caller
; end a #=> [“x.rb”, 2] #(它会因文件名和行号而异)
def b; c; end def c; Gem.location_of_caller(2)
; end b #=> [“x.rb”, 6] #(它会因文件名和行号而异)
来源
# File lib/rubygems.rb, line 657 def self.marshal_version "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}" end
Ruby 的 Marshal
格式的版本。
来源
# File lib/rubygems.rb, line 215 def self.needs rs = Gem::RequestSet.new yield rs finish_resolve rs end
来源
# File lib/rubygems.rb, line 793 def self.open_file(path, flags, &block) File.open(path, flags, &block) end
使用给定标志打开文件
来源
# File lib/rubygems.rb, line 811 def self.open_file_with_flock(path, &block) # read-write mode is used rather than read-only in order to support NFS mode = IO::RDWR | IO::APPEND | IO::CREAT | IO::BINARY mode |= IO::SHARE_DELETE if IO.const_defined?(:SHARE_DELETE) File.open(path, mode) do |io| begin io.flock(File::LOCK_EX) rescue Errno::ENOSYS, Errno::ENOTSUP end yield io end end
使用给定标志打开文件,并使用 flock 保护访问
来源
# File lib/rubygems.rb, line 800 def self.open_file_with_lock(path, &block) file_lock = "#{path}.lock" open_file_with_flock(file_lock, &block) ensure require "fileutils" FileUtils.rm_f file_lock end
使用给定标志打开文件,并使用文件锁保护访问
来源
# File lib/rubygems/defaults.rb, line 286 def self.operating_system_defaults {} end
Ruby 打包器的 gem 命令的默认选项。
此处的选项应构造为字符串数组,“gem”命令名称作为键,默认选项的字符串作为值。
示例
def self.operating_system_defaults
{ 'install' => '--no-rdoc --no-ri --env-shebang', 'update' => '--no-rdoc --no-ri --env-shebang' }
end
来源
来源
# File lib/rubygems.rb, line 350 def self.paths @paths ||= Gem::PathSupport.new(ENV) end
检索 RubyGems 用于查找文件的 PathSupport
对象。
来源
# File lib/rubygems.rb, line 360 def self.paths=(env) clear_paths target = {} env.each_pair do |k,v| case k when "GEM_HOME", "GEM_PATH", "GEM_SPEC_CACHE" case v when nil, String target[k] = v when Array unless Gem::Deprecate.skip warn <<-EOWARN Array values in the parameter to `Gem.paths=` are deprecated. Please use a String or nil. An Array (#{env.inspect}) was passed in from #{caller[3]} EOWARN end target[k] = v.join File::PATH_SEPARATOR end else target[k] = v end end @paths = Gem::PathSupport.new ENV.to_hash.merge(target) Gem::Specification.dirs = @paths.path end
从 env
初始化要使用的文件系统路径。env
是一个类哈希对象(通常是 ENV
),会查询 ‘GEM_HOME’、‘GEM_PATH’ 和 ‘GEM_SPEC_CACHE’。env
哈希的键应为字符串,哈希的值应为字符串或 nil
。
来源
# File lib/rubygems/defaults.rb, line 305 def self.platform_defaults {} end
Ruby 实现器的 gem 命令的默认选项。
此处的选项应构造为字符串数组,“gem”命令名称作为键,默认选项的字符串作为值。
示例
def self.platform_defaults
{ 'install' => '--no-rdoc --no-ri --env-shebang', 'update' => '--no-rdoc --no-ri --env-shebang' }
end
来源
# File lib/rubygems.rb, line 671 def self.platforms @platforms ||= [] if @platforms.empty? @platforms = [Gem::Platform::RUBY, Gem::Platform.local] end @platforms end
此 RubyGems 支持的平台 Array
。
来源
# File lib/rubygems.rb, line 664 def self.platforms=(platforms) @platforms = platforms end
Set
此 RubyGems 支持的平台数组(主要用于测试)。
来源
# File lib/rubygems.rb, line 950 def self.plugin_suffix_pattern @plugin_suffix_pattern ||= "_plugin#{suffix_pattern}" end
require-able 插件后缀的 glob 模式。
来源
# File lib/rubygems.rb, line 957 def self.plugin_suffix_regexp @plugin_suffix_regexp ||= /_plugin#{suffix_regexp}\z/ end
require-able 插件后缀的 Regexp
。
来源
# File lib/rubygems.rb, line 308 def self.plugindir(install_dir=Gem.dir) File.join install_dir, "plugins" end
要安装 rubygems 插件的路径。
来源
# File lib/rubygems.rb, line 686 def self.post_build(&hook) @post_build_hooks << hook end
添加一个 post-build 钩子,当调用 Gem::Installer#install
时,会将一个 Gem::Installer
实例传递给该钩子。在提取 gem 并构建扩展之后但在写入可执行文件或 gemspec 之前调用该钩子。如果钩子返回 false
,则将删除 gem 的文件并中止安装。
来源
# File lib/rubygems.rb, line 694 def self.post_install(&hook) @post_install_hooks << hook end
添加一个 post-install 钩子,当调用 Gem::Installer#install
时,会将一个 Gem::Installer
实例传递给该钩子
来源
# File lib/rubygems.rb, line 711 def self.post_reset(&hook) @post_reset_hooks << hook end
添加一个在 Gem::Specification.reset
运行后将运行的钩子。
来源
# File lib/rubygems.rb, line 720 def self.post_uninstall(&hook) @post_uninstall_hooks << hook end
添加一个 post-uninstall 钩子,当调用 Gem::Uninstaller#uninstall
时,会将一个 Gem::Uninstaller
实例和卸载的规范传递给该钩子
来源
# File lib/rubygems.rb, line 729 def self.pre_install(&hook) @pre_install_hooks << hook end
添加一个 pre-install 钩子,当调用 Gem::Installer#install
时,会将一个 Gem::Installer
实例传递给该钩子。如果钩子返回 false
,则将中止安装。
来源
# File lib/rubygems.rb, line 737 def self.pre_reset(&hook) @pre_reset_hooks << hook end
添加一个在 Gem::Specification.reset
运行之前将运行的钩子。
来源
# File lib/rubygems.rb, line 746 def self.pre_uninstall(&hook) @pre_uninstall_hooks << hook end
添加一个 pre-uninstall 钩子,当调用 Gem::Uninstaller#uninstall
时,会将一个 Gem::Uninstaller
实例和将要卸载的规范传递给该钩子
来源
# File lib/rubygems.rb, line 755 def self.prefix prefix = File.dirname RUBYGEMS_DIR if prefix != File.expand_path(RbConfig::CONFIG["sitelibdir"]) && prefix != File.expand_path(RbConfig::CONFIG["libdir"]) && File.basename(RUBYGEMS_DIR) == "lib" prefix end end
安装此 RubyGems 的目录前缀。如果您的前缀位于标准位置(即,rubygems 安装在您期望的位置),则前缀返回 nil。
来源
来源
# File lib/rubygems.rb, line 775 def self.read_binary(path) File.binread(path) end
在所有平台上以二进制模式安全读取文件。
来源
# File lib/rubygems.rb, line 768 def self.refresh Gem::Specification.reset end
从磁盘刷新可用的 gem。
来源
# File lib/rubygems.rb, line 1230 def register_default_spec(spec) extended_require_paths = spec.require_paths.map {|f| f + "/" } new_format = extended_require_paths.any? {|path| spec.files.any? {|f| f.start_with? path } } if new_format prefix_group = extended_require_paths.join("|") prefix_pattern = /^(#{prefix_group})/ end spec.files.each do |file| if new_format file = file.sub(prefix_pattern, "") next unless $~ end spec.activate if already_loaded?(file) @path_to_default_spec_map[file] = spec @path_to_default_spec_map[file.sub(suffix_regexp, "")] = spec end end
为默认 gem 注册一个 Gem::Specification
。
支持两种规范格式
-
MRI 2.0 风格,其中 spec.files 包含未加前缀的 require 名称。spec 的文件名将按原样注册。
-
新风格,其中 spec.files 包含带有 spec.require_paths 中路径前缀的文件。在注册 spec 的文件名之前,会剥离前缀。省略未加前缀的文件。
来源
# File lib/rubygems.rb, line 828 def self.ruby if @ruby.nil? @ruby = RbConfig.ruby @ruby = "\"#{@ruby}\"" if /\s/.match?(@ruby) end @ruby end
正在运行的 Ruby 解释器的路径。
来源
# File lib/rubygems.rb, line 841 def self.ruby_api_version @ruby_api_version ||= target_rbconfig["ruby_version"].dup end
返回一个 String
,其中包含 Ruby 的 API 兼容版本。
来源
# File lib/rubygems.rb, line 885 def self.ruby_version return @ruby_version if defined? @ruby_version version = RUBY_VERSION.dup if RUBY_PATCHLEVEL == -1 if RUBY_ENGINE == "ruby" desc = RUBY_DESCRIPTION[/\Aruby #{Regexp.quote(RUBY_VERSION)}([^ ]+) /, 1] else desc = RUBY_DESCRIPTION[/\A#{RUBY_ENGINE} #{Regexp.quote(RUBY_ENGINE_VERSION)} \(#{RUBY_VERSION}([^ ]+)\) /, 1] end version << ".#{desc}" if desc end @ruby_version = Gem::Version.new version end
当前正在运行的 Ruby 的 Gem::Version
。
来源
# File lib/rubygems.rb, line 904 def self.rubygems_version return @rubygems_version if defined? @rubygems_version @rubygems_version = Gem::Version.new Gem::VERSION end
当前正在运行的 RubyGems 的 Gem::Version
。
来源
# File lib/rubygems.rb, line 412 def self.set_target_rbconfig(rbconfig_path) @target_rbconfig = Gem::TargetRbConfig.from_path(rbconfig_path) Gem::Platform.local(refresh: true) Gem.platforms << Gem::Platform.local unless Gem.platforms.include? Gem::Platform.local @target_rbconfig end
来源
# File lib/rubygems.rb, line 1040 def self.solaris_platform? RUBY_PLATFORM.include?("solaris") end
此平台是否为 Solaris?
来源
# File lib/rubygems.rb, line 1185 def self.source_date_epoch Time.at(source_date_epoch_string.to_i).utc.freeze end
返回 Gem.source_date_epoch_string
的值,作为 Time
对象。
这在整个 RubyGems 中用于启用可重现的构建。
来源
# File lib/rubygems.rb, line 1166 def self.source_date_epoch_string # The value used if $SOURCE_DATE_EPOCH is not set. @default_source_date_epoch ||= Time.now.to_i.to_s specified_epoch = ENV["SOURCE_DATE_EPOCH"] # If it's empty or just whitespace, treat it like it wasn't set at all. specified_epoch = nil if !specified_epoch.nil? && specified_epoch.strip.empty? epoch = specified_epoch || @default_source_date_epoch epoch.strip end
如果设置了 SOURCE_DATE_EPOCH 环境变量,则返回其值。否则,返回首次调用 Gem.source_date_epoch_string
时的时间,格式与 SOURCE_DATE_EPOCH 相同。
注意(@duckinator):该实现有点奇怪,因为我们想要
1. Make builds reproducible by default, by having this function always return the same result during a given run. 2. Allow changing ENV['SOURCE_DATE_EPOCH'] at runtime, since multiple tests that set this variable will be run in a single process.
如果您简化此函数并导致很多测试失败,则可能是由于上面的 #2。
有关 SOURCE_DATE_EPOCH 的详细信息:reproducible-builds.org/specs/source-date-epoch/
来源
# File lib/rubygems.rb, line 913 def self.sources source_list = configuration.sources || default_sources @sources ||= Gem::SourceList.from(source_list) end
返回一个 Array
,其中包含用于从远程获取 gem 的源。如果源列表为空,则使用 default_sources
。
来源
# File lib/rubygems.rb, line 925 def self.sources=(new_sources) if !new_sources @sources = nil else @sources = Gem::SourceList.from(new_sources) end end
需要能够设置源,而无需调用 Gem.sources
.replace,因为这会导致无限循环。
文档:此注释不是关于方法本身的文档,而更像是关于实现的注释。
来源
# File lib/rubygems.rb, line 398 def self.spec_cache_dir paths.spec_cache_dir end
来源
# File lib/rubygems/defaults.rb, line 140 def self.state_file @state_file ||= File.join(Gem.state_home, "gem", "last_update_check") end
用户状态文件的标准位置路径。
来源
# File lib/rubygems/defaults.rb, line 161 def self.state_home @state_home ||= ENV["XDG_STATE_HOME"] || File.join(Gem.user_home, ".local", "state") end
用户状态目录的标准位置路径。
来源
# File lib/rubygems.rb, line 936 def self.suffix_pattern @suffix_pattern ||= "{#{suffixes.join(",")}}" end
可 require 的路径后缀的 Glob 模式。
来源
# File lib/rubygems.rb, line 943 def self.suffix_regexp @suffix_regexp ||= /#{Regexp.union(suffixes)}\z/ end
可 require 的路径后缀的 Regexp
。
来源
# File lib/rubygems.rb, line 964 def self.suffixes @suffixes ||= ["", ".rb", *%w[DLEXT DLEXT2].map do |key| val = RbConfig::CONFIG[key] next unless val && !val.empty? ".#{val}" end].compact.uniq end
可 require 的路径的后缀。
来源
# File lib/rubygems.rb, line 408 def self.target_rbconfig @target_rbconfig || Gem::TargetRbConfig.for_running_ruby end
部署目标平台的 RbConfig
对象。
这通常与运行平台相同,但如果您正在进行交叉编译,则可能会有所不同。
来源
# File lib/rubygems.rb, line 985 def self.time(msg, width = 0, display = Gem.configuration.verbose) now = Time.now value = yield elapsed = Time.now - now ui.say format("%2$*1$s: %3$3.3fs", -width, msg, elapsed) if display value end
使用调试 UI 输出打印提供的块运行所花费的时间。
来源
# File lib/rubygems.rb, line 190 def self.try_activate(path) # finds the _latest_ version... regardless of loaded specs and their deps # if another gem had a requirement that would mean we shouldn't # activate the latest version, then either it would already be activated # or if it was ambiguous (and thus unresolved) the code in our custom # require will try to activate the more specific version. spec = Gem::Specification.find_by_path path return false unless spec return true if spec.activated? begin spec.activate rescue Gem::LoadError => e # this could fail due to gem dep collisions, go lax spec_by_name = Gem::Specification.find_by_name(spec.name) if spec_by_name.nil? raise e else spec_by_name.activate end end true end
尝试激活包含 path
的 gem。如果激活成功或不需要激活(因为它已激活),则返回 true。如果在 gem 中找不到该路径,则返回 false。
来源
# File lib/rubygems.rb, line 1000 def self.ui require_relative "rubygems/user_interaction" Gem::DefaultUserInteraction.ui end
延迟加载 DefaultUserInteraction
并返回默认 UI。
来源
# File lib/rubygems.rb, line 1106 def self.use_gemdeps(path = nil) raise_exception = path path ||= ENV["RUBYGEMS_GEMDEPS"] return unless path path = path.dup if path == "-" Gem::Util.traverse_parents Dir.pwd do |directory| dep_file = GEM_DEP_FILES.find {|f| File.file?(f) } next unless dep_file path = File.join directory, dep_file break end end unless File.file? path return unless raise_exception raise ArgumentError, "Unable to find gem dependencies file at #{path}" end ENV["BUNDLE_GEMFILE"] ||= File.expand_path(path) require_relative "rubygems/user_interaction" require "bundler" begin Gem::DefaultUserInteraction.use_ui(ui) do Bundler.ui.silence do @gemdeps = Bundler.setup end ensure Gem::DefaultUserInteraction.ui.close end rescue Bundler::BundlerError => e warn e.message warn "You may need to `bundle install` to install missing gems" warn "" end end
在 path
查找 gem 依赖文件,如果找到,则激活文件中的 gem。如果找不到该文件,则会引发 ArgumentError
。
如果未给出 path
,则使用 RUBYGEMS_GEMDEPS 环境变量,但如果找不到文件,则不会引发异常。
如果为 path
指定“-”,则 RubyGems 从当前工作目录向上搜索 gem 依赖文件(gem.deps.rb、Gemfile、Isolate)并激活找到的第一个文件中的 gem。
您可以在 rubygems 启动时自动运行此操作。要启用此功能,请将 RUBYGEMS_GEMDEPS
环境变量设置为 gem 依赖文件的路径或“-”以在父目录中自动发现。
注意:在多用户系统上启用自动发现可能会导致从您无法控制的目录中使用时执行任意代码。
来源
# File lib/rubygems.rb, line 1010 def self.use_paths(home, *paths) paths.flatten! paths.compact! hash = { "GEM_HOME" => home, "GEM_PATH" => paths.empty? ? home : paths.join(File::PATH_SEPARATOR) } hash.delete_if {|_, v| v.nil? } self.paths = hash end
来源
# File lib/rubygems/defaults.rb, line 103 def self.user_dir gem_dir = File.join(Gem.user_home, ".gem") gem_dir = File.join(Gem.data_home, "gem") unless File.exist?(gem_dir) parts = [gem_dir, ruby_engine] parts << RbConfig::CONFIG["ruby_version"] unless RbConfig::CONFIG["ruby_version"].empty? File.join parts end
用户主目录中 gem 的路径。
来源
# File lib/rubygems/defaults.rb, line 96 def self.user_home @user_home ||= find_home end
用户的主目录。
来源
# File lib/rubygems.rb, line 1021 def self.win_platform? if @@win_platform.nil? ruby_platform = RbConfig::CONFIG["host_os"] @@win_platform = !WIN_PATTERNS.find {|r| ruby_platform =~ r }.nil? end @@win_platform end
这是 Windows 平台吗?
来源
# File lib/rubygems.rb, line 782 def self.write_binary(path, data) File.binwrite(path, data) rescue Errno::ENOSPC # If we ran out of space but the file exists, it's *guaranteed* to be corrupted. File.delete(path) if File.exist?(path) raise end
在所有平台上以二进制模式安全地写入文件。
私有类方法
来源
# File lib/rubygems.rb, line 1321 def already_loaded?(file) $LOADED_FEATURES.any? do |feature_path| feature_path.end_with?(file) && default_gem_load_paths.any? {|load_path_entry| feature_path == "#{load_path_entry}/#{file}" } end end
来源
# File lib/rubygems.rb, line 1327 def default_gem_load_paths @default_gem_load_paths ||= $LOAD_PATH[load_path_insert_index..-1].map do |lp| expanded = File.expand_path(lp) next expanded unless File.exist?(expanded) File.realpath(expanded) end end
来源
# File lib/rubygems/defaults.rb, line 81 def self.find_home Dir.home.dup rescue StandardError if Gem.win_platform? File.expand_path File.join(ENV["HOMEDRIVE"] || ENV["SystemDrive"], "/") else File.expand_path "/" end end
查找用户的主目录。
来源
# File lib/rubygems.rb, line 245 def self.find_spec_for_exe(name, exec_name, requirements) raise ArgumentError, "you must supply exec_name" unless exec_name dep = Gem::Dependency.new name, requirements loaded = Gem.loaded_specs[name] return loaded if loaded && dep.matches_spec?(loaded) specs = dep.matching_specs(true) specs = specs.find_all do |spec| spec.executables.include? exec_name end if exec_name unless spec = specs.first msg = "can't find gem #{dep} with executable #{exec_name}" raise Gem::GemNotFoundException, msg end spec end