Bundler

Bundler manages the dependencies between Ruby gems.

Bundler is a package dependency manager

Bundler provides a consistent environment for Ruby projects by tracking and installing the correct versions of gems needed for a project. Bundler manages the inter-gem dependencies, and selects the best set of gems that meet the version requirements specified in a project’s Gemfile. The Gemfile specifies not only the names and version requirements of gems used in a project, but also the location of public and private gem servers.

For a single project, it doesn’t really matter where Bundler stores the gems downloaded during processing of the Gemfile. But multiple projects on a single machine might have conflicting gem requirements. There are a couple of techniques for managing gems needed across multiple projects.

  • Per project gemsets This is the approach RVM takes. Each project can create a named gemset, and load into the gemset only the versions and gems necessary for a project. RVM hooks on the cd command and adjusts the search path for gems to the named gemset specified in the .rvmrc file for the project. This is conceptually simple, but means that each gemset gets its own copy of gems. RVM stores the named gemset in a way that is usually invisible to git, but if you put Gemfile, Gemfile.lock, and .rvmrc under version control, recreating the gemset is easy.

  • Pile O’ Gems Bundler can be configured to use the per project gemset approach, but bundler is also capable of determing the versions of various gems needed for a project and loading only those versions from a single set of gems used across all projects. In this approach, the single gemset contains all the gems and all the versions needed by all the projects. Bundler stores each project’s list of gem versions in Gemfile.lock and arranges for only those gems to be loaded when they are required by Ruby files.

Bundler can also be configured to create a per project gemset by using the –path option. Typically the path is in the project’s directory structure, so it usually makes sense to put this directory in the .gitignore file.

Of course, just as in the per project gemset technique, put Gemfile and Gemfile.lock under version control. Recreating the project gemset is as easy as with the RVM approach, and the default gemset is isolated from any project dependencies. Think of this as a compromise between the RVM approach and the Pile O’ Gems approach. It is easier to keep a project’s gemset clear of unneeded versions than it is using a single systemwide Pile O’ Gems, but with Bundler doing the setup work, there really isn’t any advantage to the compromise approach beyond making it easy to find versions of gems that are no longer needed in any project.