我应该在我的Gemfile中指定确切的版本吗?

时间:2012-02-13 17:41:02

标签: ruby-on-rails ruby ruby-on-rails-3 rubygems bundler

我注意到在rubygems.org上有很多宝石建议您按主要版本而不是精确版本来指定它们。例如......

The haml-rails gem ...

gem "haml-rails", "~> 0.3.4"  # "$ bundle install" will acquire the 
                              # latest version before 1.0.

然而,根据Bundler docs,我觉得最好确定这样的确切版本......

gem "haml-rails", "0.3.4"

所以你的haml-rails gem和它的所有依赖都不会向前发展。如果您在几周之后在另一台计算机上签出项目并运行$ bundle install,那么您将拥有与您指定的所有内容完全相同的版本。

我已经看到点发布破坏了,我认为Bundler的整个想法的一部分是“Bundle.lock”你所有的宝石版本。

但是在rubygems.org上,他们使用“〜>”很多,所以也许我错过了什么?

任何澄清对我理解Bundler和gem管理都非常有帮助。

3 个答案:

答案 0 :(得分:55)

这是Gemfile.lock文件的目的 - 使用Gemfile.lock运行bundle install仅使用其中列出的依赖项进行安装;它不会重新解析Gemfile。要更新依赖项/更新gem版本,您必须显式执行bundle update,这将更新您的Gemfile.lock文件。

如果没有Gemfile.lock,将代码部署到生产将是一个主要问题,因为正如您所提到的,依赖关系和gem版本可能会发生变化。

简而言之,正如rubygems.org所建议的那样,使用悲观版本约束运算符(~>)通常是安全的。确保在执行bundle update之后重新运行测试以确保没有任何中断。

Yehuda Katz有一个nice article,它有更多关于Gemfile.lock的信息。

答案 1 :(得分:6)

我肯定会说使用确切的版本号。您可能总是将其锁定为主要版本,或者从不指定任何版本,并且没关系,但如果您真的想要这种精细的控制级别并且在其他计算机上运行时对程序有100%的信心,使用确切的版本号。

我一直处在没有指定确切版本号的情况下,当我或其他人做了bundle install时,该项目因为进入了更新的版本而崩溃了。在部署到生产环境时,这可能会特别糟糕。

Bundler 确实锁定你的gem规范,但是如果你告诉它只是使用一个主要的版本,那么它将其锁定。所以只知道“哦版本被锁定在> 0.1“或其他什么,但不是”哦版本特别锁定在0.1.2.3“。

答案 2 :(得分:4)

TL; DR

是的,使用pessimistic locking~>)并指定一个semantic version来修补(Major.minor.patch)您所有的宝石!

讨论

我对这个问题缺乏明确性感到惊讶,甚至有一天,“行业专家”也告诉我Gemfile.lock在那里可以维护gem版本。错了!

您希望以一种可以随时运行Gemfile的方式来组织bundle update,而不必冒险破坏所有内容。要达到这个目的:

  1. 为所有具有悲观锁定的宝石指定补丁程序版本。这将允许bundle update为您提供修复程序,但不能破坏更改。

  2. 为git中的宝石指定ref

此设置的唯一缺点是,当出现甜美的次要/主要版本的宝石时,您必须手动提高该版本。

警告场景

考虑如果不锁定宝石会发生什么情况。
您的gemfile中有一个已解锁的gem "rails",并且Gemfile.lock中的版本是4.1.16。您正在编码,并且在某些时候执行了bundle update。现在,您的Rails版本跳至5.2.0(假设其他宝石不能阻止这一情况),一切都会中断。
帮个忙,不要让它成为宝石!

示例Gemfile

# lock that bundler
if (version = Gem::Version.new(Bundler::VERSION)) < Gem::Version.new('1.16.3')
  abort "Bundler version >= 1.16.3 is required. You are running #{version}"
end

source "http://rubygems.org"

# specify explicit ref for git repos
gem "entity_validator",
  git: "https://github.com/plataformatec/devise",
  ref: "acc45c5a44c45b252ccba65fd169a45af73ff369" # "2018-08-02"

# consider hard-lock on gems you do not want to change one bit
gem "rails", "5.1.5"

# pessimistic lock on your common gems
gem "newrelic_rpm", "~> 4.8.0"
gem "puma", "~> 3.12.0"

group :test do
  gem "simplecov", "~> 0.16.1", require: false
end

让步
如果您确信测试会发现由gem版本更改引起的错误,则可以尝试以次要版本而不是补丁程序悲观地锁定gem。
这样一来,gem版本就可以在指定的主要版本之内增加,但绝不会增加到下一个。

gem "puma", "~> 3.12"