DEV Community

Stan Lo
Stan Lo

Posted on

Completely Remove Ruby 2.7's Default Bundler

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Then you can add this to your CI config file (.travis.yml for example):

before_install:
  - ./cleanup_bundler
  - gem install bundler -v '1.17'
Enter fullscreen mode Exit fullscreen mode

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:

GitHub logo st0012 / object_tracer

ObjectTracer tracks objects and records their activities

GitHub logo st0012 / power_trace

Buff exception backtrace with local variables, passed in arguments and instance variables!

Oldest comments (7)

Collapse
 
chrismo profile image
chrismo

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

Collapse
 
alexwayfer profile image
Alexander Popov

Please, update your Rails (or whatever) version or don't update the Ruby. That's all, it's simple.

Collapse
 
st0012 profile image
Stan Lo

I’m maintaining multiple gems, so I need to make sure they are compatible with the latest Ruby release.

Collapse
 
alexwayfer profile image
Alexander Popov

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.

Collapse
 
hsbt profile image
SHIBATA Hiroshi

--default option of gem command will not install the library files. I think you can use the bundler-1.x with simply gem install bundler -v 1.17.3. After that, The bundler switcher of RubyGems can detect the old version of bundler automatically.

Collapse
 
st0012 profile image
Stan Lo

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 version 1.17.3

$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]

$ gem list bundler
*** LOCAL GEMS ***

bundler (default: 2.1.4)

$ gem install bundler -v 1.17.3                                                                                                                                                                                                              Fetching bundler-1.17.3.gem
Successfully installed bundler-1.17.3
Parsing documentation for bundler-1.17.3
Installing ri documentation for bundler-1.17.3
Done installing documentation for bundler after 2 seconds
1 gem installed

$ gem list bundler

*** LOCAL GEMS ***

bundler (default: 2.1.4, 1.17.3)

But after installing version 1.17.3 it still uses 2.1.4, which can't be uninstalled.

$ bundle -v
Bundler version 2.1.4

$ gem uninstall 2.1.4
Gem '2.1.4' is not installed

$ gem uninstall bundler -v 2.1.4
Gem bundler-2.1.4 cannot be uninstalled because it is a default gem

Now if I create a new Gemfile and run bundle install, it'll still use 2.1.4 instead of 1.17.3.

$ echo "source 'https://rubygems.org'" >> Gemfile

$ bundle
The Gemfile specifies no dependencies
Resolving dependencies...
Bundle complete! 0 Gemfile dependencies, 1 gem now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

$ cat Gemfile.lock
GEM
  remote: https://rubygems.org/
  specs:

PLATFORMS
  ruby

DEPENDENCIES

BUNDLED WITH
   2.1.4

Did I miss anything?

Collapse
 
hsbt profile image
SHIBATA Hiroshi

You can use bundler-1.17.3 with bundle __1.17.3__ install. Or After you update 2.1.4 to 1.17.3 on BUNDLED WITH field, You can use bundler-1.17.3 with bundle command.