class Gem::RequestSet::GemDependencyAPI

用于 Bundler Gemfile 和 Isolate gem 依赖文件的一个半兼容 DSL。

为了同时兼容 Bundler Gemfile 和 Isolate 格式,此实现采取了一些灵活的处理方式,以允许与两者兼容,最显著的是在 source 中。

一个基本的 gem 依赖文件如下所示:

source 'https://rubygems.org.cn'

gem 'rails', '3.2.14a
gem 'devise', '~> 2.1', '>= 2.1.3'
gem 'cancan'
gem 'airbrake'
gem 'pg'

RubyGems 建议将其保存为 gem.deps.rb,而不是 Gemfile 或 Isolate。

要安装此 Gemfile 中的 gem,请使用 ‘gem install -g` 安装并创建一个 lockfile。lockfile 将确保当您更改 gem 依赖文件时,对 gem 的依赖项所做的更改量最少。

RubyGems 可以在启动时使用 RUBYGEMS_GEMDEPS 环境变量或通过 Gem.use_gemdeps 激活您的依赖文件中的所有 gem。有关详细信息和警告,请参阅 Gem.use_gemdeps

有关更多详细信息,请参阅 ‘gem help install` 和 `gem help gem_dependencies`。

属性

dependencies[R]

gem 语句在 gem.deps.rb 文件中需要的 gem

requires[R]

一个包含 gem 名称和要从这些 gem 中 require 的文件的哈希。

公共类方法

new(set, path) 点击切换源代码

创建一个新的 GemDependencyAPI,它将根据 path 中的依赖 API 描述将依赖项添加到 Gem::RequestSet set

# File rubygems/request_set/gem_dependency_api.rb, line 197
def initialize(set, path)
  @set = set
  @path = path

  @current_groups     = nil
  @current_platforms  = nil
  @current_repository = nil
  @dependencies       = {}
  @default_sources    = true
  @git_set            = @set.git_set
  @git_sources        = {}
  @installing         = false
  @requires           = Hash.new {|h, name| h[name] = [] }
  @vendor_set         = @set.vendor_set
  @source_set         = @set.source_set
  @gem_sources        = {}
  @without_groups     = []

  git_source :github do |repo_name|
    repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include? "/"

    "https://github.com/#{repo_name}.git"
  end

  git_source :bitbucket do |repo_name|
    repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include? "/"

    user, = repo_name.split "/", 2

    "https://#{user}@bitbucket.org/#{repo_name}.git"
  end
end

公共实例方法

git_source(name, &callback) 点击切换源代码

定义一个自定义的 git 源,它使用 name 来展开 git 存储库,用于从 git 存储库构建的 gem。您必须提供一个接受 git 存储库名称以进行扩展的块。

# File rubygems/request_set/gem_dependency_api.rb, line 605
def git_source(name, &callback)
  @git_sources[name] = callback
end
load() 点击切换源代码

加载 gem 依赖文件并返回自身。

# File rubygems/request_set/gem_dependency_api.rb, line 282
def load
  instance_eval File.read(@path), @path, 1

  self
end

私有实例方法

pin_gem_source(name, type = :default, source = nil) 点击切换源代码

将 gem name 固定到给定的 source。从不同的 source 添加具有相同名称的 gem 将引发异常。

# File rubygems/request_set/gem_dependency_api.rb, line 695
def pin_gem_source(name, type = :default, source = nil)
  source_description =
    case type
    when :default then "(default)"
    when :path    then "path: #{source}"
    when :git     then "git: #{source}"
    when :source  then "source: #{source}"
    else               "(unknown)"
    end

  raise ArgumentError,
    "duplicate source #{source_description} for gem #{name}" if
      @gem_sources.fetch(name, source) != source

  @gem_sources[name] = source
end

Gem 依赖 DSL

↑ 顶部

公共实例方法

gem(name) 点击切换源代码
gem(name, *requirements)
gem(name, *requirements, options)

使用给定的 namerequirements 指定 gem 依赖项。您还可以在 requirements 之后提供 options

options 包括

require

RubyGems 不提供任何自动 require 功能,因此 gem 依赖文件中的 requires 会被记录但被忽略。

