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

时间:2021-02-15 00:18:51

I'm developing a Rails app on a Mac, and I'm new to testing, so I just added these gems to my Gemfile:

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

group :test, :development do
  gem 'rspec-rails'     
  gem 'rb-fsevent'
  gem 'growl'
end

But my production server runs Linux, so even if they aren't grouped in :production, bundler (v1.0.21) still attempts to install them. ...and fails, obviously!
extconf.rb:19:in '<main>': Only Darwin (Mac OS X) systems are supported (RuntimeError)

但是我的生产服务器运行Linux,所以即使它们没有分组:production,bundler(v1.0.21)仍然会尝试安装它们。 ......显然失败了! extconf.rb:19:在'

'中:仅支持Darwin(Mac OS X)系统(RuntimeError)

Setting RAILS_ENV to production before running bundle install doesn't work.

在运行bundle install之前将RAILS_ENV设置为production不起作用。

It worked by running bundle install --without development test, but how can these gems be taken into consideration by bundler only based on your OS?

它运行捆绑安装 - 没有开发测试,但是如何仅通过基于您的操作系统的捆绑器来考虑这些宝石?


Edit: The bundler wiki provides details on how to use platform as a parameter.
The same solution is given in bundler issue #663, so I tried:

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

group :test, :development do
  gem 'rspec-rails'     
  platforms :darwin do
    gem 'rb-fsevent'
    gem 'growl'
  end 
end

bundle install does not work, but even if we go back to square one and do
bundle install --without darwin, the result is '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]

捆绑安装不起作用,但即使我们回到原点并进行捆绑安装 - 没有darwin,结果是'darwin'不是一个有效的平台。可用选项包括:[:ruby,:ruby_18,:ruby_19,:mri,:mri_18,:mri_19,:rbx,:jruby,:mswin,:mingw,:mingw_18,:mingw_19]


Any other (elegant) approaches?

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

5 个解决方案

#1


15  

Gemfile actually is a regular ruby file, so you can use something like

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

case RUBY_PLATFORM
when /darwin/
  gem 'foo'
when /win32/
  gem 'bar'
end

#2


23  

The Bundler wiki has a method that adds all gems to Gemfile.lock regardless of platform. It sets require => false depending on the system so you don't need to be able to actually run the gems:

Bundler wiki有一个方法可以将所有gems添加到Gemfile.lock,而不管平台如何。它根据系统设置require => false,因此您不需要能够实际运行gem:

gem 'rb-inotify', :require => RUBY_PLATFORM.include?('linux') && 'rb-inotify'

And they provide helper methods to make this clean:

他们提供帮助方法来使其干净:

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)

On my Windows 7 x64 system running Ubuntu 12.04 in a Vagrant VM, this worked fine, but the :platforms setting was required - the Linux bundler choked on the 'win32console' gem:

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

Console.c:1:21: fatal error: windows.h: No such file or directory

#3


7  

@zed_0xff: found a similar approach in an older rspec-core commit:

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

if RUBY_PLATFORM =~ /darwin/
  gem 'foo'
end

#4


7  

You can use :install_if method which accepts arbitrary lambda.

您可以使用:install_if方法,它接受任意lambda。

Following example comes directly from Gemfile's man pages:

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

install_if -> { RUBY_PLATFORM =~ /darwin/ } do
  gem "pasteboard"
end

It is much better than control flow constructs (e.g. if) as it maintains dependencies correctly and keeps Gemfile.lock uniform on all machines.

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

#5


1  

According to the Bundler docs, you need to use the platforms directive:

根据Bundler文档,您需要使用platforms指令:

#Gemfile
platforms :mswin do
  gem "x"
end

gem "weakling",   :platforms => :jruby
gem "ruby-debug", :platforms => :mri_18
gem "nokogiri",   :platforms => [:mri_18, :jruby]

There are a number of Gemfile platforms:

有许多Gemfile平台:

ruby C Ruby (MRI) or Rubinius, but NOT Windows

ruby C Ruby(MRI)或Rubinius,但不是Windows

ruby_18 ruby AND version 1.8

ruby_18 ruby​​ AND版本1.8

ruby_19 ruby AND version 1.9

ruby_19 ruby​​ AND版本1.9

ruby_20 ruby AND version 2.0

