Block a specific gem version in your Gemfile in Bundler

If you ever want to exclude or block a specific version of a gem in Bundler, you can.

The syntax for excluding a particular gem version in bundler is super simple:

gem 'gemname', '!= 1.0.1'

This is most useful if you have a gem version that is broken and you want to exclude it, but don’t want to exclude all upgrades. A typical Gemfile using this might look like:

gem 'gemname', ['~> 1.0', '!= 1.0.1']

This will allow any versions of gemname in the 1.x.x series, except for 1.0.1.

When the maintainers of gemname incorporate a fix (hopefully based on your pull request and release gemname 1.0.2, you can quickly update your Gemfile.lock by running bundle update gemname. It will automatically stop the upgrade until there is a version after 1.0.1.

Here’s the code in Bundler that defines the DSL in lib/bundler/version_ranges.rb in version 1.16:

ranges = requirement.requirements.map do |op, v|
  case op
  when "=" then ReqR.new(ReqR::Endpoint.new(v, true), ReqR::Endpoint.new(v, true))
  when "!=" then NEq.new(v)
  when ">=" then ReqR.new(ReqR::Endpoint.new(v, true), ReqR::Endpoint.new(ReqR::INFINITY, false))
  when ">" then ReqR.new(ReqR::Endpoint.new(v, false), ReqR::Endpoint.new(ReqR::INFINITY, false))
  when "<" then ReqR.new(ReqR::Endpoint.new(ReqR::ZERO, true), ReqR::Endpoint.new(v, false))
  when "<=" then ReqR.new(ReqR::Endpoint.new(ReqR::ZERO, true), ReqR::Endpoint.new(v, true))
  when "~>" then ReqR.new(ReqR::Endpoint.new(v, true), ReqR::Endpoint.new(v.bump, false))
  else raise "unknown version op #{op} in requirement #{requirement}"
  end
end.uniq

This feature is undocumented in bundler, so thought it worth highlighting briefly.

Footer