在 bundler 中,require: 选项会覆盖 Bundler.require 期间要 require 的文件。默认情况下,依赖项的名称在 Bundler 中是 require 的。可以给出单个文件或文件数组。

要禁用 require 任何文件,请给出 false

gem 'rake', require: false
group

将依赖项放置在给定的依赖项组中。可以给出单个组或组数组。

另请参阅 group

platform

仅在给定的平台上安装依赖项。可以给出单个平台或平台数组。

有关可用平台列表,请参阅 platform

path

从给定目录中解压的 gem 安装此依赖项。

gem 'modified_gem', path: 'vendor/modified_gem'
git

从 git 存储库安装此依赖项

gem 'private_gem', git: '[email protected]:private_gem.git'
gist

从 gist ID 安装此依赖项

gem 'bang', gist: '1232884'
github

从 github git 存储库安装此依赖项

gem 'private_gem', github: 'my_company/private_gem'
submodules

设置为 true 以在获取 git:、gist: 和 github: 依赖项的 git 存储库时包含子模块。

ref

对于 git:、gist: 和 github: 依赖项,使用给定的提交名称或 SHA。

branch

对于 git:、gist: 和 github: 依赖项,使用给定的分支。

tag

对于 git:、gist: 和 github: 依赖项,使用给定的标签。

# File rubygems/request_set/gem_dependency_api.rb, line 359
  def gem(name, *requirements)
    options = requirements.pop if requirements.last.is_a?(Hash)
    options ||= {}

    options[:git] = @current_repository if @current_repository

    source_set = false

    source_set ||= gem_path       name, options
    source_set ||= gem_git        name, options
    source_set ||= gem_git_source name, options
    source_set ||= gem_source     name, options

    duplicate = @dependencies.include? name

    @dependencies[name] =
      if requirements.empty? && !source_set
        Gem::Requirement.default
      elsif source_set
        Gem::Requirement.source_set
      else
        Gem::Requirement.create requirements
      end

    return unless gem_platforms name, options

    groups = gem_group name, options

    return unless (groups & @without_groups).empty?

    pin_gem_source name, :default unless source_set

    gem_requires name, options

    if duplicate
      warn <<-WARNING
Gem dependencies file #{@path} requires #{name} more than once.
      WARNING
    end

    @set.gem name, *requirements
  end
gemspec(options = {}) 点击切换源代码

从 gemspec 文件加载依赖项。

options 包括

name

gemspec 文件的名称部分。默认为在当前目录中搜索任何 gemspec 文件。

gemspec name: 'my_gem'
path

gemspec 所在的路径。默认为当前目录

gemspec 'my_gem', path: 'gemspecs', name: 'my_gem'
development_group

将开发依赖项添加到的组。默认情况下为 :development。只能指定一个组。

# File rubygems/request_set/gem_dependency_api.rb, line 638
def gemspec(options = {})
  name              = options.delete(:name) || "{,*}"
  path              = options.delete(:path) || "."
  development_group = options.delete(:development_group) || :development

  spec = find_gemspec name, path

  groups = gem_group spec.name, {}

  self_dep = Gem::Dependency.new spec.name, spec.version

  add_dependencies groups, [self_dep]
  add_dependencies groups, spec.runtime_dependencies

  @dependencies[spec.name] = Gem::Requirement.source_set

  spec.dependencies.each do |dep|
    @dependencies[dep.name] = dep.requirement
  end

  groups << development_group

  add_dependencies groups, spec.development_dependencies

  @vendor_set.add_vendor_gem spec.name, path
  gem_requires spec.name, options
end
git(repository) { || ... } 点击切换源代码

用于从 git repository 指定 gem 的块形式。

git 'https://github.com/rails/rails.git' do
  gem 'activesupport'
  gem 'activerecord'
end
# File rubygems/request_set/gem_dependency_api.rb, line 592
def git(repository)
  @current_repository = repository

  yield
ensure
  @current_repository = nil
end
group(*groups) { || ... } 点击切换源代码

用于将依赖项放置在给定的 groups 中的块形式。

group :development do
  gem 'debugger'
end

group :development, :test do
  gem 'minitest'
end

