Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make bundler use different gems for different platforms

I'm working on upgrading one of our Rails 2.3.8 apps to Rails 3, and have run into an annoying problem with bundler and deployment. I develop the application on a Windows machine, but the production environment is running Ubuntu Linux. Now, my problem is that bundler is ignoring the mysql gem in the production environment, and Passenger spits out: "!!! Missing the mysql gem. Add it to your Gemfile: gem 'mysql', '2.8.1'"

Here is my Gemfile:

# Edit this Gemfile to bundle your application's dependencies. # This preamble is the current preamble for Rails 3 apps; edit as needed. source 'http://rubygems.org'  gem 'rails', '3.0.0' gem 'net-ldap', :require => 'net/ldap' gem 'highline', :require => 'highline/import' gem 'mysql', '2.8.1' gem 'net-ssh', :require => 'net/ssh'  # Bundle gems for the local environment. Make sure to # put test-only gems in this group so their generators # and rake tasks are available in development mode: group :development, :test do   gem 'fakeweb', :require => 'fakeweb'   gem 'flexmock', :require => 'flexmock/test_unit' end 

As you can see, the mysql gem is specified. However, when deploying, bundler ignores it. Why? The reason is that Bundler generates the following Gemfile.lock (only relevant parts included):

.... mime-types (1.16) mysql (2.8.1-x86-mingw32) net-ldap (0.1.1) .... 

Notice that it includes the platform specific gem. This is obviously NOT what I want it to do, as that gem is not suitable (and appearently ignored) when running under Linux.

So, does Bundler come with any way to deal with these issues? Or do I have to remember to manually change the mysql gem version in the generated Gemfile.lock every time I run bundle install on my development machine?

Thank you in advance!

Update

It seems like the bundler team is aware of this issue.

like image 360
Daniel Abrahamsson Avatar asked Sep 04 '10 11:09

Daniel Abrahamsson


People also ask

What is the difference between gem install and bundle install?

Almost seems like running 'gem install' adds it to the global available gems (and hence terminal can run the package's commands), whereas adding it to the gemfile and running bundle install only adds it to the application. Similar to npm install --global. that's basically it.

Where does bundle install gems to?

Show activity on this post. I know that when using gem install , the gem will be stored under /home/username/. rvm/gems/, under which gemset the gem was installed.

What is gem require false?

You use :require => false when you want the gem to be installed but not "required". So in the example you gave: gem 'whenever', :require => false when someone runs bundle install the whenever gem would be installed as with gem install whenever .


1 Answers

This is a known issue in Bundler. The workarounds are either:

  • Generate a Gemfile.lock on a system similar enough to your production environment that you get results that match your production platform. Effectively, that means you can only generate the Gemfile.lock file on Windows if your production system is Windows.
  • Don't commit a Gemfile.lock file at all, and determine dependencies on the production machine at deploy time (bundle install without --deploy). While not recommended in general, this is an often-used workaround until the bug is fixed. For example, this is the recommended solution offered by Heroku.
  • Switch to JRuby, which would have the same platform string across both Windows and Linux (java). I don't recommend this seriously, but I believe it would fix the problem.
  • Fix the problem in the Bundler source code, i.e., help the Bundler team fix the bug. :)
like image 188
wuputah Avatar answered Sep 23 '22 14:09

wuputah