Bundle Everything

swrobel

Stefan Wrobel

Posted on August 23, 2023

Bundle Everything

or: how I learned to stop worrying and ditch gemsets for good

tl;dr

If you don't use gemsets and are just interested in my bundler flow, skip to the Bundler workflow section.

Background

In my previous post about switching from rvm to ruby-install and chruby, I mentioned that my primary motivation for switching away from rvm is runaway gemset disk usage:

$ rvm disk-usage gemsets
Gemsets Usage: 5.4G
Enter fullscreen mode Exit fullscreen mode

I'm generally working on a bunch of different ruby projects at once, and like every good rvm user, I would create a new gemset when I started or cloned the project because ... well, that's what you do! But the problem is that there's no straightforward way to eliminate orphan gemsets when rming the project directory, and so you're left with 5.4GB of gemsets and you have no idea whether those are even relevant anymore.

Enter bundler, the tool that seems to become more and more magical with each version. You're probably already using bundler (if you aren't, WHAT?!) but letting it install into rvm's gemset folder hierarchy rather than directly into your project's directory. It's time to change that in just a few easy steps!

Inspired by Ryan McGeary's excellent "Vendor Everything" post from 2011, I set out to come up with my own bundler workflow.

Bundler workflow

I've configured bundler to install gems to my project's vendor/bundle directory. That way, if I remove the project directory, all of the gems that I've installed specifically for it are gone as well. No more hunting down orphaned gemsets.

bundle config --global path vendor/bundle
Enter fullscreen mode Exit fullscreen mode

This tells bundler to install gems to vendor/bundle by default (rather than your global gem store). You can of course always install gems that you need globally (like bundler) by using gem install.

Rails 4+ will generate binstubs for rails, rake and bundle to bin/. With binstubs, you can run bin/rake instead of bundle exec rake, for example. If you want to make it really simple, just add ./bin to the front of your $PATH and your shell will always look there first. To generate binstubs for any other gems, like spring, just run bundle binstub <gemname> and it will create one in bin/ for you.

This is a little bit tricky with chruby because it always puts its gem bin directory at the front of $PATH so you need to add it in an after hook, which isn't officially supported. This is how I accomplished that with my zsh/chruby setup.

You'll also want to add the following line to your .gitignore if it isn't there already:

/vendor/bundle
Enter fullscreen mode Exit fullscreen mode

Bonus points: parallelize bundler

First, make sure you update to bundler >= 1.5.0

If you're using Linux, run nproc. If you're using a Mac, run sysctl -n hw.ncpu. If you're using Windows, then god help you...

Take the output of that command and replace the X below with it. This will tell bundler to always spawn X number of processes to install gems in parallel. Your bundle install runs will be much faster.

bundle config --global jobs X
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
swrobel
Stefan Wrobel

Posted on August 23, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related