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)
--defaultoption 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.3But after installing version
1.17.3it 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.4instead 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.4to1.17.3onBUNDLED WITHfield, 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.