Bundler, a Ruby gem which solves dependency hall for Ruby projects by tracking and installing the exact gems and versions that are needed.

Bundler

Before using Bundler, developer use gem install to get required gems. (#0002 Ruby Gems talks more about how gem command and RubyGems works) The gems installed via gem install command are downloaded to the default installation directory. It is hard to manage and upgrade existing global gems since they are all stored in one place.

gem environment shows environment info. which include the default INSTALLATION DIRECTORY and GEM PATHS. Snippet below is part of gem environment output,

RubyGems Environment:
  - RUBYGEMS VERSION: 2.4.5.1
  - RUBY VERSION: 2.2.3 (2015-08-18 patchlevel 173) [x86_64-linux]
  - INSTALLATION DIRECTORY: /home/li-xinyang/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0
  - RUBY EXECUTABLE: /home/li-xinyang/.rbenv/versions/2.2.3/bin/ruby
  ...

Ruby 2.0 and RubyGems 2.0 both require Bundler 1.3 or above.

To starting using Bundler, all you need is a Gemfile (Gemfile is the filename with no file extension) in project’s root. This file is similar to package.json if you come from Node.js world.

Code snippet below is a sample Gemfile,

source 'https://rubygems.org'

gem 'rails', '4.1'          # v4.1 only
gem 'rack', '>=1.0'         # Greater or equal to v1.0
gem 'nokogiri', '~> 1.6.1'  # Identical to >=1.6.1 and <1.7

Gem version operators are <, >, <=, >=, ~>, =. The meaning of the operators is pretty self-explanatory.

After installing the gem, bundler writes the snapshot of all installed gems and versions to Gemfile.lock file.

Bundler supports gem grouping which allows performing operations on the entire group. For example, you can only download development and test group on local environment.

Use Local Gem/Local Git Gem/Github Gem1

Using a local gem,

gem "foo", :path => "path/to/foo"

Using a local Git controlled gem,

gem 'foo', :git => '/path/to/local/git/repo', :branch => 'my-feature-branch'

Using a Github gem,

gem 'rack', :github => 'rack/rack', :branch => 'master'

Bundler Workflow

  1. Create Gemfile, bundle init
  2. Edit Gemfile as you needed
  3. Install gems, bundle install
  4. Update gems (Optional), bundle update

More detail about the bundle workflow can be found at here.

# Install dependencies specified in Gemfile
bundle install

# Run an executable in bundle
bundle exec gem_name arg

Bundler Setup

bundler.setup configure the load path so all dependencies in Gemfile can be required.2 Using Bundler.require skips repeating a large stack of requirements.

To require all of gems in Gemfile,

require 'bundler/setup'
Bundler.require(:default)

Use :require => 'require/name' for gem has different require name compared to gem name in Gemfile (see code snippet below).

gem 'rack-cache', :require => 'rack/cache'

Bundler Commands

bundle insatll

bundle install, installs all gems specified in Gemfile. Gems will be installed to default system location for gems.3 Password is needed if system gems are stored in root-owned location.

Bundler check vendor/cache before download gems from the sources declared in Gemfile.

--path, specify a different path than the system default and Bundler will remember the value for future installs (info. is stored inside .bundle/config file).

bundle update

bundle update, updates gems to the latest available versions, which ignores the previously installed gems specified in the Gemfile.lock and resolves all the dependencies again.4

bundle package

bundle package, packages all .gem files needed to run the app into vendor/cache.5

bundle exec

bundle exec, executes a command in the context of the bundle, which make all gems specified in Gemfile available to require in Ruby programs. It does NOT require that an executable is available on shell’s $PATH.6

bundle config

bundle config, allows interacting with bundler’s configuration system.

Bundler Create New Gem

Bundler can also be used to create new gem using bundle gem command. Read more about it at offical Bundler documentation.

  1. http://stackoverflow.com/questions/4487948/how-can-i-specify-a-local-gem-in-my-gemfile

  2. http://bundler.io/v1.11/bundler_setup.html

  3. http://bundler.io/v1.2/bundle_install.html

  4. http://bundler.io/v1.2/man/bundle-update.1.html

  5. http://bundler.io/v1.2/man/bundle-package.1.html

  6. http://bundler.io/v1.2/man/bundle-exec.1.html