Should I specify exact versions in my Gemfile?

后端 未结 3 921
萌比男神i
萌比男神i 2021-01-30 02:50

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...

         


        
3条回答
  •  北海茫月
    2021-01-30 03:21

    TL;DR

    Yes, use pessimistic locking (~>) and specify a semantic version down to patch (Major.minor.patch) on all your gems!

    Discussion

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

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

    1. Specify a patch-level version for all your gems with pessimistic locking. This will allow bundle update to give you fixes, but not breaking changes.

    2. Specify a ref for gems from git

    The only downside to this setup is that when a sweet new minor/major version for a gem comes out, you have to bump the version up manually.

    Warning scenario

    Consider what happens if you do not lock your gems.
    You have an unlocked gem "rails" in your gemfile and the version in Gemfile.lock is 4.1.16. You are coding along and at some point you do a bundle update. Now your Rails version jumps to 5.2.0 (provided some other gem does not prevent this) and everything breaks.
    Do yourself a favor and do not allow this for any gem!

    An example Gemfile

    # 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
    

    A concession
    If you are confident your tests will catch bugs introduced by gem version changes, you can try pessimistic-locking gems at minor version, not patch.
    This will allow the gem version to increase within the specified major version, but never into the next one.

    gem "puma", "~> 3.12"
    

提交回复
热议问题