Should I include exact versions in my gemfile?

I noticed that on rubygems.org many gems offer to indicate them according to the main, and not according to the exact version. For example...

Gemstones ...

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

However, based on the Bundler documentation , it seemed to me that it would be better to write down an exact version, like this ...

 gem "haml-rails", "0.3.4" 

Thus, your gem and all its dependencies will not move forward. If you check the project on another computer a few weeks later and run $ bundle install you will have exactly the same versions of everything that you specified.

I saw point releases breaking things, and I thought that part of the whole Bundler idea was " Bundle.lock " for all of your versions of Bundle.lock .

But on rubygems.org they often use "~>", so maybe I missed something?

Any clarification would be very helpful for understanding the Bundler and managing gems.

+61
ruby ruby-on-rails ruby-on-rails-3 rubygems bundler
Feb 13 '12 at 17:41
source share
3 answers

This is the purpose of the Gemfile.lock file - to run bundle install with the presence of Gemfile.lock only using the dependencies listed there; it does not redirect the gemfile. To update dependencies / update gem versions, you need to explicitly do bundle update , which will update your Gemfile.lock file.

If there wasn’t Gemfile.lock, deploying code for production would be a serious problem because, as you mentioned, changes in the dependency and version of gem can change.

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

There is a good article from Yehuda Katz that has a bit more information about Gemfile.lock.

+54
Feb 13 '12 at 18:11
source share

I will definitely say that I use the exact version numbers. You can probably always just lock it to the main version or never specify any version, and that's all right, but if you really want this subtle level of control to be 100% sure of your program when running on other machines , use exact version numbers.

I was in situations where the exact version number was not specified, and when I or someone else did bundle install , the project broke down because it switched to a newer version. This can be especially bad when deployed into production.

The Bundler blocks your gem characteristics, but if you tell him to just use the main release, then he blocks it. So he just knows: "Oh, the version is blocked at> 0.1" or something else, but not "Oh, the version is blocked, in particular, at 0.1.2.3."

+5
Feb 13 '12 at 18:10
source share

TL; DR

Yes, use a pessimistic lock ( ~> ) and specify the semantic version for correction ( Major.minor.patch ) for all your gems!

discussion

I am surprised at the lack of clarity on this issue, even "industry experts" told me the other day that Gemfile.lock exists to support gem versions. Wrong!

You want to organize your Gemfile in such a way that you can run bundle update at any time without risking breaking everything. To achieve this:

  1. Specify a patch level version for all your pessimistic blocking gems. This will allow bundle update provide you with fixes, but not make changes.

  2. Specify ref for git gems

The only drawback of this setting is that when a new sweet / main version for the gem comes out, you have to increase the version manually.

Warning script

Think about what happens if you don’t block your gems.
Your gemfile has unlocked gem "rails" for gems, and the version in Gemfile.lock is 4.1.16 . You write code, and at some point you do bundle update . Now your version of Rails switches to 5.2.0 (assuming that some other gems do not interfere with this), and everything breaks.
Do yourself a favor and do not allow it for any gem!

Gemfile Example

 # lock that bundler if (version = Gem::Version.new(Bundler::VERSION)) < Gem::Version.new('1.16.3') abort "Bundler version >= 1.16.3 is required. You are running #{version}" end source "http://rubygems.org" # specify explicit ref for git repos gem "entity_validator", git: "https://github.com/plataformatec/devise", ref: "acc45c5a44c45b252ccba65fd169a45af73ff369" # "2018-08-02" # consider hard-lock on gems you do not want to change one bit gem "rails", "5.1.5" # pessimistic lock on your common gems gem "newrelic_rpm", "~> 4.8.0" gem "puma", "~> 3.12.0" group :test do gem "simplecov", "~> 0.16.1", require: false end 

Concession
If you are sure that your tests will detect errors caused by changes in the version of the gem, you can try gems with pessimistic blocking in the minor version, and not in the patch.
This will increase the version of the gem within the specified main version, but not in the next.

 gem "puma", "~> 3.12" 
+3
Aug 10 '18 at 14:24
source share



All Articles