Ruby 2.7 comes with the default bundler
gem, which always has 2.0+
version. This is a great default in general, especially to the beginners. But in some cases, like when using Rails 4
, we want to keep the bundler
version under 2.0
to avoid conflicts.
Bundler could not find compatible versions for gem "bundler":
In Gemfile:
rails (~> 4.2) was resolved to 4.2.11.3, which depends on
bundler (< 2.0, >= 1.3.0)
Current Bundler version:
bundler (2.1.4)
However, it's not easy to rollback to a older version of bundler
. Since the 2.0+
version will be installed as a default gem, simply uninstall it won't work:
$ gem uninstall bundler
=> Gem bundler-2.1.4 cannot be uninstalled because it is a default gem
And these tricks won't work either (at least they didn't work for me):
$ bundle -v
Bundler version 2.1.4
$ gem install bundler:1.17.3 --default
Successfully installed bundler-1.17.3 as a default gem
Done installing documentation for bundler after 0 seconds
1 gem installed
$ bundle -v
Bundler version 2.1.4
$ bundle config default 1.17.3
$ bundle -v
Bundler version 2.1.4
From all the references I can find, the only way to remove it is to delete the bundler-2.1.4.gemspec
file from the gem path. The following commands did the trick for me:
$ gem env gempath
/Users/st0012/.gem/ruby/2.7.0:/Users/st0012/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0
$ ls /Users/st0012/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/specifications/**/bundler-*.gemspec
/Users/st0012/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/specifications/default/bundler-2.1.4.gemspec
$ rm /Users/st0012/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/specifications/**/bundler-2.1.4.gemspec
$ gem install bundler:1.17.3 --default
$ bundle -v
Bundler version 1.17.3
But what if we want to perform the same cleanup on CI (like travis-ci
) too? Well, I wrote a script for you:
#!/usr/bin/env ruby
gempaths = `gem env gempath`.split(":")
gempaths.each do |gempath|
# lookup bundler-*.gemspec files and delete them
# this is the only way to completely cleanup default bundler
# Note: the bundler gemspecs' paths are different for CRuby and JRuby
Dir.glob(gempath.strip + "/specifications/**/bundler-*.gemspec").each { |p| File.delete(p) }
end
# Remember to make this file executable
Then you can add this to your CI config file (.travis.yml
for example):
before_install:
- ./cleanup_bundler
- gem install bundler -v '1.17'
And that's it! I hope this short post can save you from pulling your hair for a few hours 😉
If you're a Rubyist and you like this post, please also check the debugging tools I wrote:
Top comments (7)
--default
option of gem command will not install the library files. I think you can use the bundler-1.x with simplygem install bundler -v 1.17.3
. After that, The bundler switcher of RubyGems can detect the old version of bundler automatically.Thanks for the comment! But I just tried it with freshly installed Ruby 2.7.1 and it didn't work 🤔
First, I made sure I only have the default bundler
2.1.4
. And then I installed version1.17.3
But after installing version
1.17.3
it still uses2.1.4
, which can't be uninstalled.Now if I create a new Gemfile and run bundle install, it'll still use
2.1.4
instead of1.17.3
.Did I miss anything?
You can use bundler-1.17.3 with
bundle __1.17.3__ install
. Or After you update2.1.4
to1.17.3
onBUNDLED WITH
field, You can use bundler-1.17.3 with bundle command.I wrote this script a couple of years ago when working on my Bundler plugin. It's pretty thorough, maybe more than what you need. It also may be a little out of date: github.com/chrismo/bundler-fixture...
Please, update your Rails (or whatever) version or don't update the Ruby. That's all, it's simple.
I’m maintaining multiple gems, so I need to make sure they are compatible with the latest Ruby release.
When a new Ruby release is incompatible with some versions of your gems dependencies — I think it's time to make a new major release. Old gem versions works with old Bundler and Ruby, new — with new, seems legit.