There are a couple of libraries which I usually include in my Gemfiles because they make Guard more awesome on Ubuntu. However, they don’t make sense to require on other platforms, and they probably don’t even compile when not on Linux.
As far as I can tell, there’s no “official” way to conditionally include gems in a Gemfile based on the current OS platform. Or at least there wasn’t the last time I looked at the Bundler documentation. Fortunately a Gemfile is just Ruby, so that’s not really a limitation.
So here’s what I put in my Gemfile:
group :test, :development do # ... gem 'rb-inotify' if RUBY_PLATFORM =~ /linux/i gem 'libnotify' if RUBY_PLATFORM =~ /linux/i end
This works well for me, but if there’s a better way I’d love to know it.
The bundler manual has this on the Gemfile (read this: http://gembundler.com/man/gemfile.5.html):
This probably means that you might be able to use something like:
Hope to have helped.
Yes, but that’s for the type of Ruby VM, not the OS.
You’re right, I should have noticed that. Thanks for pointing it out.
What you want is: “gem ‘libnotify’, :require => false”
An example is at https://gist.github.com/3843679
These libraries will be installed, but won’t be required and therefore won’t bork other platforms.
The method you have above, which I’m sure you are aware, will cause the Gemfile.lock file to change depending on which platform you run “bundle install” on.
I’m not sure that’s what I want, since last I checked at least one of those gems won’t even compile on non-linux platforms.
I’ve used it on windows, Ubuntu, and Mac OS X successfully. If you have problems, I’d like to know about it.
By looking at https://github.com/rubygems/rubygems/blob/master/lib/rubygems/platform.rb and https://github.com/carlhuda/bundler/blob/master/spec/other/ext_spec.rb, it seems that you can specify a string to :platform instead of a symbol in order to match the OS as well.
Now that is indeed interesting.
I usually use Gemfile groups for these, like:
gem ‘rb-inotify’, :group => :linux
When I install gems, I have to specify –without in order to not install those gems, but this works well. Using if statements in the Gemfile will cause your Gemfile.lock to be generated with the logic of the platform you last ran bundle upgrade on.
Hi Avdi, I had problems with this approach when using it with Capistrano for deployment. Didn’t you encounter similar problems?
I needed some platform specific gems for OSX (growl, terminal-notifier) and some platform specific for Linux, so as an alternative to using plain old ruby conditionals, I put it in a :osx and a :linux group and excluded :linux on osx with bundle install –without linux and vice versa. But this is not a clean solution, so I think it would be very useful to have native support in bundler, to manage platform specific gems.
This is what I do as well. You can tell bundler to never install the “linux” group by doing
bundle config without :linux.
What always trips me with this is that on OSX i need bundler to install let’s say the fs-event gem and it then writes it to Gemfile.lock, but when I deploy to a Linux system it will cry as fs-event is in Gemfile.lock but not available on Linux.
Any solutions to that problem?
As others have said, the remaining issue is how to manage the Gemfile.lock. Have you found a solution? it would be nice if there were a way to specify the location of the Gemfile.lock and change it based on the platform, but last I checked the code’s highly coupled to the naming convention.