使用bundler为不同平台加载不同版本的gem

时间:2012-01-01 21:06:24

标签: ruby git sinatra bundler

所以我正在为Windows和Linux开发Sinatra。问题是我使用的是Thin而不是Webrick,而eventmachine for windows仅适用于预发布版本,而linux使用最新的稳定版本。在gemfile中,你当然不能包含不同版本的同一个gem,如下所示:

gem "eventmachine", "~> 1.0.0.beta.4.1", :group => :development_win
gem "eventmachine", group => :development_linux
gem "thin

我想知道是否有办法解决这个问题,可能使用一个用于windows的gemfile和一个用于linux的gemfile,该命令将加载一个或另一个。

或者有一种方法可能在git中管理两个不同平台的gemfile,可能只通过文件的分支(不知道是否可以从我读过的git分支)。

3 个答案:

答案 0 :(得分:20)

你可以这样做:

# Windows
gem "eventmachine", "~> 1.0.0.beta.4.1", :platform => [:mswin, :mingw]

# C Ruby (MRI) or Rubinius, but NOT Windows
gem "eventmachine", :platform => :ruby

可用平台的完整列表:

ruby      C Ruby (MRI) or Rubinius, but NOT Windows
ruby_18   ruby AND version 1.8
ruby_19   ruby AND version 1.9
ruby_20   ruby AND version 2.0
mri       Same as ruby, but not Rubinius
mri_18    mri AND version 1.8
mri_19    mri AND version 1.9
mri_20    mri AND version 2.0
rbx       Same as ruby, but only Rubinius (not MRI)
jruby     JRuby
mswin     Windows
mingw     Windows 'mingw32' platform (aka RubyInstaller)
mingw_18  mingw AND version 1.8
mingw_19  mingw AND version 1.9
mingw_20  mingw AND version 2.0 

您可以在Gemfile(5)手册页here中找到更多信息(请参阅“平台”部分)。

另一种方法是使用RUBY_PLATFORM常量:

if RUBY_PLATFORM =~ /win32/
  gem "eventmachine", "~> 1.0.0.beta.4.1"
else
  gem "eventmachine"
end

我还没有看到RUBY_PLATFORM的完整可用值列表,但您可以运行

ruby -e 'puts RUBY_PLATFORM'

在你的平台上看到差异。

答案 1 :(得分:3)

您可以使用--gemfile选项为不同的平台使用不同的gem文件。请参阅此处的文档 http://gembundler.com/man/bundle-config.1.html

答案 2 :(得分:0)

您需要宝石的多个版本(都具有相同的名称)。因此,目前使用Bundler,您需要多个同时使用的Bundler依赖关系快照'lock'文件。如果您的开发人员使用Bundler的gemfile配置设置,这是可能的。他们可能会这样做:

  1. 通过使用环境变量BUNDLE_GEMFILE(在命令行或.bash_profile中);或
  2. (可能不太理想).bundle/config(全局,在其主目录中)。
  3. 因此,安全地,Bundler可以创建(并且可能在以后使用,在给定相同的配置设置的情况下),例如Gemfile-linux.lockGemfile-windows.lock

    虽然这种基本方法似乎可行,但它并不是很干。但是,如果例如Gemfile-linuxGemfile-windows自动合并它们共有的任何Gemfile语句,则会改善这种情况:即,如果它们包含语句:

    ::Kernel.eval(File.open('Gemfile-common','r'){|f| f.read},::Kernel.binding)