198

运行bundle install命令后,在工作目录中创建了“Gemfile.lock ”。该文件中的指令是什么意思?

例如,让我们采用以下文件:

PATH
  remote: .
  specs:
    gem_one (0.0.1)

GEM
  remote: http://example.org/
  specs:
    gem_two (0.0.2)
    gem_three (0.0.3)
      gem_four (0.0.4)

PLATFORMS
  platform

DEPENDENCIES
  gem_two
  gem_one!

PATH ”、“ GEM ”、“ PLATFORMS ”和“ DEPENDENCIES ”描述了什么?都是必需的吗?

什么应该包含 ' remote ' 和 ' specs ' 子指令?

' DEPENDENCIES '组中gem名称后的感叹号是什么意思?

4

7 回答 7

69

您可以在bundler 网站上找到更多相关信息(为方便起见,在下面添加了重点):

在开发应用程序一段时间后,将应用程序连同 Gemfile 和Gemfile.lock快照一起签入。现在,您的存储库记录了您上次使用的所有 gem 的确切版本,您确定该应用程序工作正常......

这很重要:Gemfile.lock使您的应用程序成为您自己的代码和它最后一次运行的第三方代码的单个包,您可以确定一切正常。在 Gemfile 中指定您依赖的第三方代码的确切版本不会提供相同的保证,因为 gems 通常会为其依赖项声明一系列版本。

于 2011-09-22T16:27:06.580 回答
57

在过去的几个月里,我在构建一个自动依赖更新工具1时,一直在搞乱 Gemfiles 和 Gemfile.locks 。下面的内容远非明确,但它是理解 Gemfile.lock 格式的一个很好的起点。您可能还想查看 Bundler 的lockfile parser的源代码。

您会在 Bundler 1.x 生成的锁定文件中找到以下标题:

GEM(可选但很常见)

这些是来自 Rubygems 服务器的依赖项。这可能是 Rubygems.org 上的主要 Rubygems 索引,也可能是自定义索引,例如 Gemfury 和其他提供的索引。在本节中,您将看到:

  • remote:一行或多行指定 Rubygems 索引的位置
  • specs:依赖项列表,及其版本号,以及对任何子依赖项的约束

GIT(可选)

这些是来自给定 git 远程的依赖项。对于每个 git 远程,您会看到其中不同的部分,并且在每个部分中,您将看到:

  • remote:git 遥控器。例如,git@github.com:rails/rails
  • revision:Gemfile.lock 被锁定到的提交引用
  • tag:(可选)在 Gemfile 中指定的标签
  • specs:在此远程找到的 git 依赖项,及其版本号,以及对任何子依赖项的约束

路径(可选)

这些是来自pathGemfile 中提供的给定的依赖项。对于每个路径依赖项,您将看到其中不同的部分,并且在每个部分中,您将看到:

  • remote:路径。例如,plugins/vendored-dependency
  • specs:在此远程找到的 git 依赖项,及其版本号,以及对任何子依赖项的约束

平台

生成 Gemfile.lock 的 Ruby 平台。如果 Gemfile 中的任何依赖项指定了一个平台,那么它们只会在该平台上生成锁定文件(例如,通过安装)时包含在 Gemfile.lock 中。

依赖项

中指定的依赖项列表,Gemfile以及那里指定的版本约束。

使用主 Rubygems 索引以外的源指定的依赖项(例如,git 依赖项、基于路径的依赖项)具有 a !,这意味着它们被“固定”到该源2(尽管有时必须查看 Gemfile 才能确定)。

红宝石版本(可选)

Gemfile 中指定的 Ruby 版本,创建此 Gemfile.lock 时。如果在文件中指定了 Ruby 版本,则.ruby_version此部分将不存在(因为 Bundler 将认为 Gemfile / Gemfile.lock 与安装程序的 Ruby 版本无关)。

