了解Gemfile.lock文件

Sha*_*oke 174 ruby bundler gemfile.lock

运行该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!
Run Code Online (Sandbox Code Playgroud)

' PATH ',' GEM ',' PLATFORMS '和' DEPENDENCIES '描述的是什么?他们都需要吗?

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

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

Fil*_*eca 72

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

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

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

  • 这没有回答他的任何问题,他在询问Gemfile.lock的格式,但这只是描述了它的作用. (62认同)

小智 36

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

gem "foo", :git => "git@github.com:company/foo.git"
Run Code Online (Sandbox Code Playgroud)

  • 通过`path`选项加载本地gem时也会发生这种情况.我猜它与加载未编译的gem有关? (5认同)

gre*_*eil 26

我花了最近几个月的时间搞乱了Gemfiles和Gemfile.locks,同时构建了一个自动依赖更新工具1.下面的内容远非确定,但它是理解Gemfile.lock格式的一个很好的起点.您可能还想查看Bundler的lockfile解析器的源代码.

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

创业板(可选但很常见)

这些是源自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依赖项及其版本号以及对任何子依赖项的约束

PLATFORMS

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

相关内容

在其中指定的依赖项列表,以及在此处指定Gemfile的版本约束.

使用除主Rubygems索引以外的源指定的依赖关系(例如,git依赖关系,基于路径,依赖关系)具有!这意味着它们被"固定"到该源2(尽管有时必须在Gemfile中查找以确定).

RUBY VERSION(可选)

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

BUNDLED WITH(Bundler> = v1.10.x)

Bundler的版本用于创建Gemfile.lock.用于提醒安装程序更新其Bundler版本(如果它早于创建该文件的版本).

PLUGIN SOURCE(可选且非常罕见)

理论上,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认同)

Kes*_*hav 9

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

Gemfile和Gemfile.lock是Bundler gem给出的主要产品(Bundler本身就是一个gem).

Gemfile包含您对gem(s)的项目依赖性,您手动提及指定的版本,但这些gem(s)inturn取决于Bundler自动解析的其他gem.

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

当您第一次调用bundle install时,它将创建此Gemfile.lock并在所有后续的bundle install调用中使用此文件,这将确保您安装了所有依赖项并将跳过依赖项安装.

使用不同的计算机共享代码时也会发生相同的情况

你与Gemfile一起分享你的Gemfile.lock,当你在其他机器上运行bundle install时,它将引用你的Gemfile.lock并跳过依赖关系解析步骤,而不是安装你在上面使用的所有相同的依赖gem.原始机器,可以保持多台机器的一致性

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

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

  • 假设,您的应用程序使用的是1.5.3版本并且它在14个月前运行
    没有任何问题,并且您尝试在
    没有Gemfile.lock的情况下安装在不同的计算机上,现在您获得1.5.8版本.也许它被某些gem的最新版本打破了,你的应用程序将
    失败.保持一致性至关重要(首选
    实践).

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

这是基于保守更新的概念


Isa*_*esh 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
Run Code Online (Sandbox Code Playgroud)

通过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.
Run Code Online (Sandbox Code Playgroud)

这意味着两者之间的区别

s.add_development_dependency "july" # (1)
Run Code Online (Sandbox Code Playgroud)

s.add_dependency "july" # (2)
Run Code Online (Sandbox Code Playgroud)

是(1)将只在开发环境中的Gemfile.lock(因此在应用程序中)中包含"july".因此,当你跑步时bundle install,你会看到"七月"不仅在PATH下,而且在DEPENDENCIES下,但仅在开发中.在生产中,它根本就不存在.但是,当你使用(2)时,你只会在PATH中看到"july",而不是在DEPENDENCIES中,但是当你bundle install从生产环境(即在某些其他包含你作为依赖关系的gem中)时,它会显示出来,而不是只有发展.

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