Home » Ruby » Should I specify exact versions in my Gemfile?

Should I specify exact versions in my Gemfile?

Posted by: admin November 30, 2017 Leave a comment

Questions:

I’ve noticed that on rubygems.org a lot of the gems suggest you specify them by major version rather than exact version. For example…

The haml-rails gem

gem "haml-rails", "~> 0.3.4"  # "$ bundle install" will acquire the 
                              # latest version before 1.0.

However, based on the Bundler docs it sounded to me like it would be better to nail down the exact version like this…

gem "haml-rails", "0.3.4"

So there’s your haml-rails gem and all its dependencies won’t drift forward. If you check out the project on a different machine a few weeks later and run $ bundle install you’ll have precisely the same versions of everything you specified.

I’ve seen point releases break stuff, and I thought part of the whole idea of Bundler was to “Bundle.lock” all your gem versions.

But on rubygems.org they use “~>” a lot so maybe I’m missing something?

Any clarification would be very helpful to me in understanding Bundler and gem management.

Answers:

This is the purpose of the Gemfile.lock file – running bundle install with a Gemfile.lock present only installs using the dependencies listed in there; it doesn’t re-resolve the Gemfile. To update dependencies / update gem versions, you then have to explicitly do a bundle update, which will update your Gemfile.lock file.

If there wasn’t a Gemfile.lock, deploying code to production would be a major issue because, as you mention, the dependencies and gem versions could change.

In short, you should be generally safe using the pessimistic version constraint operator (~>) as rubygems.org advises. Just be sure to re-run your tests after you do a bundle update to make sure nothing breaks.

There’s a nice article by Yehuda Katz that has a little more info on Gemfile.lock.

Questions:
Answers:

I would definitely say use the exact version numbers. You can probably always just lock it down to a major version, or never specify any version, and be okay, but if you really want that fine grained level of control and to have 100% confidence in your program when being run on other machines, use the exact version numbers.

I’ve been in situations where the exact version number wasn’t specified, and when I or someone else did a bundle install, the project broke because it went to a newer version. This can be especially bad when deploying to production.

Bundler does lock in your gem specifications, but if you’re telling it to just use a major release, then it locks that in. So is just knows “Oh the version is locked in at > 0.1” or whatever, but not “Oh the version is locked in specifically at 0.1.2.3”.