捆绑(捆绑器> = v1.10.x

用于创建 Gemfile.lock 的 Bundler 版本。用于提醒安装程序更新他们的 Bundler 版本,如果它比创建文件的版本旧。

插件源(可选且非常罕见)

理论上,一个 Gemfile 可以指定 Bundler 插件,以及 gems 3,然后将在此处列出。实际上,截至 2017 年 7 月,我不知道有任何可用的插件。Bundler 的这一部分仍在积极开发中!


  1. https://dependabot.com
  2. https://github.com/bundler/bundler/issues/4631
  3. http://andre.arko.net/2012/07/23/towards-a-bundler-plugin-system/
于 2017-07-07T23:05:43.437 回答
40

关于感叹号,我刚刚发现它在通过 获取的宝石上:git,例如

gem "foo", :git => "git@github.com:company/foo.git"
于 2012-02-15T01:11:55.403 回答
12

Bundler 是一个 Gem 管理器,它通过跟踪和安装所需的确切 gem 和版本来为 Ruby 项目提供一致的环境。

Gemfile 和 Gemfile.lock 是 Bundler gem 提供的主要产品(Bundler 本身就是一个 gem)。

Gemfile 包含您对 gem(s) 的项目依赖项,您手动提及指定的版本,但这些 gem(s) 又依赖于捆绑器自动解析的其他 gem(s)。

Gemfile.lock 包含 Gemfile 中所有 gem(s) 的完整快照以及相关的依赖项。

当你第一次调用bundle install时,它会创建这个 Gemfile.lock 并在所有后续调用 bundle install 时使用这个文件,这样可以确保你安装了所有依赖项,并且会跳过依赖项安装。

当您与不同的机器共享代码时也会发生同样的情况

您与 Gemfile 共享您的 Gemfile.lock,当您在其他机器上运行 bundle install 时,它将引用您的 Gemfile.lock 并跳过依赖项解析步骤,而是安装您在原始机器,在多台机器之间保持一致性

为什么我们需要在多台机器上保持一致性?

  • 在不同的机器上运行不同的版本可能会导致代码损坏

  • 假设您的应用程序使用的是 1.5.3 版本,并且它在 14 个月前可以正常运行
    ,并且您尝试在
    没有 Gemfile.lock 的不同机器上安装,现在您获得了 1.5.8 版本。也许它被某些 gem 的最新版本破坏了,您的应用程序将
    失败。保持一致性至关重要(首选
    做法)。

也可以使用 bundle update 更新Gemfile.lock 中的 gem 。

这是基于保守更新的概念

于 2016-02-21T12:40:51.437 回答
8

在我看来,PATH 直接从您的 gemspec 中列出了第一代依赖项,而 GEM 列出了第二代依赖项(即您的依赖项所依赖的内容)和 Gemfile 中的那些。PATH::remote 是.因为它依靠当前目录中的本地 gemspec 来找出 PATH::spec 中的内容,而 GEM::remote 是rubygems.org,因为它必须去那里找出 GEM:: 中的内容规格。

在 Rails 插件中,您会看到 PATH 部分,但在 Rails 应用程序中看不到。由于该应用程序没有 gemspec 文件,因此不会在 PATH 中放置任何内容。

至于 DEPENDENCIES,gembundler.com指出:

Runtime dependencies in your gemspec are treated like base dependencies, 
and development dependencies are added by default to the group, :development

生成的 Gemfilerails plugin new my_plugin说类似的话:

# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.

这意味着之间的区别

s.add_development_dependency "july" # (1)

s.add_dependency "july" # (2)

是(1)将仅在开发环境中的 Gemfile.lock(因此在应用程序中)中包含“july”。因此,当您运行时bundle install,您不仅会在 PATH 下而且还会在 DEPENDENCIES 下看到“july”,而且只会在开发中看到。在生产中,它根本不存在。但是,当您使用 (2) 时,您只会在 PATH 中看到“july”,而不是在 DEPENDENCIES 中,但是当您bundle install从生产环境中(即在其他一些包含您作为依赖项的 gem 中)时,它会显示出来,而不是只有发展。

这些只是我的观察,我无法完全解释为什么会这样,但我欢迎进一步的评论。

于 2012-09-21T04:00:42.290 回答
4

It seems no clear document talking on the Gemfile.lock format. Maybe it's because Gemfile.lock is just used by bundle internally.

However, since Gemfile.lock is a snapshot of Gemfile, which means all its information should come from Gemfile (or from default value if not specified in Gemfile).

For GEM, it lists all the dependencies you introduce directly or indirectly in the Gemfile. remote under GEM tells where to get the gems, which is specified by source in Gemfile.

If a gem is not fetch from remote, PATH tells the location to find it. PATH's info comes from path in Gemfile when you declare a dependency.

And PLATFORM is from here.

For DEPENDENCIES, it's the snapshot of dependencies resolved by bundle.

于 2016-09-09T01:35:11.830 回答
0

'DEPENDECIES' 组中宝石名称后的感叹号是什么意思?

当使用“ https://rubygems.org ”以外的源安装 gem 时,会出现感叹号。

于 2016-01-06T10:50:48.333 回答