如何添加Mac特定的宝石在Mac上捆绑但不在Linux上捆绑?

Mar*_*tuc 27 ruby rubygems ruby-on-rails bundler

我正在Mac上开发一个Rails应用程序,我是新手测试,所以我只是将这些宝石添加到我的Gemfile中:

group :test, :development do
  gem 'rspec-rails'     
  gem 'rb-fsevent'
  gem 'growl'
end
Run Code Online (Sandbox Code Playgroud)

但是我的生产服务器运行Linux,所以即使它们没有分组:production,bundler(v1.0.21)仍然会尝试安装它们.......显然失败了!
extconf.rb:19:in '<main>': Only Darwin (Mac OS X) systems are supported (RuntimeError)

RAILS_ENV在运行之前设置为生产bundle install 不起作用.

它通过运行起作用bundle install --without development test,但是如何仅通过基于您的操作系统的捆绑器来考虑这些宝石?


编辑: bundler wiki提供有关如何使用platform作为参数的详细信息.
捆绑问题#663中给出了相同的解决方案,所以我尝试了:

group :test, :development do
  gem 'rspec-rails'     
  platforms :darwin do
    gem 'rb-fsevent'
    gem 'growl'
  end 
end
Run Code Online (Sandbox Code Playgroud)

bundle install不起作用,但即使我们回到原点并做
bundle install --without darwin,结果是'darwin' is not a valid platform.
The available options are: [:ruby, :ruby_18, :ruby_19, :mri, :mri_18, :mri_19, :rbx, :jruby, :mswin, :mingw, :mingw_18, :mingw_19]


还有其他(优雅的)方法吗?

ion*_*ono 23

捆扎机维基有一种方法将所有宝石Gemfile.lock的与平台无关的.它require => false根据系统设置,因此您无需实际运行宝石:

gem 'rb-inotify', :require => RUBY_PLATFORM.include?('linux') && 'rb-inotify'
Run Code Online (Sandbox Code Playgroud)

并且它们提供了帮助方法来使其干净:

def os_is(re)
  RbConfig::CONFIG['host_os'] =~ re
end

gem 'rb-fsevent', "~> 0.9.3", platforms: :ruby, install_if: os_is(/darwin/)
gem 'rb-inotify', "~> 0.8.8", platforms: :ruby, install_if: os_is(/linux/)
gem 'wdm',        "~> 0.1.0", platforms: [:mswin, :mingw. :x64_mingw], install_if: os_is(/mingw|mswin/i)
Run Code Online (Sandbox Code Playgroud)

在我在Vagrant VM上运行Ubuntu 12.04的Windows 7 x64系统上,这很好用,但:platforms设置是必需的 - 在"win32console"gem上阻塞的Linux捆绑器:

Console.c:1:21: fatal error: windows.h: No such file or directory
Run Code Online (Sandbox Code Playgroud)

  • 捆绑维基似乎不再存在,它(或那个页面)移动到其他地方? (2认同)

zed*_*xff 17

Gemfile实际上是一个常规的ruby文件,所以你可以使用类似的东西

case RUBY_PLATFORM
when /darwin/
  gem 'foo'
when /win32/
  gem 'bar'
end
Run Code Online (Sandbox Code Playgroud)

  • 我使用这种方法的问题是你的Gemfile.lock的内容将根据你运行bundle命令的平台而改变.通常一个检查Gemfile.lock,所以这可能是一个问题...... (17认同)

Mar*_*tuc 7

@ zed_0xff:在旧的rspec-core提交中找到了类似的方法:

if RUBY_PLATFORM =~ /darwin/
  gem 'foo'
end
Run Code Online (Sandbox Code Playgroud)


ska*_*lee 7

您可以使用:install_if接受任意lambda的方法.

以下示例直接来自Gemfile的手册页:

install_if -> { RUBY_PLATFORM =~ /darwin/ } do
  gem "pasteboard"
end
Run Code Online (Sandbox Code Playgroud)

它比控制流构造(例如if)好得多,因为它正确地维护了依赖关系并且在所有机器上保持Gemfile.lock一致.