在Gemfile和.ruby-version Dotfile中列出Ruby版本是不好的做法吗?

时间:2015-10-04 14:38:37

标签: ruby-on-rails ruby gemfile convention dotfiles

我最新的Rails项目或多或少,并试图在这个过程中分解很多东西并学习。我在我的gemfile中指定了最新版本的Ruby:

ruby '2.2.3'

我在项目中也有一个.ruby-version点文件,其中包含以下内容:

2.2.3

除了明显的重复之外,这有什么问题?这两个公约的目的是什么?如果我只有一个列出我的Ruby版本的约定,为什么我应该有一个(Gemfile)而另一个(dotfile)?

在项目中同时使用两种约定是否完美无缺?

我将成为这个实验项目的唯一维护者,并且不会觉得必须保持这个微妙的重复是一个问题。我不打算为这个项目升级Ruby,如果我这样做,我就不会记得在两个地方都这样做了。除了这个细节,我当然避免在我的应用程序中出现任何重复。代码库。

3 个答案:

答案 0 :(得分:22)

它们各自由不同团队在不同时间开发,并由不同的软件使用。

在Gemfile中列出ruby版本是feature in bundler

由于Gemfile主要仅由bundler使用,因此它主要仅在您运行with bundler时使用bundle exec,或者为您自动触发bundler的软件(如Rails)。如果您没有使用指定的ruby版本,它的效果就是错误输出并拒绝运行。这是一个要求 - 在这个红宝石下运行,或者我会抛出错误警告你在错误的红宝石下运行。

但是,heroku also pays attention为Gemfile中指定的版本,并将在该版本下运行。 Heroku也决定在捆绑器中使用该功能。但是,您工作站上的大多数其他软件甚至travis都不使用该约定。 (Travis让您编辑.travis.yml ENV以指定要使用的ruby版本)。

Bundler中的功能于2012年8月在Bundler 1.2中引入。

.ruby-version文件首先由第一个ruby版本管理器rvm引入。如果您使用的是rvm,并且切换到带有.ruby-version文件的项目目录,则rvm会自动将您的shell切换为使用指定的ruby版本。

我不确定rvm什么时候引入了这个功能,但我想在Gemfile之前" ruby​​"特征。

由于rvm引入了它,其他ruby版本交换软件如rbenv和chruby也采用了它来做同样的事情 - 自动切换到cd指定的ruby版本到目录中。虽然我认为rbenv和chruby都可能是一个可选功能。

因此,它们是在不同时间引入并由不同软件包支持的不同功能,做了一些不同的事情。

我同意维护它们并让它们保持同步会很烦人。

它们实际上都是可选的,您不需要使用其中任何一个。除非你可能需要使用geoku文件ruby规范来告诉它你希望它运行哪个ruby。

我也不会亲自使用。但是如果你需要在不同的项目中使用不同的ruby版本,并且发现让ruby版本管理器(rvm,rbenv或chruby)自动切换到正确的项目特定的ruby版本,.ruby-version可能会很方便有用。

除了heroku之外,在Gemfile中列出ruby主要是为了避免犯错,例如在部署时。或者,内部自动部署或CI环境可能会像heroku一样使用它们,或者其他云部署堆栈可能会或已经采用它。我想很多人发现它不太有用 - 这个也是,我不会使用,直到你碰到或看到它正在解决的问题。一些人在Gemfile中列出ruby版本的一个不便之处在于,随着新的红宝石总是出现,你必须一直更新所有的Gemfiles。

一般来说,过去几年的ruby版本都是向后兼容的,这限制了确保你使用精确版本的ruby的必要性,最新的代码将在最新的ruby上运行,甚至如果它最初是为较旧的。

我不相信这两个功能都允许您指定一系列ruby版本,例如2.2.*或您拥有的内容。

使用其中一种/两种功能,只有在您需要它们或使用它们时才使用它们,您不必使用它们,如果您需要,可以使用它们(如果烦人的话)这两者都做了。

由于Gemfile是实时ruby代码,理论上你可以让你的Gemfile读取你的.ruby-version文件,并自动将该值用作Gemfile ruby值。如果你想同时使用两者,并且不要重复自己"用它。我不知道这是否是常见的事情,我只是想到了。但它应该工作正常。

答案 1 :(得分:11)

我认为最好避免两次列出相同的信息,除非有充分的理由 - 即保持干燥。

您可以将ruby版本存储在" .ruby-version"中,然后在Gemfile中执行以下操作:

ruby File.open('.ruby-version', 'rb') { |f| f.read.chomp }

答案 2 :(得分:1)

在您的Gemfile中使用它:

ruby File.read('.ruby-version').strip

优点:

  • 您不会忘记在其中一个文件中更新版本
  • 它确保您始终运行正确的版本。