【问题标题】:using bundler to load different versions of gems for different platforms使用 bundler 为不同平台加载不同版本的 gem
【发布时间】:2012-01-01 21:06:24
【问题描述】:

所以我正在为 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 分支)。

【问题讨论】:

    标签: ruby git sinatra bundler


    【解决方案1】:

    你可以这样做:

    # 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'
    

    在您的两个平台上查看差异。

    【讨论】:

    • hmm,第一个解决方案抛出了关于在 gemfile 中指定两个 gem 的相同错误。条件语句工作正常。
    • 第二种方法是无效的,因为它将一个或另一个gem版本存储到Gemfile.lock中。它不能同时存储两者。因此,如果您在 Win32 开发机器上准备 Gemfile.lock 然后将其部署到 Linux,您将得到相同的错误版本。因此,我仍在寻找有效的解决方案。
    • :platform 方法效果很好,前提是不同平台只需要不同的(命名的)gem,甚至可以提交 Gemfile.lock 并使其保持稳定(与 if-else 方法不同)
    【解决方案2】:

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

    【讨论】:

    • 我假设:1.“不同的 gemfiles”是指“不同的 Gemfiles”(不是“不同的 gem 文件”);和 2. --gemfile 是指环境变量 BUNDLE_GEMFILE 或文件 .bundle/config(在开发人员的主目录中)中的 gemfile 配置设置。因此 Bundler 可以安全地创建例如Gemfile-linux.lockGemfile-windows.lock.
    【解决方案3】:

    您需要一个 gem 的多个版本(都具有相同的名称)。因此,当前使用 Bundler,您需要多个同时的 Bundler 依赖项快照“锁定”文件。如果您的开发人员使用 Bundler 的 gemfile 配置设置,这是可能的。他们可能会这样做:

    1. 通过使用环境变量BUNDLE_GEMFILE(在命令行或.bash_profile);或
    2. (可能不太理想)在.bundle/config(全局,在他们的主目录中)。

    因此,Bundler 可以安全地创建(并且可能在以后自动使用,给定相同的配置设置),例如Gemfile-linux.lockGemfile-windows.lock

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

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

    【讨论】:

    • 感谢您的回答,但我已经多年没有使用 Ruby,但我相信 2012 年的回答是令人满意的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 2012-12-07
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 2014-12-12
    • 1970-01-01
    相关资源
    最近更新 更多