Blog header transparent bg

Bundler 1.13: The one with steady improvements

by André Arko on

Bundler 1.13 is out! It’s been a steady stream of improvements over the last four months, and we’re shipping some new features, some improved features, and some experimental features. Now that we’ve shipped all of these changes, we’re starting to work at full speed on the upcoming 1.14 and 2.0 releases. While you wait, read on for the changes in 1.13 and then give it a try!

New features

Support for required_ruby_version (with declared ruby)

One very nice addition is that gems with a required_ruby_version will now resolve correctly as long as your Gemfile contains a ruby declaration. This change is the culmination of years worth of work, including the new compact index released in Bundler 1.12. In the future, we’re also going to support gems with required Ruby versions in Gemfiles that don’t declare a Ruby requirement. Because of existing features (like the Gemfile Ruby declaration), we’re having to do some mork work so that everything can coexist harmoniously. In the meantime, set a Ruby version and you’ll get the right gem versions to install on your Ruby.

The bundle doctor command

We’ve also added a bundle doctor command, courtesy of [@mistydemeo]. Over time, the doctor command will try to solve common problems. Today, it is capable of detecting gems that have been compiled against libraries that no longer exist. For example, if you use Bundler to install the pg gem and then later run brew upgrade postgres, the gem will stop working. We’ve never had a good way to explain (or even detect) this kind of problem before, and now we’re able to fix it for you automatically.

Add options --add-platform and --remove-platform to the lock command

In the past, the only way to resolve your Gemfile on a new platform (like java or mswin) was to run bundle install on that platform. We’ve added explicit options to the lock command to allow managing platforms. Platforms can be added using bundle lock --add-platform NAME, and platforms can be removed using bundle lock --remove-platform NAME.

This makes it possible to (for example) develop on Windows and deploy to a Unix server. However! (and this is a pretty big however), gems on different platforms can have completely different code. Run your test suite on whatever platform you will use in production—it’s the only way to be sure.

Improved features

Auto-install for bundler/inline

When using bundler/inline, gems are now automatically installed. This makes it ridiculously easy to create and distribute single-file scripts that depend on gems. Highly recommended.

Dramatic resolver optimizations

The resolver has been fine-tuned. It allocates less objects, uses less memory, needs less GC time, and is all-around better. It is now able to find usable Gem versions noticably faster. In many cases, the improvement was about 4x. For one especially dramatic Gemfile, Bundler now runs 100x faster than it did before.

Better faster exec

The new exec command (added in v1.12) switched from always calling exec to calling load instead if possible. In version 1.13 we added a way to turn it off: bundle config exec_disable_load true. We also dramatically improved it process, adding support for JRuby, and setting process titles the same way they used to be set.

Improved usage of the compact index

We launched the compact index in v1.12. In this version, we’ve sped things up by using persistent HTTP for more than one request, fixed printing dots to indicate progress, and added support for legacy gems with capitalized names and users without a home directory.

Experimental features

This version also contains three experimental features, disabled by default: a plugin system, and version locking for Bundler itself.

Experimental plugin system

For a long time now, we’ve supported “command” plugins the same way that git does: if there is a command named bundle-foo, then Bundler will run it when you execute bundle foo. The experimental plugin system builds on top of that, providing a way to create new Bundler commands that hook into the Bundler CLI internals. The plugin system also supports “source” plugins, which means it should be possible to use gems from Subversion, Mercurial, S3, or anything else you can think of. In addition to source plugins, we’ve started adding new “lifecycle” hooks. That means plugins will be able to hook in and run their own code before, during, or after the install or update process.

Experimental Bundler version locking

Someday, Bundler 2.0 is going to break backwards compatibility. When that happens, we’re going to need a way for applications that use Bundler 1.x to keep working. We’re also going to need a way for applications that use Bundler 2.x to work in the first place. As a first step towards that glorious future, we’ve built a feature that allows Bundler to automatically run the version of Bundler locked in the Gemfile.lock. It adds an additional level of complexity, though, so we’ve disabling it by default in this version of Bundler. If you want to opt in, and have Bundler 1.13 automatically download, install, and run an older version of Bundler, here’s how it works:

First, export the environment variable BUNDLE_ENABLE_TRAMPOLINE. In the Bash shell, that means running export BUNDLE_ENABLE_TRAMPOLINE=true. Then, run bundle install and bundle exec as usual. You should notice that Bundler will automatically switch to the version of Bundler that is saved into the Gemfile.lock. To update the version of Bundler saved in the lockfile, run bundle update --bundler. That will overwrite the Bundler version in the lock with the newest version of Bundler installed on your machine.

Experimental conservative updates

bundle update received some new options to support conservative updates: --patch and --minor. “Conservative” meaning it will sort all available versions to prefer the latest patch releases from the current version, then the latest minor releases and then the latest major releases. These aren’t documented or formally supported yet while we allow the community some opportunity to weigh in on how these options should work. Join the discussion and give us your 2 cents so we can lock this in for 1.14. There’s even some outstanding issues you can contribute to!

Feedback for experimental features

These features are a really big deal, and we want to launch them at the same level of polish and stability that you’re used to getting from Bundler. We’ll get there, and when we do these features will be turned on by default. In the meantime, if you’d like to try them out, that would be awesome. We’d love to hear your feedback. <3

How To Upgrade

Run gem install bundler to upgrade to the newest version of Bundler.