了解Gemfile.lock文件


181

运行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 ”描述了什么?全部都需要吗?

什么应包含“ 远程 ”和“ 规格 ”子指令?

DEPENDENCIES ”组中宝石名称后面的感叹号是什么意思?

Answers:


71

您可以在捆绑器网站上找到有关此内容的更多信息(下面为方便起见添加了重点):

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

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


65
这没有回答他的任何问题,他在询问Gemfile.lock的格式,但这只是描述了它的作用。
约书亚脸颊

38

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

gem "foo", :git => "git@github.com:company/foo.git"

哇,很好的工作弄清楚了这一点,我也想知道这一点。谢谢。
JP Silvashy

5
通过该path选项加载本地宝石时,也会发生这种情况。我猜这与加载未编译的宝石有关吗?
zykadelic 2014年

是的,这是一个原因。但这不是宝石带有感叹号标记的唯一原因。我目前看到在源代码块中声明的任何宝石都标有感叹号。
肖恩·莫布里2013年

35

在过去的几个月中,我花了很多时间来处理Gemfiles和Gemfile.locks,同时构建了自动依赖项更新工具1。以下内容远非定论,但它是理解Gemfile.lock格式的一个很好的起点。您可能还想查看Bundler的lockfile解析器的源代码。

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

GEM(可选,但很常见)

这些是从Rubygems服务器获取的依赖项。这可能是Rubygems.org上的主要Rubygems索引,也可能是自定义索引,例如从Gemfury等获得的索引。在此部分中,您将看到:

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

GIT(可选)

这些是从给定的git remote衍生的依赖项。对于每个git遥控器,您将在这些部分中看到一个不同的部分,在每个部分中,您将看到:

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

PATH(可选)

这些是从pathGemfile中提供的给定衍生的依赖项。对于每种路径依赖性,您将在这些部分中看到一个不同的部分,在每个部分中,您将看到:

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

平台

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

依赖

在中指定的依赖项列表以及在其中指定Gemfile的版本约束。

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

RUBY VERSION(可选)

创建此Gemfile.lock时,在Gemfile中指定的Ruby版本。如果在Ruby中指定了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/

2
似乎是最好的答案
令人生畏的

9

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

Gemfile和Gemfile.lock是Bundler gem(Bundler本身是宝石)提供的主要产品。

Gemfile包含您对gem的项目依赖性,您可以使用指定的版本手动提及它,但是这些gem反过来又依赖于捆绑程序自动解决的其他gem。

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

首次调用bundle install时,它将创建此Gemfile.lock并在随后的所有对bundle install的调用中使用此文件,以确保您已安装所有依赖项,并且将跳过依赖项安装。

当您与其他计算机共享代码时,也会发生同样的情况

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

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

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

  • 假设您的应用程序使用的是1.5.3版本,并且它在14个月前正常运行,
    没有任何问题,并且您尝试在
    没有Gemfile.lock的其他计算机上进行安装,现在您获得的版本是1.5.8。可能是某些宝石的最新版本损坏了,您的应用程序将
    失败。保持一致性至关重要(首选
    做法)。

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

这是基于保守更新的概念


8

在我看来,PATH可以直接从gemspec列出第一代依赖关系,而GEM可以列出第二代依赖关系(即依赖关系所依赖的东西)以及Gemfile中的依赖关系。PATH :: remote是.因为它依靠当前目录中的本地gemspec来查找PATH :: spec中的内容,而GEM :: remote是rubygems.org,因为这是它必须去找出GEM ::中的内容的地方。规格

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

至于依赖,gembundler.com指出:

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

生成的Gemfile rails 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中只有发展。

这些只是我的观察,我无法完全解释为什么其中的任何一种都是这种方式,但是我欢迎进一步评论。


3

似乎没有明确的文件讨论Gemfile.lock格式。也许是因为Gemfile.lock捆绑包内部仅使用了它。

但是,由于Gemfile.lock是的快照Gemfile,这意味着其所有信息都应来自Gemfile(或如果未在中指定,则应来自默认值Gemfile)。

为此GEM,它列出了您直接或间接在中引入的所有依赖项GemfileremoteGEM告诉哪里获得的宝石,它是由指定Gemfile

如果未从获取宝石remote,则PATH告知找到它的位置。PATH的信息来自于Gemfile,当你声明的依赖性。

而且PLATFORM是从这里来的

对于DEPENDENCIES,这是捆绑软件解析的依赖项的快照。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.