了解Gemfile。锁文件

运行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!

什么‘路径’,‘宝石’,‘平台’和‘依赖关系描述?所有这些都是必需的吗?

什么应该包含'远程'和'规格'子指令?

依赖关系”组中宝石名称后面的感叹号是什么意思?

126476 次浏览

你可以在打包机的网站中找到更多关于它的信息(为了方便起见,在下面添加了重点):

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

这一点很重要:Gemfile.lock使你的应用程序成为一个单独的包,包含你自己的代码和上次你确定一切正常运行时运行的第三方代码。在Gemfile中指定您所依赖的第三方代码的确切版本并不能提供相同的保证,因为gems通常会为它们的依赖声明一系列版本。

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

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

在我看来,PATH列出了直接来自gemspec的第一代依赖项,而GEM列出了第二代依赖项(即依赖项依赖于什么)和来自Gemfile的依赖项。PATH::remote是.,因为它依赖于当前目录中的本地gemspec来找到属于PATH::spec的内容,而GEM::remote是rubygems.org,因为它必须去那里才能找到属于GEM::spec的内容。

在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

rails plugin new my_plugin生成的Gemfile表示类似的内容:

# 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中只包含“july”。在开发环境中锁定(因此锁定在应用程序中)。因此,当你运行bundle install时,你不仅会在PATH下看到“july”,还会在DEPENDENCIES下看到“july”,但只会在development中看到。在生产中,它根本不会存在。然而,当你使用(2)时,你只会在PATH中看到“july”,而不是在DEPENDENCIES中,但是当你从生产环境中bundle install时(即在其他一些包含你的依赖项的gem中),而不仅仅是开发环境中,它会显示。

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

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

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

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

Gemfile和Gemfile。锁是邦德勒宝石给予的初级产品(邦德勒本身就是宝石)。

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

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

当你第一次调用包安装时,它会创建这个Gemfile。Lock并在所有后续调用中使用此文件来捆绑安装,这确保您已经安装了所有依赖项,并将跳过依赖项安装。

在不同的机器上共享代码时也会发生同样的情况

共享您的Gemfile。当你在其他机器上运行bundle install时,它会引用你的Gemfile。锁定并跳过依赖项解析步骤,相反,它将安装您在原始机器上使用的所有相同的依赖gem,即在多台机器上保持一致性 . gem

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

    在不同的机器上运行不同的版本可能会导致崩溃 李代码< / p > < / > 假设,你的应用使用1.5.3版本,它在14个月前就工作了 没有任何问题,您尝试在不同的机器上安装
    没有Gemfile。锁定后,您将获得1.5.8版本。也许它坏了 一些gem(s)的最新版本和你的应用程序将
    失败。保持一致性是至关重要的(首选
    李实践)。< / p > < / >
也可以在Gemfile中更新gem(s)。使用锁定 包更新 . < / p >

这是基于保守的更新的概念

似乎没有明确的文档讨论Gemfile.lock格式。也许是因为Gemfile.lock只被bundle内部使用。

然而,由于Gemfile.lockGemfile的快照,这意味着它的所有信息都应该来自Gemfile(如果没有在Gemfile中指定,则来自默认值)。

对于GEM,它列出了你在Gemfile中直接或间接引入的所有依赖项。GEM下的remote告诉在哪里获取宝石,这是由Gemfile中的指定的。

如果一个宝石没有从remote中获取,PATH将告诉该位置以找到它。当你声明一个依赖时,PATH的信息来自Gemfile中的路径

PLATFORM来自在这里

对于DEPENDENCIES,它是由bundle解析的依赖项的快照。

在过去的几个月里,我一直在摆弄Gemfiles和Gemfile。在构建自动依赖更新工具__abc0时,会锁很多锁。下面的内容远不是决定性的,但它是理解Gemfile的一个很好的起点。锁格式。你可能还想查看Bundler的lockfile解析器的源代码。

你会在Bundler 1.x生成的锁文件中发现以下标题:

宝石(可选但非常常见)

这些依赖关系来自Rubygems服务器。这可能是Rubygems的主索引,在Rubygems.org上,也可能是一个自定义索引,比如从Gemfury和其他网站获得的索引。在本节中,你将看到:

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

GIT(可选)

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

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

路径(可选)

这些依赖项来自于Gemfile中提供的给定path。对于每个路径依赖项,你会看到不同的这些部分,在每个部分中你会看到:

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

平台

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

依赖关系

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

使用Rubygems主索引以外的源指定的依赖项(例如,git依赖项,基于路径的依赖项,依赖项)有一个!,这意味着它们被“固定”到source2上(尽管有时必须在Gemfile中查找来确定)。

RUBY版本(可选)

Gemfile中指定的Ruby版本,当此Gemfile。Lock被创建。如果Ruby版本是在.ruby_version文件中指定的,则此部分将不会出现(因为Bundler将考虑Gemfile / Gemfile。锁定不可知的安装程序的Ruby版本)。

捆绑与 (Bundler >= v1.10.x)

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

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

理论上,Gemfile可以指定Bundler插件,以及gems3.,然后在这里列出。实际上,截至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/