Docs header transparent bg

gemfile

Gemfile - 描述 Ruby 程序 gem 依赖关系的格式

A Gemfile describes the gem dependencies required to execute associated
Ruby code.

Gemfile 放置在包含相关代码的目录的根目录中。例如,在 Rails 应用程序中,将 Gemfile 放置在与 Rakefile 相同的目录中。

语法

Gemfile 作为 Ruby 代码进行评估,在上下文中提供了一些用于描述 gem 需求的方法。

全局源

Gemfile 的顶部,为包含 Gemfile 中列出的 gem 的 RubyGems 源添加一行。

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

您只能添加一个全局源。在 Bundler 1.13 中,添加多个全局源已被弃用。source 必须是有效的 RubyGems 仓库。

要使用多个 RubyGems 源,您应该使用 source

根据 源优先级 中描述的启发式方法,检查源中是否存在 gem。

关于 Bundler 1.13 中弃用功能的行为的说明:如果在一个以上的全局源中找到 gem,Bundler 将在安装 gem 后打印一条警告,指示使用了哪个源,并列出 gem 可用的其他源。可以使用 :source 选项source 块为需要使用非标准仓库的 gem 选择特定源,从而抑制此警告。

凭据

某些 gem 源需要用户名和密码。使用 bundle config(1) 为任何需要它的源设置用户名和密码。该命令必须在每个将安装 Gemfile 的计算机上运行一次,但这可以防止凭据以明文形式存储在版本控制中。

bundle config gems.example.com user:password

对于某些源,例如公司 Gemfury 帐户,在 Gemfile 中将凭据包含在源 URL 中可能更容易。

source "https://user:[email protected]"

源 URL 中的凭据将优先于使用 config 设置的凭据。

Ruby

如果您的应用程序需要特定的 Ruby 版本或引擎,请使用 ruby 方法指定您的需求,并使用以下参数。所有参数都是 可选 的,除非另有说明。

版本(必需)

您应用程序所需的 Ruby 版本。如果您的应用程序需要其他 Ruby 引擎,例如 JRuby、TruffleRuby 等,则应为该引擎兼容的 Ruby 版本。

ruby "3.1.2"

如果您希望从版本文件(例如 .ruby-version)中获取 Ruby 版本,可以使用 file 选项。

ruby file: ".ruby-version"

