class Gem::Specification
Specification 类包含 gem 的信息。通常定义在 .gemspec 文件或 Rakefile 中,看起来像这样
Gem::Specification.new do |s| s.name = 'example' s.version = '0.1.0' s.licenses = ['MIT'] s.summary = "This is an example!" s.description = "Much longer explanation of the example!" s.authors = ["Ruby Coder"] s.email = 'rubycoder@example.com' s.files = ["lib/example.rb"] s.homepage = 'https://rubygems.org.cn/gems/example' s.metadata = { "source_code_uri" => "https://github.com/example/example" } end
从 RubyGems 2.0 开始,Specification 可以包含任意元数据。有关您可以添加到规范的元数据项的格式和大小限制,请参阅 metadata。
Constants
- NONEXISTENT_SPECIFICATION_VERSION
-
未指定版本号的规范的版本号(即 RubyGems 0.7 或更早版本)。
Public Instance Methods
Source
# File lib/rubygems/specification.rb, line 186 def removed_method_calls @removed_method_calls ||= [] end
可选的 gemspec 属性
Constants
- LATEST_RUBY_WITHOUT_PATCH_VERSIONS
属性
gem 中可执行脚本的路径。通常是 'exe'
用法
spec.bindir = 'exe'
用于签名此 gem 的证书链。有关详细信息,请参阅 Gem::Security。
在 gem 安装后显示的提示消息。
用法
spec.post_install_message = "Thanks for installing!"
此 gem 所需的 RubyGems 版本
用于签名此 gem 的密钥。有关详细信息,请参阅 Gem::Security。
Public Instance Methods
Source
# File lib/rubygems/specification.rb, line 543 def add_dependency(gem, *requirements) if requirements.uniq.size != requirements.size warn "WARNING: duplicated #{gem} dependency #{requirements}" end add_dependency_with_type(gem, :runtime, requirements) end
向此 gem 添加一个名为 gem、带有 requirements 的运行时依赖项。
用法
spec.add_dependency 'example', '~> 1.1', '>= 1.1.4'
Source
# File lib/rubygems/specification.rb, line 532 def add_development_dependency(gem, *requirements) add_dependency_with_type(gem, :development, requirements) end
向此 gem 添加一个名为 gem、带有 requirements 的开发依赖项。
用法
spec.add_development_dependency 'example', '~> 1.1', '>= 1.1.4'
开发依赖项默认不安装,并且在 require gem 时不激活。
Source
# File lib/rubygems/specification.rb, line 566 def executables @executables ||= [] end
gem 中包含的可执行文件。
例如,rake gem 包含 rake 作为可执行文件。您不指定完整路径(如 bin/rake);所有应用程序风格的文件都应位于 bindir 中。这些文件必须是可执行的 Ruby 文件。使用 bash 或其他解释器的文件将无法工作。
包含的可执行文件只能是 Ruby 脚本,不能是其他语言的脚本或编译后的二进制文件。
用法
spec.executables << 'rake'
Source
# File lib/rubygems/specification.rb, line 583 def extensions @extensions ||= [] end
安装 gem 时要构建的扩展,特别是用于编译扩展的 extconf.rb 风格文件的路径。
这些文件将在 gem 安装时运行,导致 C(或其他)代码在用户的机器上编译。
用法
spec.extensions << 'ext/rmagic/extconf.rb'
有关编写 gem 扩展的信息,请参阅 Gem::Ext::Builder。
Source
# File lib/rubygems/specification.rb, line 599 def extra_rdoc_files @extra_rdoc_files ||= [] end
要添加到 RDoc 的额外文件,如 README 或 doc/examples.txt
当用户选择为 gem 生成 RDoc 文档时(通常在安装时),所有库文件都将发送给 RDoc 进行处理。此选项允许您包含一些非代码文件,以提供更完整的文档集。
用法
spec.extra_rdoc_files = ['README', 'doc/user-guide.txt']
Source
# File lib/rubygems/specification.rb, line 463 def platform=(platform) @original_platform = platform case platform when Gem::Platform::CURRENT then @new_platform = Gem::Platform.local @original_platform = @new_platform.to_s when Gem::Platform then @new_platform = platform # legacy constants when nil, Gem::Platform::RUBY then @new_platform = Gem::Platform::RUBY when "mswin32" then # was Gem::Platform::WIN32 @new_platform = Gem::Platform.new "x86-mswin32" when "i586-linux" then # was Gem::Platform::LINUX_586 @new_platform = Gem::Platform.new "x86-linux" when "powerpc-darwin" then # was Gem::Platform::DARWIN @new_platform = Gem::Platform.new "ppc-darwin" else @new_platform = Gem::Platform.new platform end @platform = @new_platform.to_s end
此 gem 运行的平台。
这通常是 Gem::Platform::RUBY 或 Gem::Platform::CURRENT。
大多数 gem 包含纯 Ruby 代码;它们应保持默认值不变。一些 gem 包含要编译成 Ruby“扩展”的 C(或其他)代码。gem 应保持默认值不变,除非代码只能在特定类型的系统上编译。一些 gem 由预编译的代码(“二进制 gem”)组成。它们尤其需要适当地设置平台属性。一个快捷方式是将平台设置为 Gem::Platform::CURRENT,这将导致 gem 构建器将平台设置为在执行构建的系统上使用的相应值。
如果此属性设置为非默认值,它将包含在构建 gem 的文件名中,例如:nokogiri-1.6.0-x86-mingw32.gem
用法
spec.platform = Gem::Platform.local
Source
# File lib/rubygems/specification.rb, line 629 def rdoc_options @rdoc_options ||= [] end
指定生成 API 文档时使用的 rdoc 选项。
用法
spec.rdoc_options << '--title' << 'Rake -- Ruby Make' << '--main' << 'README' << '--line-numbers'
Source
# File lib/rubygems/specification.rb, line 507 def require_paths=(val) @require_paths = Array(val) end
gem 中在激活此 gem 时添加到 $LOAD_PATH 的路径。如果您有扩展,则无需将 "ext" 添加到 require 路径,扩展构建过程会将扩展文件复制到“lib”中。
默认值为 "lib"
用法
# If all library files are in the root directory... spec.require_paths = ['.']
Source
# File lib/rubygems/specification.rb, line 659 def required_ruby_version=(req) @required_ruby_version = Gem::Requirement.create req @required_ruby_version.requirements.map! do |op, v| if v >= LATEST_RUBY_WITHOUT_PATCH_VERSIONS && v.release.segments.size == 4 [op == "~>" ? "=" : op, Gem::Version.new(v.segments.tap {|s| s.delete_at(3) }.join("."))] else [op, v] end end end
此 gem 所需的 Ruby 版本。Ruby 版本可以精确到补丁级别。
$ ruby -v -e 'p Gem.ruby_version' ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0] #<Gem::Version "2.0.0.247">
也可以指定预发布版本。
用法
# This gem will work with 1.8.6 or greater... spec.required_ruby_version = '>= 1.8.6' # Only with final releases of major version 2 where minor version is at least 3 spec.required_ruby_version = '~> 2.3' # Only prereleases or final releases after 2.6.0.preview2 spec.required_ruby_version = '> 2.6.0.preview2' # This gem will work with 2.3.0 or greater, including major version 3, but lesser than 4.0.0 spec.required_ruby_version = '>= 2.3', '< 4'
Source
# File lib/rubygems/specification.rb, line 674 def required_rubygems_version=(req) @required_rubygems_version = Gem::Requirement.create req end
此 gem 所需的 RubyGems 版本
Source
# File lib/rubygems/specification.rb, line 687 def requirements @requirements ||= [] end
列出此 gem 工作所需的外部(非 RubyGems)要求。它仅供用户参考。
用法
spec.requirements << 'libmagick, v6.0' spec.requirements << 'A good graphics card'
只读属性
属性
用于创建此 gem 的 RubyGems 版本。
Public Instance Methods
Source
# File lib/rubygems/specification.rb, line 714 def extensions_dir @extensions_dir ||= super end
此 gem 安装其扩展的路径。
推荐的 gemspec 属性
属性
此 gem 的详细描述。
描述应比摘要更详细,但又不至于过长。建议的长度为几段,不包含示例或格式。
用法
spec.description = <<~EOF Rake is a Make-like program implemented in Ruby. Tasks and dependencies are specified in standard Ruby syntax. EOF
此 gem 的联系电子邮件地址(或地址)。
用法
spec.email = 'john.jones@example.com' spec.email = ['jack@example.com', 'jill@example.com']
此 gem 主页的 URL。
用法
spec.homepage = 'https://github.com/ruby/rake'
元数据包含此 gem 的额外数据,可能对其他消费者有用,并且 gem 作者可以设置。
元数据项有以下限制:
-
元数据必须是
Hash对象。 -
所有键和值都必须是字符串。
-
键最多可为 128 字节,值最多可为 1024 字节。
-
所有字符串必须是 UTF-8,不允许二进制数据。
您可以使用元数据指定指向 gem 主页、代码库、文档、Wiki、邮件列表、问题跟踪器和更改日志的链接。
s.metadata = { "bug_tracker_uri" => "https://example.com/user/bestgemever/issues", "changelog_uri" => "https://example.com/user/bestgemever/CHANGELOG.md", "documentation_uri" => "https://www.example.info/gems/bestgemever/0.0.1", "homepage_uri" => "https://bestgemever.example.io", "mailing_list_uri" => "https://groups.example.com/bestgemever", "source_code_uri" => "https://example.com/user/bestgemever", "wiki_uri" => "https://example.com/user/bestgemever/wiki", "funding_uri" => "https://example.com/donate" }
这些链接将用于 rubygems.org 上的 gem 页面,并且必须通过以下正则表达式进行验证。
%r{\Ahttps?:\/\/([^\s:@]+:[^\s:@]*@)?[A-Za-z\d\-]+(\.[A-Za-z\d\-]+)+\.?(:\d{1,5})?([\/?]\S*)?\z}
此 gem 所需的 Ruby 版本。
用法
spec.required_ruby_version = '>= 2.7.0'
Public Instance Methods
Source
# File lib/rubygems/specification.rb, line 348 def license=(o) self.licenses = [o] end
此 gem 的许可证。
许可证最多不得超过 64 个字符。
这应该是您许可证的名称。许可证的完整文本应在构建 gem 时放在 gem 的顶层。
最简单的方法是指定标准的 SPDX ID spdx.org/licenses/。理想情况下,您应选择一个经过 OSI(开放标准倡议)opensource.org/licenses/ 批准的。
最常用的 OSI 批准的许可证是 MIT 和 Apache-2.0。GitHub 还在 choosealicense.com/ 上提供许可证选择器。
您还可以使用自定义许可证文件以及您的 gemspec,并指定 LicenseRef-<idstring>,其中 idstring 是包含许可证文本的文件名。
您应该为您的 gem 指定一个许可证,以便人们知道他们如何被允许使用它以及您对此施加了什么限制。不指定许可证意味着保留所有权利;他人无权出于任何目的使用该代码。
您可以使用 licenses= 设置多个许可证。
用法
spec.license = 'MIT'
Source
# File lib/rubygems/specification.rb, line 365 def licenses=(licenses) @licenses = Array licenses end
库的许可证。
每个许可证都应是简短的名称,最多 64 个字符。
这应该是您许可证的名称。许可证的完整文本应在构建 gem 时放在 gem 中。
有关更多讨论,请参阅 license=。
用法
spec.licenses = ['MIT', 'GPL-2.0']
必需的 gemspec 属性
属性
此 gem 的名称。
用法
spec.name = 'rake'
此 gem 描述的简短摘要。显示在 gem list -d 中。
description 应比摘要更详细。
用法
spec.summary = "This is a small summary of my gem"
此 gem 的版本。
版本字符串可以包含数字和句点,例如 1.0.0。如果版本包含字母,例如 1.0.0.pre,则该 gem 为 '预发布' gem。
用法
spec.version = '0.4.1'
Public Instance Methods
Source
# File lib/rubygems/specification.rb, line 247 def files # DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks) # DOC: Why isn't it normal? Why does it suck? How can we fix this? @files = [@files, @test_files, add_bindir(@executables), @extra_rdoc_files, @extensions].flatten.compact.uniq.sort end
包含在此 gem 中的文件。您不能追加到此访问器,必须对其赋值。
只将可以 require 的文件添加到此列表,不要添加目录等。
构建 gem 时会自动从此列表中删除目录,其他非文件会导致错误。
用法
require 'rake' spec.files = FileList['lib/**/*.rb', 'bin/*', '[A-Z]*'].to_a # or without Rake... spec.files = Dir['lib/**/*.rb'] + Dir['bin/*'] spec.files += Dir['[A-Z]*'] spec.files.reject! { |fn| fn.include? "CVS" }
Specification 内部
属性
当此 gemspec 已激活时为 true。此属性不会持久化。
当此 gemspec 已激活时为 true。此属性不会持久化。
此 gemspec 的 Gem::Specification 版本。
不要设置此项,在 gem 打包时会自动设置。
Public Class Methods
Source
# File lib/rubygems/specification.rb, line 1232 def self._load(str) Gem.load_yaml Gem.load_safe_marshal yaml_set = false retry_count = 0 array = begin Gem::SafeMarshal.safe_load str rescue ArgumentError => e # Avoid an infinite retry loop when the argument error has nothing to do # with the classes not being defined. # 1 retry each allowed in case all 3 of # - YAML # - YAML::Syck::DefaultKey # - YAML::PrivateType # need to be defined raise if retry_count >= 3 # # Some very old marshaled specs included references to `YAML::PrivateType` # and `YAML::Syck::DefaultKey` constants due to bugs in the old emitter # that generated them. Workaround the issue by defining the necessary # constants and retrying. # message = e.message raise unless message.include?("YAML::") unless Object.const_defined?(:YAML) Object.const_set "YAML", Psych yaml_set = true end if message.include?("YAML::Syck::") YAML.const_set "Syck", YAML unless YAML.const_defined?(:Syck) YAML::Syck.const_set "DefaultKey", Class.new if message.include?("YAML::Syck::DefaultKey") && !YAML::Syck.const_defined?(:DefaultKey) elsif message.include?("YAML::PrivateType") && !YAML.const_defined?(:PrivateType) YAML.const_set "PrivateType", Class.new end retry_count += 1 retry ensure Object.__send__(:remove_const, "YAML") if yaml_set end spec = Gem::Specification.new spec.instance_variable_set :@specification_version, array[1] current_version = CURRENT_SPECIFICATION_VERSION field_count = if spec.specification_version > current_version spec.instance_variable_set :@specification_version, current_version MARSHAL_FIELDS[current_version] else MARSHAL_FIELDS[spec.specification_version] end if array.size < field_count raise TypeError, "invalid Gem::Specification format #{array.inspect}" end spec.instance_variable_set :@rubygems_version, array[0] # spec version spec.instance_variable_set :@name, array[2] spec.instance_variable_set :@version, array[3] spec.date = array[4] spec.instance_variable_set :@summary, array[5] spec.instance_variable_set :@required_ruby_version, array[6] spec.instance_variable_set :@required_rubygems_version, array[7] spec.platform = array[8] spec.instance_variable_set :@dependencies, array[9] # offset due to rubyforge_project removal spec.instance_variable_set :@email, array[11] spec.instance_variable_set :@authors, array[12] spec.instance_variable_set :@description, array[13] spec.instance_variable_set :@homepage, array[14] # offset due to has_rdoc removal spec.instance_variable_set :@licenses, array[17] spec.instance_variable_set :@metadata, array[18] spec.instance_variable_set :@loaded, false spec.instance_variable_set :@activated, false spec end
加载自定义 marshal 格式,根据需要重新初始化默认值。
Source
# File lib/rubygems/specification.rb, line 845 def self.add_spec(spec) specification_record.add_spec(spec) end
将 spec 添加到已知规范中,保持集合正确排序。
Source
# File lib/rubygems/specification.rb, line 860 def self.all warn "NOTE: Specification.all called from #{caller(1, 1).first}" unless Gem::Deprecate.skip _all end
返回所有规范。不建议使用此方法。您可能更希望使用 Enumerable 方法之一。
Source
# File lib/rubygems/specification.rb, line 869 def self.all=(specs) specification_record.all = specs end
将已知规范设置为 specs。
Source
# File lib/rubygems/specification.rb, line 876 def self.all_names specification_record.all_names end
按排序顺序返回所有规范的完整名称。
Source
# File lib/rubygems/specification.rb, line 885 def self.array_attributes @@array_attributes.dup end
返回所有面向数组的实例变量的列表。
Source
# File lib/rubygems/specification.rb, line 894 def self.attribute_names @@attributes.dup end
返回所有实例变量的列表。
Source
# File lib/rubygems/specification.rb, line 792 def self.default_stubs(pattern = "*.gemspec") base_dir = Gem.default_dir gems_dir = File.join base_dir, "gems" gemspec_stubs_in(Gem.default_specifications_dir, pattern) do |path| Gem::StubSpecification.default_gemspec_stub(path, base_dir, gems_dir) end end
为默认 gem 返回一个 Gem::StubSpecification。
Source
# File lib/rubygems/specification.rb, line 901 def self.dirs @@dirs ||= Gem::SpecificationRecord.dirs_from(gem_path) end
返回 Specification 用于查找规范的目录。
Source
# File lib/rubygems/specification.rb, line 909 def self.dirs=(dirs) reset @@dirs = Gem::SpecificationRecord.dirs_from(Array(dirs)) end
设置 Specification 用于查找规范的目录。设置此项会重置已知规范的列表。
Source
# File lib/rubygems/specification.rb, line 921 def self.each(&block) specification_record.each(&block) end
枚举每个已知规范。请参阅 ::dirs= 和 ::add_spec 来设置规范列表。
Source
# File lib/rubygems/specification.rb, line 974 def self.find_active_stub_by_path(path) specification_record.find_active_stub_by_path(path) end
在已激活的规范中,返回包含匹配 path 的文件的最佳规范。
Source
# File lib/rubygems/specification.rb, line 935 def self.find_all_by_full_name(full_name) stubs.select {|s| s.full_name == full_name }.map(&:to_spec) end
返回所有具有给定 full_name 的规范。
Source
# File lib/rubygems/specification.rb, line 928 def self.find_all_by_name(name, *requirements) specification_record.find_all_by_name(name, *requirements) end
返回所有匹配 name 和可选 requirements 的规范。
Source
# File lib/rubygems/specification.rb, line 951 def self.find_by_full_name(full_name) stubs.find {|s| s.full_name == full_name }&.to_spec end
Find 匹配 full_name 的最佳规范。
Source
# File lib/rubygems/specification.rb, line 943 def self.find_by_name(name, *requirements) requirements = Gem::Requirement.default if requirements.empty? Gem::Dependency.new(name, *requirements).to_spec end
Find 匹配 name 和 requirements 的最佳规范。如果依赖项无法解析为有效规范,则引发异常。
Source
# File lib/rubygems/specification.rb, line 958 def self.find_by_path(path) specification_record.find_by_path(path) end
返回包含匹配 path 的文件的最佳规范。
Source
# File lib/rubygems/specification.rb, line 981 def self.find_in_unresolved(path) unresolved_specs.find_all {|spec| spec.contains_requirable_file? path } end
返回当前未解析的、包含匹配 path 的文件的规范。
Source
# File lib/rubygems/specification.rb, line 989 def self.find_in_unresolved_tree(path) unresolved_specs.each do |spec| spec.traverse do |_from_spec, _dep, to_spec, trail| if to_spec.has_conflicts? || to_spec.conflicts_when_loaded_with?(trail) :next else return trail.reverse if to_spec.contains_requirable_file? path end end end [] end
搜索所有未解析的依赖项和子依赖项,并返回包含匹配 path 的文件的规范。
Source
# File lib/rubygems/specification.rb, line 966 def self.find_inactive_by_path(path) specification_record.find_inactive_by_path(path) end
在未激活的规范中,返回包含匹配 path 的文件的最佳规范。
Source
# File lib/rubygems/specification.rb, line 1016 def self.from_yaml(input) Gem.load_yaml input = normalize_yaml_input input spec = Gem::SafeYAML.safe_load input if spec && spec.class == FalseClass raise Gem::EndOfYAMLException end unless Gem::Specification === spec raise Gem::Exception, "YAML data doesn't evaluate to gem specification" end spec.specification_version ||= NONEXISTENT_SPECIFICATION_VERSION spec.reset_nil_attributes_to_default spec.flatten_require_paths spec end
用于 YAML 文件的特殊加载器。当从 YAML 文件加载 Specification 对象时,它会绕过正常的 Ruby 对象初始化例程(initialize)。此方法弥补了这一点,并处理了不同年龄的 gem。
Source
# File lib/rubygems/specification.rb, line 1048 def self.latest_spec_for(name) specification_record.latest_spec_for(name) end
返回 gem name 的最新已安装规范。
Source
# File lib/rubygems/specification.rb, line 1041 def self.latest_specs(prerelease = false) specification_record.latest_specs(prerelease) end
返回最新规范,如果 prerelease 为 true,则可选地包含预发布规范。
Source
# File lib/rubygems/specification.rb, line 1069 def self.load(file) return unless file spec = @load_cache_mutex.synchronize { @load_cache[file] } return spec if spec return unless File.file?(file) code = Gem.open_file(file, "r:UTF-8:-", &:read) begin spec = eval code, binding, file if Gem::Specification === spec spec.loaded_from = File.expand_path file.to_s @load_cache_mutex.synchronize do prev = @load_cache[file] if prev spec = prev else @load_cache[file] = spec end end return spec end warn "[#{file}] isn't a Gem::Specification (#{spec.class} instead)." rescue SignalException, SystemExit raise rescue SyntaxError, StandardError => e warn "Invalid gemspec in [#{file}]: #{e}" end nil end
从 file 加载 Ruby 格式的 gemspec。
Source
# File lib/rubygems/specification.rb, line 833 def self.load_defaults each_spec([Gem.default_specifications_dir]) do |spec| # #load returns nil if the spec is bad, so we just ignore # it at this stage Gem.register_default_spec(spec) end end
加载默认规范。应只调用一次。
Source
# File lib/rubygems/specification.rb, line 1926 def initialize(name = nil, version = nil) super() @gems_dir = nil @base_dir = nil @loaded = false @activated = false @loaded_from = nil @original_platform = nil @installed_by_version = nil set_nil_attributes_to_nil set_not_nil_attributes_to_default_values @new_platform = Gem::Platform::RUBY self.name = name if name self.version = version if version if (platform = Gem.platforms.last) && platform != Gem::Platform::RUBY && platform != Gem::Platform.local self.platform = platform end yield self if block_given? end
Specification 构造函数。将默认值分配给属性,并 yield 本身以供进一步初始化。可选地接受 name 和 version。
Gem::BasicSpecification::newSource
# File lib/rubygems/specification.rb, line 1108 def self.non_nil_attributes @@non_nil_attributes.dup end
Specification 属性必须是非 nil 的。
Source
# File lib/rubygems/specification.rb, line 1115 def self.normalize_yaml_input(input) result = input.respond_to?(:read) ? input.read : input result = "--- " + result unless result.start_with?("--- ") result = result.dup result.gsub!(/ !!null \n/, " \n") # date: 2011-04-26 00:00:00.000000000Z # date: 2011-04-26 00:00:00.000000000 Z result.gsub!(/^(date: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+?)Z/, '\1 Z') result end
确保 YAML 规范正确格式化,带有连字符。
Source
# File lib/rubygems/specification.rb, line 1133 def self.outdated outdated_and_latest_version.map {|local, _| local.name } end
返回所有过时的本地 gem 名称列表。此方法开销很大,因为它必须从服务器获取规范。
如果您希望检索最新的远程版本,请使用 outdated_and_latest_version。
Source
# File lib/rubygems/specification.rb, line 1144 def self.outdated_and_latest_version return enum_for __method__ unless block_given? # TODO: maybe we should switch to rubygems' version service? fetcher = Gem::SpecFetcher.fetcher latest_specs(true).each do |local_spec| dependency = Gem::Dependency.new local_spec.name, ">= #{local_spec.version}" remotes, = fetcher.search_for_dependency dependency remotes = remotes.map {|n, _| n.version } latest_remote = remotes.sort.last yield [local_spec, latest_remote] if latest_remote && local_spec.version < latest_remote end nil end
枚举过时的本地 gem,yield 本地规范和最新的远程版本。
此方法可能需要一段时间才能返回,因为它必须检查每个本地 gem 是否与服务器的索引匹配。
Source
# File lib/rubygems/specification.rb, line 852 def self.remove_spec(spec) specification_record.remove_spec(spec) end
从已知规范中删除 spec。
Source
# File lib/rubygems/specification.rb, line 1169 def self.required_attribute?(name) @@required_attributes.include? name.to_sym end
name 是必需的属性吗?
Source
# File lib/rubygems/specification.rb, line 1176 def self.required_attributes @@required_attributes.dup end
必需的规范属性。
Source
# File lib/rubygems/specification.rb, line 1184 def self.reset @@dirs = nil Gem.pre_reset_hooks.each(&:call) @specification_record = nil clear_load_cache unless unresolved_deps.empty? unresolved = unresolved_deps.filter_map do |name, dep| matching_versions = find_all_by_name(name) next if dep.latest_version? && matching_versions.any?(&:default_gem?) [dep, matching_versions.uniq(&:full_name)] end.to_h unless unresolved.empty? warn "WARN: Unresolved or ambiguous specs during Gem::Specification.reset:" unresolved.each do |dep, versions| warn " #{dep}" unless versions.empty? warn " Available/installed versions of this gem:" versions.each {|s| warn " - #{s.version}" } end end warn "WARN: Clearing out unresolved specs. Try 'gem cleanup <gem>'" warn "Please report a bug if this causes problems." end unresolved_deps.clear end Gem.post_reset_hooks.each(&:call) end
重置已知规范列表,运行在 Gem 中注册的 pre 和 post reset 钩子。
Source
# File lib/rubygems/specification.rb, line 1220 def self.specification_record @specification_record ||= Gem::SpecificationRecord.new(dirs) end
跟踪所有当前已知的规范。
Source
# File lib/rubygems/specification.rb, line 785 def self.stubs specification_record.stubs end
返回已安装的每个 gem 的 Gem::StubSpecification。
Source
# File lib/rubygems/specification.rb, line 804 def self.stubs_for(name) specification_record.stubs_for(name) end
返回已安装的名为 name 的 gem 的 Gem::StubSpecification。仅返回匹配 Gem.platforms 的 stub。
Source
# File lib/rubygems/specification.rb, line 1225 def self.unresolved_deps @unresolved_deps ||= Hash.new {|h, n| h[n] = Gem::Dependency.new n } end
DOC:此方法需要文档记录或 nodoc_d。
私有类方法
Source
# File lib/rubygems/specification.rb, line 1003 def self.unresolved_specs unresolved_deps.values.flat_map(&:to_specs) end
Public Instance Methods
Source
# File lib/rubygems/specification.rb, line 1337 def _dump(limit) Marshal.dump [ @rubygems_version, @specification_version, @name, @version, date, @summary, @required_ruby_version, @required_rubygems_version, @original_platform, @dependencies, "", # rubyforge_project @email, @authors, @description, @homepage, true, # has_rdoc @new_platform, @licenses, @metadata, ] end
仅转储关键实例变量。
Source
# File lib/rubygems/specification.rb, line 1426 def abbreviate self.files = [] self.test_files = [] self.rdoc_options = [] self.extra_rdoc_files = [] self.cert_chain = [] end
缩短 spec 以供下载。缩短的 spec 仅用于搜索、下载和相关活动,不需要部署特定信息(例如文件列表)。因此,我们缩短了 spec,使其更小,下载速度更快。
Source
# File lib/rubygems/specification.rb, line 1367 def activate other = Gem.loaded_specs[name] if other check_version_conflict other return false end raise_if_conflicts activate_dependencies add_self_to_load_path Gem.loaded_specs[name] = self @activated = true @loaded = true true end
激活此 spec,将其注册为已加载的 spec,并将其实例路径添加到 $LOAD_PATH。如果 spec 在激活时存在冲突,则返回 true,如果之前已激活,则返回 false。
Source
# File lib/rubygems/specification.rb, line 1391 def activate_dependencies unresolved = Gem::Specification.unresolved_deps runtime_dependencies.each do |spec_dep| if loaded = Gem.loaded_specs[spec_dep.name] next if spec_dep.matches_spec? loaded msg = "can't satisfy '#{spec_dep}', already activated '#{loaded.full_name}'" e = Gem::LoadError.new msg e.name = spec_dep.name raise e end specs = spec_dep.matching_specs(true).uniq(&:full_name) if specs.size == 0 raise Gem::MissingSpecError.new(spec_dep.name, spec_dep.requirement, "at: #{spec_file}") elsif specs.size == 1 specs.first.activate else name = spec_dep.name unresolved[name] = unresolved[name].merge spec_dep end end unresolved.delete self.name end
激活此 spec 的所有明确解析的运行时依赖项。将任何模棱两可的依赖项添加到未解析列表中,以便稍后按需解析。
Source
# File lib/rubygems/specification.rb, line 1462 def add_bindir(executables) return nil if executables.nil? if @bindir Array(executables).map {|e| File.join(@bindir, e) } else executables end rescue StandardError nil end
返回一个数组,其中 bindir 已附加到 executables 列表中的每个可执行文件。
Source
# File lib/rubygems/specification.rb, line 1501 def add_self_to_load_path return if default_gem? paths = full_require_paths Gem.add_to_load_path(*paths) end
将此 spec 的 require 路径添加到 LOAD_PATH,放在正确的位置。
Source
# File lib/rubygems/specification.rb, line 1980 def base_dir return Gem.dir unless loaded_from @base_dir ||= if default_gem? File.dirname File.dirname File.dirname loaded_from else File.dirname File.dirname loaded_from end end
Source
# File lib/rubygems/specification.rb, line 1531 def bin_dir @bin_dir ||= File.join gem_dir, bindir end
返回已安装 gem 的 bin 目录的完整路径。
注意:不要将其与 bindir 混淆,bindir 只是 'bin',而不是完整路径。
Source
# File lib/rubygems/specification.rb, line 1538 def bin_file(name) File.join bin_dir, name end
返回此 gem 中名为 name 的可执行文件的完整路径。
Source
# File lib/rubygems/specification.rb, line 1545 def build_args if File.exist? build_info_file build_info = File.readlines build_info_file build_info = build_info.map(&:strip) build_info.delete "" build_info else [] end end
返回用于安装 gem 的 build_args。
Source
# File lib/rubygems/specification.rb, line 1593 def build_info_dir File.join base_dir, "build_info" end
返回构建信息目录的完整路径。
Source
# File lib/rubygems/specification.rb, line 1601 def build_info_file File.join build_info_dir, "#{full_name}.info" end
返回 gem 安装时生成的构建信息文件的完整路径。
Source
# File lib/rubygems/specification.rb, line 1609 def cache_dir File.join base_dir, "cache" end
返回包含此 spec 的缓存 gem 的缓存目录的完整路径。
Source
# File lib/rubygems/specification.rb, line 1616 def cache_file File.join cache_dir, "#{full_name}.gem" end
返回此 spec 的缓存 gem 的完整路径。
Source
# File lib/rubygems/specification.rb, line 1623 def conflicts conflicts = {} runtime_dependencies.each do |dep| spec = Gem.loaded_specs[dep.name] if spec && !spec.satisfies_requirement?(dep) (conflicts[spec] ||= []) << dep end end env_req = Gem.env_requirement(name) (conflicts[self] ||= []) << env_req unless env_req.satisfied_by? version conflicts end
返回与当前已加载规范的任何可能冲突。
Source
# File lib/rubygems/specification.rb, line 1667 def date @date ||= Time.utc(*Gem.source_date_epoch.utc.to_a[3..5].reverse) end
创建此 gem 的日期。
如果 SOURCE_DATE_EPOCH 设置为环境变量,则使用它来支持可重现的构建;否则,默认为当前 UTC 日期。
SOURCE_DATE_EPOCH 的详细信息:reproducible-builds.org/specs/source-date-epoch/
Source
# File lib/rubygems/specification.rb, line 1687 def date=(date) # We want to end up with a Time object with one-day resolution. # This is the cleanest, most-readable, faster-than-using-Date # way to do it. @date = case date when String then if DateTimeFormat =~ date Time.utc($1.to_i, $2.to_i, $3.to_i) else raise(Gem::InvalidSpecificationException, "invalid date format in specification: #{date.inspect}") end when Time, DateLike then Time.utc(date.year, date.month, date.day) else TODAY end end
创建此 gem 的日期。
不要设置此项,在 gem 打包时会自动设置。
Source
# File lib/rubygems/specification.rb, line 1709 def default_value(name) @@default_value[name] end
规范属性 name 的默认值。
Source
# File lib/rubygems/specification.rb, line 1719 def dependencies @dependencies ||= [] end
此 gem 所依赖的 Gem::Dependency 对象列表。
使用 add_dependency 或 add_development_dependency 向 gem 添加依赖项。
Source
# File lib/rubygems/specification.rb, line 1729 def dependent_gems(check_dev = true) out = [] Gem::Specification.each do |spec| deps = check_dev ? spec.dependencies : spec.runtime_dependencies deps.each do |dep| next unless satisfies_requirement?(dep) sats = [] find_all_satisfiers(dep) do |sat| sats << sat end out << [spec, dep, sats] end end out end
返回所有依赖于此 gemspec 的 gem 列表。列表结构包含符合以下条件的条目:
[depending_gem, dependency, [list_of_gems_that_satisfy_dependency]]
Source
# File lib/rubygems/specification.rb, line 1748 def dependent_specs runtime_dependencies.flat_map(&:to_specs) end
返回所有与此 spec 的运行时依赖项匹配的规范。
Source
# File lib/rubygems/specification.rb, line 1755 def description=(str) @description = str.to_s end
此 gem 的详细描述。另请参阅 summary。
Source
# File lib/rubygems/specification.rb, line 1762 def development_dependencies dependencies.select {|d| d.type == :development } end
用于开发的依赖项列表。
Source
# File lib/rubygems/specification.rb, line 1774 def doc_dir(type = nil) @doc_dir ||= File.join base_dir, "doc", full_name if type File.join @doc_dir, type else @doc_dir end end
返回此 spec 的文档目录的完整路径。如果提供了 type,则会附加到末尾。例如:
spec.doc_dir # => "/path/to/gem_repo/doc/a-1" spec.doc_dir 'ri' # => "/path/to/gem_repo/doc/a-1/ri"
Source
# File lib/rubygems/specification.rb, line 1804 def executable (val = executables) && val.first end
executables 的单数访问器。
Source
# File lib/rubygems/specification.rb, line 1811 def executable=(o) self.executables = [o] end
executables 的单数访问器。
Source
# File lib/rubygems/specification.rb, line 1818 def executables=(value) @executables = Array(value) end
将可执行文件设置为 value,确保它是数组。
Source
# File lib/rubygems/specification.rb, line 1825 def extensions=(extensions) @extensions = Array extensions end
将扩展设置为 extensions,确保它是数组。
Source
# File lib/rubygems/specification.rb, line 1832 def extra_rdoc_files=(files) @extra_rdoc_files = Array files end
将 extra_rdoc_files 设置为 files,确保它是数组。
Source
# File lib/rubygems/specification.rb, line 1841 def file_name "#{full_name}.gem" end
gem 的默认(生成)文件名。另请参阅 spec_name。
spec.file_name # => "example-1.0.gem"
Source
# File lib/rubygems/specification.rb, line 1848 def files=(files) @files = Array files end
将文件设置为 files,确保它是数组。
Source
# File lib/rubygems/specification.rb, line 1866 def for_cache spec = dup spec.files = nil spec.test_files = nil spec end
创建一个重复的 spec,但不包含运行时不使用的的大型 blob。
Source
# File lib/rubygems/specification.rb, line 1883 def gems_dir @gems_dir ||= File.join(base_dir, "gems") end
Source
# File lib/rubygems/specification.rb, line 1649 def has_conflicts? return true unless Gem.env_requirement(name).satisfied_by?(version) runtime_dependencies.any? do |dep| spec = Gem.loaded_specs[dep.name] spec && !spec.satisfies_requirement?(dep) end rescue ArgumentError => e raise e, "#{name} #{version}: #{e.message}" end
如果与当前已加载的规范存在潜在冲突,则返回 true。
Source
# File lib/rubygems/specification.rb, line 1955 def initialize_copy(other_spec) self.class.array_attributes.each do |name| name = :"@#{name}" next unless other_spec.instance_variable_defined? name begin val = other_spec.instance_variable_get(name) if val instance_variable_set name, val.dup elsif Gem.configuration.really_verbose warn "WARNING: #{full_name} has an invalid nil value for #{name}" end rescue TypeError e = Gem::FormatException.new \ "#{full_name} has an invalid value for #{name}" e.file_path = loaded_from raise e end end @required_ruby_version = other_spec.required_ruby_version.dup @required_rubygems_version = other_spec.required_rubygems_version.dup end
复制 other_spec 中的 Array 和 Gem::Requirement 属性,因此状态不会共享。
Source
# File lib/rubygems/specification.rb, line 2504 def keep_only_files_and_directories @executables.delete_if {|x| File.directory?(File.join(@bindir, x)) } @extensions.delete_if {|x| File.directory?(x) && !File.symlink?(x) } @extra_rdoc_files.delete_if {|x| File.directory?(x) && !File.symlink?(x) } @files.delete_if {|x| File.directory?(x) && !File.symlink?(x) } @test_files.delete_if {|x| File.directory?(x) && !File.symlink?(x) } end
Source
# File lib/rubygems/specification.rb, line 2000 def lib_files @files.select do |file| require_paths.any? do |path| file.start_with? path end end end
Gem 中位于 require_paths 之一下的文件。
Source
# File lib/rubygems/specification.rb, line 2011 def license licenses.first end
licenses 的单数访问器。
Source
# File lib/rubygems/specification.rb, line 2020 def licenses @licenses ||= [] end
设置许可证的复数访问器。
有关详细信息,请参阅 license=。
Source
# File lib/rubygems/specification.rb, line 2055 def missing_extensions? return false if extensions.empty? return false if default_gem? return false if File.exist? gem_build_complete_path true end
此规范是否缺少其扩展?当此返回 true 时,您可能希望执行 build_extensions。
Source
# File lib/rubygems/specification.rb, line 2086 def name_tuple Gem::NameTuple.new name, version, original_platform end
返回表示此 Specification 的 NameTuple。
Source
# File lib/rubygems/specification.rb, line 2069 def normalize if defined?(@extra_rdoc_files) && @extra_rdoc_files @extra_rdoc_files.uniq! @files ||= [] @files.concat(@extra_rdoc_files) end @files = @files.uniq.sort if @files @extensions = @extensions.uniq.sort if @extensions @test_files = @test_files.uniq.sort if @test_files @executables = @executables.uniq.sort if @executables @extra_rdoc_files = @extra_rdoc_files.uniq.sort if @extra_rdoc_files end
规范文件列表,以便:
-
删除所有文件列表中的冗余项。
-
在
extra_rdoc_files中引用的文件包含在打包文件列表中。
Source
# File lib/rubygems/specification.rb, line 2112 def platform @new_platform ||= Gem::Platform::RUBY # rubocop:disable Naming/MemoizedInstanceVariableName end
此 gem 运行的平台。有关详细信息,请参阅 Gem::Platform。
Source
# File lib/rubygems/specification.rb, line 2178 def rdoc_options=(options) @rdoc_options = Array options end
将 rdoc_options 设置为 value,确保它是数组。
Source
# File lib/rubygems/specification.rb, line 2185 def require_path (val = require_paths) && val.first end
require_paths 的单数访问器。
Source
# File lib/rubygems/specification.rb, line 2192 def require_path=(path) self.require_paths = Array(path) end
require_paths 的单数访问器。
Source
# File lib/rubygems/specification.rb, line 2199 def requirements=(req) @requirements = Array req end
将需求设置为 req,确保它是数组。
Source
# File lib/rubygems/specification.rb, line 2544 def reset_nil_attributes_to_default nil_attributes = self.class.non_nil_attributes.find_all do |name| !instance_variable_defined?("@#{name}") || instance_variable_get("@#{name}").nil? end nil_attributes.each do |attribute| default = default_value attribute value = case default when Time, Numeric, Symbol, true, false, nil then default else default.dup end instance_variable_set "@#{attribute}", value end @installed_by_version ||= nil nil end
将 nil 属性重置为其默认值,以使 spec 有效。
Source
# File lib/rubygems/specification.rb, line 2210 def ri_dir @ri_dir ||= File.join base_dir, "ri", full_name end
返回此 spec 的 ri 目录的完整路径。
Source
# File lib/rubygems/specification.rb, line 2243 def runtime_dependencies dependencies.select(&:runtime?) end
运行时将自动激活的依赖项列表。
Source
# File lib/rubygems/specification.rb, line 1439 def sanitize self.summary = sanitize_string(summary) self.description = sanitize_string(description) self.post_install_message = sanitize_string(post_install_message) self.authors = authors.collect {|a| sanitize_string(a) } end
清理 spec 中的描述性字段。有时非 ASCII 字符会弄乱站点索引。非 ASCII 字符将被替换为其 XML 实体等价物。
Source
# File lib/rubygems/specification.rb, line 1449 def sanitize_string(string) return string unless string # HACK: the #to_s is in here because RSpec has an Array of Arrays of # Strings for authors. Need a way to disallow bad values on gemspec # generation. (Probably won't happen.) string.to_s end
清理单个字符串。
Source
# File lib/rubygems/specification.rb, line 2259 def satisfies_requirement?(dependency) @name == dependency.name && dependency.requirement.satisfied_by?(@version) end
检查此规范是否满足 dependency 的要求。
Source
# File lib/rubygems/specification.rb, line 2267 def sort_obj [@name, @version, Gem::Platform.sort_priority(@new_platform)] end
返回一个可用于在 sort_by 中排序规范的对象。
Source
# File lib/rubygems/specification.rb, line 2282 def spec_dir @spec_dir ||= File.join base_dir, "specifications" end
返回包含此规范的 gemspec 文件的目录的完整路径。例如:/usr/local/lib/ruby/gems/1.8/specifications
Source
# File lib/rubygems/specification.rb, line 2290 def spec_file @spec_file ||= File.join spec_dir, "#{full_name}.gemspec" end
返回此规范的 gemspec 文件的完整路径。例如:/usr/local/lib/ruby/gems/1.8/specifications/mygem-1.0.gemspec
Source
# File lib/rubygems/specification.rb, line 2299 def spec_name "#{full_name}.gemspec" end
gemspec 的默认名称。另请参阅 file_name
spec.spec_name # => "example-1.0.gemspec"
Source
# File lib/rubygems/specification.rb, line 2306 def summary=(str) @summary = str.to_s.strip. gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').gsub(/\n[ \t]*/, " ") # so. weird. end
此 gem 描述的简短摘要。
Source
# File lib/rubygems/specification.rb, line 2349 def to_ruby result = [] result << "# -*- encoding: utf-8 -*-" result << "#{Gem::StubSpecification::PREFIX}#{name} #{version} #{platform} #{raw_require_paths.join("\0")}" result << "#{Gem::StubSpecification::PREFIX}#{extensions.join "\0"}" unless extensions.empty? result << nil result << "Gem::Specification.new do |s|" result << " s.name = #{ruby_code name}" result << " s.version = #{ruby_code version}" unless platform.nil? || platform == Gem::Platform::RUBY result << " s.platform = #{ruby_code original_platform}" end result << "" result << " s.required_rubygems_version = #{ruby_code required_rubygems_version} if s.respond_to? :required_rubygems_version=" if metadata && !metadata.empty? result << " s.metadata = #{ruby_code metadata} if s.respond_to? :metadata=" end result << " s.require_paths = #{ruby_code raw_require_paths}" handled = [ :dependencies, :name, :platform, :require_paths, :required_rubygems_version, :specification_version, :version, :metadata, :signing_key, ] @@attributes.each do |attr_name| next if handled.include? attr_name current_value = send(attr_name) if current_value != default_value(attr_name) || self.class.required_attribute?(attr_name) result << " s.#{attr_name} = #{ruby_code current_value}" end end if String === signing_key result << " s.signing_key = #{ruby_code signing_key}" end if @installed_by_version result << nil result << " s.installed_by_version = #{ruby_code Gem::VERSION}" end unless dependencies.empty? result << nil result << " s.specification_version = #{specification_version}" result << nil dependencies.each do |dep| dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>.freeze, #{ruby_code dep.requirements_list})" end end result << "end" result << nil result.join "\n" end
返回此规范的 Ruby 代码表示形式,以便可以对其进行 eval 并稍后重建相同的规范。仍具有默认值的属性将被省略。
Source
# File lib/rubygems/specification.rb, line 2423 def to_ruby_for_cache for_cache.to_ruby end
返回此规范的 Ruby 轻量级代码表示形式,仅用于索引。
请参阅 to_ruby。
Source
# File lib/rubygems/specification.rb, line 2465 def traverse(trail = [], visited = {}, &block) trail.push(self) begin runtime_dependencies.each do |dep| dep.matching_specs(true).each do |dep_spec| next if visited.key?(dep_spec) visited[dep_spec] = true trail.push(dep_spec) begin result = block[self, dep, dep_spec, trail] ensure trail.pop end next if result == :next spec_name = dep_spec.name dep_spec.traverse(trail, visited, &block) unless trail.any? {|s| s.name == spec_name } end end ensure trail.pop end end
递归遍历此规范的依赖项,为每个跳转执行 block。
Source
# File lib/rubygems/specification.rb, line 2496 def validate(packaging = true, strict = false) normalize validation_policy = Gem::SpecificationPolicy.new(self) validation_policy.packaging = packaging validation_policy.validate(strict) end
检查规范是否包含所有必需的字段,并进行非常基本的健全性检查。
如果规范未通过检查,则引发 InvalidSpecificationException。
Source
# File lib/rubygems/specification.rb, line 2512 def validate_for_resolution Gem::SpecificationPolicy.new(self).validate_for_resolution end
Source
# File lib/rubygems/specification.rb, line 2519 def version=(version) @version = version.nil? ? version : Gem::Version.create(version) end
将版本设置为 version。
私有实例方法
Source
# File lib/rubygems/specification.rb, line 1479 def add_dependency_with_type(dependency, type, requirements) requirements = if requirements.empty? Gem::Requirement.default else requirements.flatten end unless dependency.respond_to?(:name) && dependency.respond_to?(:requirement) dependency = Gem::Dependency.new(dependency.to_s, requirements, type) end dependencies << dependency end
添加对 gem dependency 的依赖,类型为 type,要求 requirements。当前有效的类型为 :runtime 和 :development。
Source
# File lib/rubygems/specification.rb, line 1855 def find_all_satisfiers(dep) Gem::Specification.each do |spec| yield spec if spec.satisfies_requirement? dep end end
查找满足 dep 的所有 gem
Source
# File lib/rubygems/specification.rb, line 2218 def ruby_code(obj) case obj when String then obj.dump + ".freeze" when Array then "[" + obj.map {|x| ruby_code x }.join(", ") + "]" when Hash then seg = obj.keys.sort.map {|k| "#{k.to_s.dump} => #{obj[k].to_s.dump}" } "{ #{seg.join(", ")} }" when Gem::Version then ruby_code(obj.to_s) when DateLike then obj.strftime("%Y-%m-%d").dump when Time then obj.strftime("%Y-%m-%d").dump when Numeric then obj.inspect when true, false, nil then obj.inspect when Gem::Platform then "Gem::Platform.new(#{ruby_code obj.to_a})" when Gem::Requirement then list = obj.as_list "Gem::Requirement.new(#{ruby_code(list.size == 1 ? obj.to_s : list)})" else raise Gem::Exception, "ruby_code case not handled: #{obj.class}" end end
返回包含给定对象 Ruby 代码表示形式的字符串。
Source
# File lib/rubygems/specification.rb, line 2250 def same_attributes?(spec) @@attributes.all? {|name, _default| send(name) == spec.send(name) } end
如果此 gem 与 other 具有相同的属性,则为 true。