Automating bundle exec
Bundler is a program for installing the libraries (i.e. gems) that a Ruby application depends on, in a sandbox. By specifying an application's dependencies with Bundler developers can guarantee that only specific versions of the dependencies are used when the application is running on a user's computer, or when deployed to a web server.
Before I get into the nitty gritty of how it works, here are the quick installation instructions:
$ curl -L https://github.com/gma/bundler-exec/raw/master/bundler-exec.sh > ~/.bundler-exec.sh $ echo "[ -f ~/.bundler-exec.sh ] && source ~/.bundler-exec.sh" >> ~/.bashrc
Read more on the GitHub page.
How bundler-exec works
Once bundler-exec is configured, it replaces a bunch of common Ruby
rspec) with a shell function
- Check whether your current directory is within a bundled project (it
checks for a
Gemfilein your current directory, or one of its parents), and
- Run the command you entered, prefixing it with
bundle execif appropriate.
It does this with the magic of shell aliases (and therefore only works
with Bourne style shells, or shells that support the
Browse the code on GitHub; it's very simple stuff. The full list
of commands that it looks after for you is currently:
You can easily override that list by setting
BUNDLED_COMMANDS in your
~/.bashrc file before
~/.bundler-exec.sh gets loaded, like this:
BUNDLED_COMMANDS="ruby rails" [ -f ~/.bundler-exec.sh ] && source ~/.bundler-exec.sh
If you need to add commands that are in common use, please fork the project, add them to the script, and send me a pull request. Cheers!
To check whether
bundler-exec is configured, check what your shell
will do if you run Ruby. It should tell you that Ruby has been aliased,
$ type ruby ruby is aliased to `run-with-bundler ruby'
What can go wrong if you forget bundle exec?
Remembering to run
bundle exec is a pain, can be easy to forget, and
no end of subtle bugs can occur if you forget it.
Imagine that your project requires version 1.0.0 of a gem, but you've got both 1.0.0 and 1.0.1 installed. It all goes south like this:
- Your shell will find the command that shipped with 1.0.1, and run it.
- The command will load your application code, which calls
- Bundler (quite rightly) complains when it tries to load 1.0.0 and finds that 1.0.1 is "already activated").
Avoid the ball ache, get bundler-exec!
I love feedback and questions — please feel free to get in touch on Mastodon or Twitter, or leave a comment.