Ruby 捆绑器 - 同一 gemfile 中的多个 Ruby 版本
Ruby Bundler - Multiple Ruby versions in the same gemfile
我在 macOS 上使用 rbenv
和 bundler
。
我需要为我的应用程序维护 Ruby 的多个版本。特别是 2.2.4 和 2.5.5。不同的用户会有不同的版本。
目前我只使用 2.2.4,所以我执行以下操作。我的 gemfile
看起来像这样
source "https://rubygems.org"
ruby '2.2.4'
gem "net-ssh", "4.1.0"
gem "net-scp", "2.0.0"
.....
安装我 运行 bundle install
然后用我的应用程序部署我 运行
bundle install --deployment --path src/mct-tools/ext/gems
这会在我的应用程序中生成一个文件夹 src/mct-tools/ext/gems/ruby/2.2.0
,然后我会分发该文件夹。
现在我想添加 ruby 2.5.5 和更新的 gem,所以我想知道是否可以接受像这样的 gemfile
source "https://rubygems.org"
ruby '2.2.4'
gem "net-ssh", "4.1.0"
gem "net-scp", "2.0.0"
.....
ruby '2.5.5'
gem "net-ssh", "6.1.0"
gem "net-scp", "3.0.0"
.....
这样当我使用 bundle install --deployment --path src/mct-tools/ext/gems
部署时,这两个版本就会添加到 gems 文件夹中。
这是正确的做法吗?另一种方法是为每个版本指定两个不同的 gemfile,然后在它们之间切换。
Gemfiles 声明依赖关系
Gemfile 在 Ruby 版本上声明 依赖关系 ,有或没有 semantic versioning 约束。它并不意味着控制您的应用程序的多个构建目标。它只是强制您的 app/gem 可用的 Ruby 版本是您定义的任何版本。例如:
# Will fail if run with a different RUBY_VERSION.
ruby '2.2.4'
# Allows RUBY_VERSION >= 2.2.4, but <= 2.3.
ruby '~> 2.2.4'
# Allows either Ruby 2.2.4+ or 2.5.5+, with
# a minimum (but no maximum) patch version.
ruby '~> 2.2.4', '~> 2.5.5'
但是,它不会安装给定的 Ruby,也不会在 运行 bundler install
时引发错误和 non-zero 退出状态。您需要采用不同的方法来测试多个目标。
使用持续集成(CI)工具更改构建目标
如果您使用的是外部 CI,例如 TravisCI,您可以创建一个 build matrix 来针对多个 Ruby 版本进行测试。是完全删除 Ruby 版本限制,还是指定受支持的范围,由您决定。利用您的 CI 工具针对您计划支持的 Ruby 版本进行构建确实是最好的方法,但是,无论您是否将 Ruby 运行时限制在 Gemfile 中。
例如,您可以在 travis.yml 中使用矩阵,如下所示:
language: ruby
rvm:
- 2.2.4
- 2.5.5
切换 Gemfiles
如果你坚持按照你的方式去做,在你的 Gemfile 中允许一个单一的 Ruby 版本,那么你可能会考虑在你的源代码树中有两个不同名称的独立 gemfile,例如作为 Gemfile-2.2.4 和 Gemfile-2.5.5。然后,您可以指定要与 Bundler's --gemfile
flag 一起使用的 Gemfile,或者通过将自定义 Gemfile 符号链接到项目的规范 Gemfile
。
这里有一些要考虑的例子:
# Resolve against a specific Gemfile with
# hard-coded Ruby version.
$ ls Gemfile*
Gemfile-2.2.4 Gemfile-2.5.5
$ bundle install --gemfile="Gemfile-2.2.4"
# Resolve against whatever custom file is
# symlinked to your ./Gemfile.
$ ln -sf Gemfile{-2.5.5,}
$ ls -F Gemfile*
Gemfile@ Gemfile-2.2.4 Gemfile-2.5.5
$ bundle install
这两种方法都有效,但前者更灵活,代价是每次都需要指定您选择的 Gemfile,而后者在您的 development/testing 工作流程不支持 Bundler 的 --gemfile
旗帜。
与 Ruby 经理一起更换红宝石
如果您在开发中有多个 Ruby 版本,最佳做法是使用版本管理器,例如 rvm、rbenv 或 chruby。您可以使用版本管理器根据需要手动来回更改红宝石。
您还可以检查您的版本管理器是否在 .ruby-version
或其他配置文件上支持 auto-switching。每次要针对不同的 Ruby 构建或测试时,您仍然需要更新该文件,但您不必不断更改 Gemfile 内容、re-pointing Gemfile 符号链接或更新每次调用 Bundler 时都有一个标志。
任何给定的方法是否优于其他方法将取决于您的工作流程。没有适合所有情况的技术解决方案,因此您的里程可能会有所不同。
我在 macOS 上使用 rbenv
和 bundler
。
我需要为我的应用程序维护 Ruby 的多个版本。特别是 2.2.4 和 2.5.5。不同的用户会有不同的版本。
目前我只使用 2.2.4,所以我执行以下操作。我的 gemfile
看起来像这样
source "https://rubygems.org"
ruby '2.2.4'
gem "net-ssh", "4.1.0"
gem "net-scp", "2.0.0"
.....
安装我 运行 bundle install
然后用我的应用程序部署我 运行
bundle install --deployment --path src/mct-tools/ext/gems
这会在我的应用程序中生成一个文件夹 src/mct-tools/ext/gems/ruby/2.2.0
,然后我会分发该文件夹。
现在我想添加 ruby 2.5.5 和更新的 gem,所以我想知道是否可以接受像这样的 gemfile
source "https://rubygems.org"
ruby '2.2.4'
gem "net-ssh", "4.1.0"
gem "net-scp", "2.0.0"
.....
ruby '2.5.5'
gem "net-ssh", "6.1.0"
gem "net-scp", "3.0.0"
.....
这样当我使用 bundle install --deployment --path src/mct-tools/ext/gems
部署时,这两个版本就会添加到 gems 文件夹中。
这是正确的做法吗?另一种方法是为每个版本指定两个不同的 gemfile,然后在它们之间切换。
Gemfiles 声明依赖关系
Gemfile 在 Ruby 版本上声明 依赖关系 ,有或没有 semantic versioning 约束。它并不意味着控制您的应用程序的多个构建目标。它只是强制您的 app/gem 可用的 Ruby 版本是您定义的任何版本。例如:
# Will fail if run with a different RUBY_VERSION.
ruby '2.2.4'
# Allows RUBY_VERSION >= 2.2.4, but <= 2.3.
ruby '~> 2.2.4'
# Allows either Ruby 2.2.4+ or 2.5.5+, with
# a minimum (but no maximum) patch version.
ruby '~> 2.2.4', '~> 2.5.5'
但是,它不会安装给定的 Ruby,也不会在 运行 bundler install
时引发错误和 non-zero 退出状态。您需要采用不同的方法来测试多个目标。
使用持续集成(CI)工具更改构建目标
如果您使用的是外部 CI,例如 TravisCI,您可以创建一个 build matrix 来针对多个 Ruby 版本进行测试。是完全删除 Ruby 版本限制,还是指定受支持的范围,由您决定。利用您的 CI 工具针对您计划支持的 Ruby 版本进行构建确实是最好的方法,但是,无论您是否将 Ruby 运行时限制在 Gemfile 中。
例如,您可以在 travis.yml 中使用矩阵,如下所示:
language: ruby
rvm:
- 2.2.4
- 2.5.5
切换 Gemfiles
如果你坚持按照你的方式去做,在你的 Gemfile 中允许一个单一的 Ruby 版本,那么你可能会考虑在你的源代码树中有两个不同名称的独立 gemfile,例如作为 Gemfile-2.2.4 和 Gemfile-2.5.5。然后,您可以指定要与 Bundler's --gemfile
flag 一起使用的 Gemfile,或者通过将自定义 Gemfile 符号链接到项目的规范 Gemfile
。
这里有一些要考虑的例子:
# Resolve against a specific Gemfile with
# hard-coded Ruby version.
$ ls Gemfile*
Gemfile-2.2.4 Gemfile-2.5.5
$ bundle install --gemfile="Gemfile-2.2.4"
# Resolve against whatever custom file is
# symlinked to your ./Gemfile.
$ ln -sf Gemfile{-2.5.5,}
$ ls -F Gemfile*
Gemfile@ Gemfile-2.2.4 Gemfile-2.5.5
$ bundle install
这两种方法都有效,但前者更灵活,代价是每次都需要指定您选择的 Gemfile,而后者在您的 development/testing 工作流程不支持 Bundler 的 --gemfile
旗帜。
与 Ruby 经理一起更换红宝石
如果您在开发中有多个 Ruby 版本,最佳做法是使用版本管理器,例如 rvm、rbenv 或 chruby。您可以使用版本管理器根据需要手动来回更改红宝石。
您还可以检查您的版本管理器是否在 .ruby-version
或其他配置文件上支持 auto-switching。每次要针对不同的 Ruby 构建或测试时,您仍然需要更新该文件,但您不必不断更改 Gemfile 内容、re-pointing Gemfile 符号链接或更新每次调用 Bundler 时都有一个标志。
任何给定的方法是否优于其他方法将取决于您的工作流程。没有适合所有情况的技术解决方案,因此您的里程可能会有所不同。