我正在使用仅以二进制形式分发的gem。因此,我们有两个版本(不是宝石版本号,只是两个不同的二进制文件),我们必须以某种方式在我们的环境中有条件地加载,因为我们在OS X上开发并在Linux(AWS)上部署。
我将这些宝石提取到<app_root>/vendor/gems
,如下所示:
chilkat-9.5.0.69-x86_64-darwin/
chilkat-9.5.0.69-x86_64-linux/
我意识到我可以在Gemfile中设置development
组和production
组:
group :development do
gem 'chilkat', path: 'vendor/gems/chilkat-9.5.0.69-x86_64-darwin'
end
group :production do
gem 'chilkat', path: 'vendor/gems/chilkat-9.5.0.69-x86_64-linux'
end
但那失败了:
[!] There was an error parsing `Gemfile`: You cannot specify the same gem twice coming from different sources.
You specified that chilkat (>= 0) should come from source at `vendor/gems/chilkat-9.5.0.69-x86_64-darwin` and source at `vendor/gems/chilkat-9.5.0.69-x86_64-linux`
. Bundler cannot continue.
更重要的是,我无法让Bundler在production
上独立运行,可能是因为它无法识别平台:
Could not find chilkat-9.5.0.69 in any of the sources
我对gemspec文件了解不多,但可能是最后一行:
--- !ruby/object:Gem::Specification
name: chilkat
version: !ruby/object:Gem::Version
version: 9.5.0.69
platform: x86_64-linux
告诉Bundler如果它指定的平台与运行它的平台不同,则跳过它。
初始解决方案
由下面的用户ulferts。
if RUBY_PLATFORM =~ /darwin/
gem 'chilkat', path: 'vendor/gems/chilkat-9.5.0.69-x86_64-darwin'
elsif RUBY_PLATFORM =~ /x86_64-linux/
gem 'chilkat', path: 'vendor/gems/chilkat-9.5.0.69-x86_64-linux'
end
我一直试图检查Rails.env
,但我不知道RUBY_PLATFORM
常数。
然而
Bundler似乎有缺陷,缺乏灵活性。尝试部署到生产中时失败:
You are trying to install in deployment mode after changing
your Gemfile. Run `bundle install` elsewhere and add the
updated Gemfile.lock to version control.
因此即使条件存在,Gemfile.lock
文件似乎也会导致出现某种问题。这真的很不幸,因为我认为这种合法用法不是一个边缘案例。
简而言之,即使使用条件,也不能在Gemfile中列出两次相同的gem。是否为不同的来源,不同的版本,或两者兼而有之。
我尝试了其他的东西:在生产中更改宝石的名称。我更改了gemspec文件中的目录名称,gem名称和引用。结果:
You have added to the Gemfile:
* source: source at `vendor/gems/chilkatprod-9.5.0.69-x86_64-linux`
* chilkatprod
You have deleted from the Gemfile:
* source: source at `vendor/gems/chilkat-9.5.0.69-x86_64-darwin`
* chilkat
You have changed in the Gemfile:
* chilkat from `no specified source` to `source at
`供应商/宝石/奇尔卡特-9.5.0.69-x86_64的-darwin``
突然看起来它现在甚至不喜欢条件。我在执行require
的代码中设置了一个条件来促进这一点,但如果代码无法部署,我甚至无法实现。
答案 0 :(得分:2)
Gemfile
只是另一个ruby文件。如果你能弄清楚你所在的架构,你可以简单地将它包装在if ... else
例如
if architecture_is_os_x?
gem 'chilkat', path: 'vendor/gems/chilkat-9.5.0.69-x86_64-darwin'
else
gem 'chilkat', path: 'vendor/gems/chilkat-9.5.0.69-x86_64-linux'
end
区分的一种可能性是在生产中设置env变量。
答案 1 :(得分:0)
也许您可以使用 Install_if ?