ruby_20 ruby​​ AND 2.0版

mri Same as ruby, but not Rubinius

mri和红宝石一样,但不是Rubinius

mri_18 mri AND version 1.8

mri_18 mri和版本1.8

mri_19 mri AND version 1.9

mri_19 mri和1.9版

mri_20 mri AND version 2.0 rbx Same as ruby, but only Rubinius (not MRI

mri_20 mri和版本2.0 rbx与ruby相同,但只有Rubinius(不是MRI

jruby JRuby

jruby JRuby

mswin Windows

mswin Windows

mingw Windows 'mingw32' platform (aka RubyInstaller)

mingw Windows'mingw32'平台(又名RubyInstaller)

mingw_18 mingw AND version 1.8

mingw_18 mingw和版本1.8

mingw_19 mingw AND version 1.9 mingw_20 mingw AND version 2.0

mingw_19 mingw AND version 1.9 mingw_20 mingw AND version 2.0

#1


15  

Gemfile actually is a regular ruby file, so you can use something like

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

case RUBY_PLATFORM
when /darwin/
  gem 'foo'
when /win32/
  gem 'bar'
end

#2


23  

The Bundler wiki has a method that adds all gems to Gemfile.lock regardless of platform. It sets require => false depending on the system so you don't need to be able to actually run the gems:

Bundler wiki有一个方法可以将所有gems添加到Gemfile.lock,而不管平台如何。它根据系统设置require => false,因此您不需要能够实际运行gem:

gem 'rb-inotify', :require => RUBY_PLATFORM.include?('linux') && 'rb-inotify'

And they provide helper methods to make this clean:

他们提供帮助方法来使其干净:

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)

On my Windows 7 x64 system running Ubuntu 12.04 in a Vagrant VM, this worked fine, but the :platforms setting was required - the Linux bundler choked on the 'win32console' gem:

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

Console.c:1:21: fatal error: windows.h: No such file or directory

#3


7  

@zed_0xff: found a similar approach in an older rspec-core commit:

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

if RUBY_PLATFORM =~ /darwin/
  gem 'foo'
end

#4


7  

You can use :install_if method which accepts arbitrary lambda.

您可以使用:install_if方法,它接受任意lambda。

Following example comes directly from Gemfile's man pages:

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

install_if -> { RUBY_PLATFORM =~ /darwin/ } do
  gem "pasteboard"
end

It is much better than control flow constructs (e.g. if) as it maintains dependencies correctly and keeps Gemfile.lock uniform on all machines.

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

#5


1  

According to the Bundler docs, you need to use the platforms directive:

根据Bundler文档,您需要使用platforms指令:

#Gemfile
platforms :mswin do
  gem "x"
end

gem "weakling",   :platforms => :jruby
gem "ruby-debug", :platforms => :mri_18
gem "nokogiri",   :platforms => [:mri_18, :jruby]

There are a number of Gemfile platforms:

有许多Gemfile平台:

ruby C Ruby (MRI) or Rubinius, but NOT Windows

ruby C Ruby(MRI)或Rubinius,但不是Windows

ruby_18 ruby AND version 1.8

ruby_18 ruby​​ AND版本1.8

ruby_19 ruby AND version 1.9

ruby_19 ruby​​ AND版本1.9

ruby_20 ruby AND version 2.0

ruby_20 ruby​​ AND 2.0版

mri Same as ruby, but not Rubinius

mri和红宝石一样,但不是Rubinius

mri_18 mri AND version 1.8

mri_18 mri和版本1.8

mri_19 mri AND version 1.9

mri_19 mri和1.9版

mri_20 mri AND version 2.0 rbx Same as ruby, but only Rubinius (not MRI

mri_20 mri和版本2.0 rbx与ruby相同,但只有Rubinius(不是MRI

jruby JRuby

jruby JRuby

mswin Windows

mswin Windows

mingw Windows 'mingw32' platform (aka RubyInstaller)

mingw Windows'mingw32'平台(又名RubyInstaller)

mingw_18 mingw AND version 1.8

mingw_18 mingw和版本1.8

mingw_19 mingw AND version 1.9 mingw_20 mingw AND version 2.0

mingw_19 mingw AND version 1.9 mingw_20 mingw AND version 2.0