可以使用 ‘gem install -g –without development` 在安装时排除组。有关更多详细信息,请参阅 `gem help install` 和 `gem help gem_dependencies`。

# File rubygems/request_set/gem_dependency_api.rb, line 683
def group(*groups)
  @current_groups = groups

  yield
ensure
  @current_groups = nil
end
platform(*platforms) { || ... } 点击切换源代码

用于将 gem 限制为一组平台的块形式。

gem 依赖平台的平台与 Gem::Platform 不同。gem.deps.rb 平台的平台与 ruby 引擎、ruby 版本以及是否允许 windows 相匹配。

:ruby, :ruby_XY

匹配非 windows、非 jruby 实现,其中 X 和 Y 可用于匹配 1.8、1.9、2.0 或 2.1 系列中的版本。

:mri, :mri_XY

匹配非 windows C Ruby (Matz Ruby) 或仅匹配 1.8、1.9、2.0 或 2.1 系列。

:mingw, :mingw_XY

匹配 MinGW 上的 32 位 C Ruby 或仅匹配 1.8、1.9、2.0 或 2.1 系列。

:x64_mingw, :x64_mingw_XY

匹配 MinGW 上的 64 位 C Ruby 或仅匹配 1.8、1.9、2.0 或 2.1 系列。

:mswin, :mswin_XY

匹配 Microsoft Windows 上的 32 位 C Ruby 或仅匹配 1.8、1.9、2.0 或 2.1 系列。

:mswin64, :mswin64_XY

匹配 Microsoft Windows 上的 64 位 C Ruby 或仅匹配 1.8、1.9、2.0 或 2.1 系列。

:jruby, :jruby_XY

匹配 JRuby 或 1.8 或 1.9 模式下的 JRuby。

:maglev

匹配 Maglev

:rbx

匹配非 windows Rubinius

注意:平台匹配的环境不一致。您可能需要阅读源代码以了解确切的详细信息。

# File rubygems/request_set/gem_dependency_api.rb, line 757
def platform(*platforms)
  @current_platforms = platforms

  yield
ensure
  @current_platforms = nil
end
也称为:platforms
platforms(*platforms)

用于将 gem 限制为特定平台集的块形式。请参阅 platform

别名为:platform
ruby(version, options = {}) 点击切换源代码

将此 gem 依赖文件限制为给定的 ruby version

您还可以提供 engine:engine_version: 选项,将此 gem 依赖文件限制为特定的 ruby 引擎及其引擎版本。此匹配是通过使用 RUBY_ENGINE 和 RUBY_ENGINE_VERSION 常量执行的。

# File rubygems/request_set/gem_dependency_api.rb, line 783
def ruby(version, options = {})
  engine         = options[:engine]
  engine_version = options[:engine_version]

  raise ArgumentError,
        "You must specify engine_version along with the Ruby engine" if
          engine && !engine_version

  return true if @installing

  unless version == RUBY_VERSION
    message = "Your Ruby version is #{RUBY_VERSION}, " \
              "but your #{gem_deps_file} requires #{version}"

    raise Gem::RubyVersionMismatch, message
  end

  if engine && engine != Gem.ruby_engine
    message = "Your Ruby engine is #{Gem.ruby_engine}, " \
              "but your #{gem_deps_file} requires #{engine}"

    raise Gem::RubyVersionMismatch, message
  end

  if engine_version
    if engine_version != RUBY_ENGINE_VERSION
      message =
        "Your Ruby engine version is #{Gem.ruby_engine} #{RUBY_ENGINE_VERSION}, " \
        "but your #{gem_deps_file} requires #{engine} #{engine_version}"

      raise Gem::RubyVersionMismatch, message
    end
  end

  true
end
source(url) 点击切换源代码

url 设置为此依赖项 API 的 gem 源。如果没有给出源,RubyGems 将使用默认配置的源。如果设置了源,则只使用该源。

此方法的行为与 Bundler 不同

  • 不支持 :gemcutter:rubygems:rubyforge 源,因为它们在 bundler 中已弃用。

  • 不支持 prepend: 选项。如果您希望对源进行排序,请按您喜欢的顺序列出它们。

# File rubygems/request_set/gem_dependency_api.rb, line 834
def source(url)
  Gem.sources.clear if @default_sources

  @default_sources = false

  Gem.sources << url
end