版本文件应符合以下任何格式

  • 3.1.2 (.ruby-version)
  • ruby 3.1.2 (.tool-versions,阅读:https://asdf-vm.com/manage/configuration.html#tool-versions)

引擎

每个应用程序可以指定一个 Ruby 引擎。如果指定了引擎,则必须也指定引擎版本。

什么是引擎?

  • Ruby 引擎是 Ruby 语言的实现。

  • 背景:Ruby 编程语言的参考或原始实现称为 Matz's Ruby Interpreter,简称 MRI。它以 Ruby 创建者松本行弘(也称为 Matz)的名字命名。MRI 也称为 CRuby,因为它是用 C 语言编写的。MRI 是使用最广泛的 Ruby 引擎。

  • 其他实现 Ruby 也存在。一些更知名的实现包括 JRubyTruffleRuby。Rubinius 是用 Ruby 编写的 Ruby 的替代实现。JRuby 是 Ruby 在 JVM(Java 虚拟机)上的实现。TruffleRuby 是在 GraalVM 上的 Ruby 实现,GraalVM 是一个基于 JVM 的语言工具包。

引擎版本

每个应用程序可以指定一个 Ruby 引擎版本。如果指定了引擎版本,则必须也指定引擎。如果引擎是“ruby”,则指定的引擎版本必须与 Ruby 版本匹配。

ruby "2.6.8", engine: "jruby", engine_version: "9.3.8.0"

补丁级别

每个应用程序可以指定一个 Ruby 补丁级别。自从 Ruby 2.1.0 发布以来,指定补丁级别就没有意义了,因为补丁级别现在由主版本、次版本和微版本号的组合唯一确定。

此选项是在 Bundler 1.4.0 中为 Ruby 2.0 或更早版本实现的。

ruby "3.1.2", patchlevel: "20"

宝石

使用 gem 方法指定宝石需求,并使用以下参数。所有参数都是可选的,除非另有说明。

名称(必需)

对于每个宝石需求,列出一行宝石

gem "nokogiri"

版本

每个宝石可以有一个或多个版本说明符。

gem "nokogiri", ">= 1.4.2"
gem "RedCloth", ">= 4.1.0", "< 4.2.0"

作为需求

每个gem MAY 指定在通过 Bundler.require 自动加载时应使用的文件。您可以传递包含多个文件的数组,或者如果要 required 的文件与gem同名,则传递 true,或者传递 false 以防止任何文件被自动加载。

gem "redis", require: ["redis/connection/hiredis", "redis"]
gem "webmock", require: false
gem "byebug", require: true

该参数默认为 gem 的名称。例如,这些是相同的

gem "nokogiri"
gem "nokogiri", require: "nokogiri"
gem "nokogiri", require: true

每个gem MAY 指定其属于一个或多个组。任何未指定其属于任何组的gem都将被放置在 default 组中。

gem "rspec", group: :test
gem "wirble", groups: [:development, :test]

Bundler 运行时允许其两种主要方法 Bundler.setupBundler.require 将其影响限制在特定组。

# setup adds gems to Ruby's load path
Bundler.setup                    # defaults to all groups
require "bundler/setup"          # same as Bundler.setup
Bundler.setup(:default)          # only set up the _default_ group
Bundler.setup(:test)             # only set up the _test_ group (but `not` _default_)
Bundler.setup(:default, :test)   # set up the _default_ and _test_ groups, but no others

# require requires all of the gems in the specified groups
Bundler.require                  # defaults to the _default_ group
Bundler.require(:default)        # identical
Bundler.require(:default, :test) # requires the _default_ and _test_ groups
Bundler.require(:test)           # requires the _test_ group

Bundler CLI 允许您指定一个组列表,这些组的 gem bundle install 不应该使用 without 配置进行安装。

要指定多个要忽略的组,请指定以空格分隔的组列表。

bundle config set --local without test
bundle config set --local without development test

此外,调用不带参数的 Bundler.setup 或调用 require "bundler/setup" 将设置所有组,除了您通过 --without 排除的组(因为它们不可用)。

请注意,在 bundle install 上,bundler 会下载并评估所有 gem,以创建所有必需 gem 及其依赖项的单个规范列表。这意味着您不能在不同组中列出同一 gem 的不同版本。有关更多详细信息,请参阅 理解 Bundler

平台

如果 gem 应该只在特定平台或一组平台中使用,您可以指定它们。平台本质上与组相同,只是您不需要使用 --without 安装时标志来排除其他平台的 gem 组。

有许多 Gemfile 平台

ruby
C Ruby (MRI)、Rubinius 或 TruffleRuby,但不包括 Windows
mri
仅 C Ruby (MRI),但不包括 Windows
windows
Windows C Ruby (MRI),包括 RubyInstaller 32 位和 64 位版本
mswin
Windows C Ruby (MRI),包括 RubyInstaller 32 位版本
mswin64
Windows C Ruby (MRI),包括 RubyInstaller 64 位版本
rbx
Rubinius
jruby
JRuby
truffleruby
TruffleRuby

rubymrimswinmswin64windows 平台上,您还可以通过附加主要版本号和次要版本号(不带分隔符)来指定版本。例如,要指定宝石仅在 ruby 平台版本 3.1 上使用,请使用

ruby_31

与组(如上所述)一样,您可以指定一个或多个平台

gem "weakling",   platforms: :jruby
gem "ruby-debug", platforms: :mri_31
gem "nokogiri",   platforms: [:windows_31, :jruby]

所有涉及组的操作(bundle installBundler.setupBundler.require)的行为与明确排除任何与当前平台不匹配的组的行为完全相同。

以下平台值已弃用,应替换为 windows

  • mswinmswin64mingw32x64_mingw

Force_ruby_platform

如果您始终希望选择宝石的纯 Ruby 变体而不是平台特定变体,可以使用 force_ruby_platform 选项

gem "ffi", force_ruby_platform: true

这在以下情况下可能很方便(假设纯 Ruby 变体可以正常工作)

  • 您在使用平台特定变体时遇到问题。
  • 平台特定变体尚不支持较新的 Ruby(因此具有 required_ruby_version 上限),但您仍然希望您的 Gemfile{.lock} 文件在该 Ruby 下解析。

来源

您可以使用 :source 选项为宝石选择备用 RubyGems 存储库。

gem "some_internal_gem", source: "https://gems.example.com"

这将强制宝石从该来源加载,并忽略文件中顶层声明的全局来源。如果宝石在该来源中不存在,则不会安装它。

Bundler 将首先在为父级选择的来源中搜索该宝石的子依赖项,但如果在该来源中找不到,它将回退到全局来源。

关于 Bundler 1.13 中弃用功能的行为的说明:以这种方式选择特定来源存储库还会抑制上面 全局来源 中描述的不明确宝石警告。

为单个宝石使用 :source 选项也将使该来源作为任何其他未指定显式来源的宝石的可能全局来源。因此,在添加具有显式来源的宝石时,建议您还确保 Gemfile 中的所有其他宝石都使用显式来源。

Git

如有必要,您可以使用 :git 参数指定宝石位于特定 Git 存储库中。可以通过多种协议访问存储库

HTTP(S)
gem "rails", git: "https://github.com/rails/rails.git"
SSH
gem "rails", git: "[email protected]:rails/rails.git"
git
gem "rails", git: "git://github.com/rails/rails.git"

如果使用 SSH,则运行 bundle install 的用户 必须 在其 $HOME/.ssh 中拥有相应的密钥。

注意:尽可能避免使用 http://git:// URL。这些协议未经身份验证,因此中间人攻击者可以传递恶意代码并危害您的系统。强烈建议使用 HTTPS 和 SSH。

groupplatformsrequire 选项可用,其行为与普通 gem 完全相同。

git 仓库 应该 至少包含一个文件,该文件位于包含 gem 的目录的根目录下,扩展名为 .gemspec。此文件 必须 包含有效的 gem 规范,如 gem build 命令所预期的那样。

如果 git 仓库没有 .gemspec,bundler 将尝试创建一个,但它不包含任何依赖项、可执行文件或 C 扩展编译指令。因此,它可能无法正确集成到您的应用程序中。

如果 git 仓库包含您附加到它的 gem 的 .gemspec,则提供的版本说明符意味着 git 仓库仅在 .gemspec 指定与版本说明符匹配的版本时才有效。否则,bundler 将打印警告。

gem "rails", "2.3.8", git: "https://github.com/rails/rails.git"
# bundle install will fail, because the .gemspec in the rails
# repository's master branch specifies version 3.0.0

如果 git 仓库 没有 包含您附加到它的 gem 的 .gemspec,则 必须 提供版本说明符。Bundler 将在它创建的简单 .gemspec 中使用此版本。

Git 仓库支持许多其他选项。

branchtagref
必须 仅指定最多一个这些选项。默认值为 branch: "master"。例如

gem "rails", git: "https://github.com/rails/rails.git", branch: "5-0-stable"

gem "rails", git: "https://github.com/rails/rails.git", tag: "v5.0.0"

gem "rails", git: "https://github.com/rails/rails.git", ref: "4aded"

子模块
作为参考,git 子模块 允许您在仓库的子文件夹中拥有另一个 git 仓库。指定 submodules: true 以使 bundler 展开 git 仓库中包含的任何子模块

如果 git 仓库包含多个 .gemspecs,则每个 .gemspec 代表一个 gem,该 gem 位于与 .gemspec 相同的文件系统位置。

|~rails                   [git root]
| |-rails.gemspec         [rails gem located here]
|~actionpack
| |-actionpack.gemspec    [actionpack gem located here]
|~activesupport
| |-activesupport.gemspec [activesupport gem located here]
|...

要安装位于 Git 仓库中的 gem,Bundler 会切换到包含 gemspec 的目录,运行 gem build name.gemspec,然后安装生成的 gem。gem build 命令是 Rubygems 的标准命令,它会在 gemspec 所在的目录上下文中评估 .gemspec 文件。

Git 源

可以使用 git_source 方法定义自定义 Git 源。提供源的名称作为参数,以及一个接收单个参数并将其插入字符串以返回完整仓库地址的代码块。

git_source(:stash){ |repo_name| "https://stash.corp.acme.pl/#{repo_name}.git" }
gem 'rails', stash: 'forks/rails'

此外,如果您想选择特定的分支

gem "rails", stash: "forks/rails", branch: "branch_name"

GitHub

注意:在 Bundler 2.0 之前,应避免使用此简写,因为它目前扩展为不安全的 git:// URL。这会让中间人攻击者有机会入侵您的系统。

如果要使用的 Git 仓库托管在 GitHub 上并且是公开的,可以使用 :github 简写来指定 GitHub 用户名和仓库名称(不含尾部的 ".git"),用斜杠分隔。如果用户名和仓库名称相同,可以省略其中一个。

gem "rails", github: "rails/rails"
gem "rails", github: "rails"

等效于

gem "rails", git: "https://github.com/rails/rails.git"

由于 github 方法是 git_source 的特例,它接受一个名为 :branch 的命名参数。

您也可以直接传递拉取请求 URL

gem "rails", github: "https://github.com/rails/rails/pull/43753"

等效于

gem "rails", github: "rails/rails", branch: "refs/pull/43753/head"

Gist

如果要使用的 Git 仓库托管为 GitHub Gist 并且是公开的,可以使用 :gist 简写来指定 Gist 标识符(不含尾部的 ".git")。

gem "the_hatch", gist: "4815162342"

等效于

gem "the_hatch", git: "https://gist.github.com/4815162342.git"

由于 gist 方法是 git_source 的特例,它接受一个名为 :branch 的命名参数。

Bitbucket

如果要使用的 Git 仓库托管在 Bitbucket 上并且是公开的,可以使用 :bitbucket 简写来指定 Bitbucket 用户名和仓库名称(不含尾部的 ".git"),用斜杠分隔。如果用户名和仓库名称相同,可以省略其中一个。

gem "rails", bitbucket: "rails/rails"
gem "rails", bitbucket: "rails"

等效于

gem "rails", git: "https://[email protected]/rails/rails.git"

由于 bitbucket 方法是 git_source 的特例,它接受一个名为 :branch 的命名参数。

路径

您可以指定 gem 位于文件系统中的特定位置。相对路径相对于包含 Gemfile 的目录解析。

类似于 :git 选项的语义,:path 选项要求目标目录包含 gem 的 .gemspec 文件,或者您指定 Bundler 应该使用的显式版本。

:git 不同,Bundler 不会为指定为路径的 gem 编译 C 扩展。

gem "rails", path: "vendor/rails"

如果您想直接从文件系统中使用多个本地 gem,可以将全局 path 选项设置为包含 gem 文件的路径。这将自动从子目录加载 gemspec 文件。

path 'components' do
  gem 'admin_ui'
  gem 'public_ui'
end

源、Git、路径、组和平台的代码块形式

:source:git:path:group:platforms 选项可以使用代码块形式应用于一组 gem。

source "https://gems.example.com" do
  gem "some_internal_gem"
  gem "another_internal_gem"
end

git "https://github.com/rails/rails.git" do
  gem "activesupport"
  gem "actionpack"
end

platforms :ruby do
  gem "ruby-debug"
  gem "sqlite3"
end

group :development, optional: true do
  gem "wirble"
  gem "faker"
end

对于组块形式,可以添加 `:optional` 选项来阻止组的安装,除非在 `bundle install` 命令中使用 `--with` 选项指定了该组。

对于 `git` 块形式,可以将 `:ref`、`:branch`、`:tag` 和 `:submodules` 选项传递给 `git` 方法,块中的所有 gem 将继承这些选项。

在 Gemfile 中存在 `source` 块也会使该源作为所有未指定显式源的 gem 的潜在全局源。因此,在定义源块时,建议您还确保 Gemfile 中的所有其他 gem 都使用显式源,无论是通过源块还是在单个 gem 上使用 `:source` 指令。

安装条件

`install_if` 方法允许根据 proc 或 lambda 安装 gem。这对于可选 gem 特别有用,因为可选 gem 只有在安装了特定软件或满足其他条件时才能使用。

install_if -> { RUBY_PLATFORM =~ /darwin/ } do
  gem "pasteboard"
end

Gemspec

.gemspec 文件中,您可以提供有关 gem 的元数据给 Rubygems。一些必需的 Gemspec 属性包括 gem 的名称、描述和主页。您也可以在这里指定 gem 运行所需的依赖项。

如果您希望使用 Bundler 在开发 gem 时帮助安装依赖项,请使用 `gemspec` 方法来获取 `。gemspec` 文件中列出的依赖项。

`gemspec` 方法将任何运行时依赖项作为 gem 需求添加到默认组中。它还将开发依赖项作为 gem 需求添加到 `development` 组中。最后,它在您的项目上添加一个 gem 需求 ( `path: '.'` )。结合 `Bundler.setup`,这允许您在测试代码中像安装 gem 一样要求项目文件;您无需手动操作加载路径或通过相对路径要求项目文件。

`gemspec` 方法支持可选的 `:path`、`:glob`、`:name` 和 `:development_group` 选项,这些选项控制 Bundler 在哪里查找 `。gemspec`、它用来查找 gemspec 的 glob(默认为:`{,*,*/*}.gemspec`)、它使用的命名 `。gemspec`(如果存在多个)以及将哪些组的开发依赖项包含在内。

当 `gemspec` 依赖项在解析期间遇到版本冲突时,始终会选择正在开发的本地版本,即使存在更符合 `gemspec` gem 的其他需求的远程版本。

源优先级

当尝试定位满足 gem 需求的 gem 时,bundler 使用以下优先级顺序

  1. 显式附加到 gem 的源(使用 :source:path:git
  2. 对于隐式 gem(显式 gem 的依赖项),父级上声明的任何源、git 或路径存储库。这会导致 bundler 优先考虑来自 Rails git 存储库的 ActiveSupport gem,而不是来自 rubygems.org 的 gem
  3. 如果上述两个条件均不满足,则将使用全局源。如果指定了多个全局源,则将从后到前优先考虑它们,但这已在 Bundler 1.13 中弃用,因此 Bundler 会打印警告并在将来出现错误时中止。
在 GitHub 上编辑此文档,如果您发现错误或注意到缺少内容。