Что такое Bundler?


Это менеджер для управления зависимостями gem'ов в ruby приложениях. Эта утилита позволяет легко устанавливать необходимые gem'ы для вашего приложения, при этом вовсе не зависеть от установленных в системе. Если вы использовали Rails для своих разработок, то вы вспомните, как задавали зависимости gem'ов c помощью config.gem в enviroment.rb, Bundler решает эту задачу намного удобнее и проще. Его включили в Rails 3.0 по умолчанию и теперь, именно он используется для управления зависимостями gem’ов в данной версии фреймворка. Эту утилиту можно использовать для любого ruby фреймворка.

Установка


Устанавливаем эту утилиту как любой другой gem:

gem install bundler

Для Rails 3.0 ничего больше делать не нужно, потому как он используется по умолчанию. А для Rails.2.3.x нужно выполнить следующие шаги. C начала добавить ниже приведенный код в boot.rb перед Rails.boot!:

class Rails::Boot
  def run
    load_initializer
    extend_environment
    Rails::Initializer.run(:set_load_path)
  end

  def extend_environment
    Rails::Initializer.class_eval do
      old_load = instance_method(:load_environment)
      define_method(:load_environment) do
        Bundler.require :default, Rails.env
        old_load.bind(self).call
      end
    end
  end
end


Далее создать файл preinitializer.rb в директории config/initializers с содержимым:

begin
  # Require the preresolved locked set of gems.
  require File.expand_path('../../.bundle/environment', __FILE__)
rescue LoadError
  # Fallback on doing the resolve at runtime.
  require "rubygems"
  require "bundler"
  Bundler.setup
end


Конфигурирование


После создании нового Rails приложения в версии 3.0 в корне проекта уже существует файл Gemfile, который является конфигом для Bundler'а. Для версий Rails 2.3.x его нужно создать самому. Для этого нужно перейти в директорию проекта и выполнить команду:

bundle init

В этом файле задаются все необходимые зависимости gem'ов. Рассмотрим какие именно возможности предоставляет данный конфиг файл.

Сперва задается ресурс откуда по умолчанию будут устанавливаться gem'ы:

source 'http://gemcutter.org'

Как уже многие знают ресурс gemcutter.org становится неким стандартом для хранения gem'ов, поэтому при создании конфига именно этот ресурс будет установлен по умолчанию. Но вы легко можете его з��менить допустим на gems.github.com или добавить столько ресурсов сколько вам нужно:

source 'http://gemcutter.org'
source 'http://gems.github.com'
source 'http://gems.rubyforge.org'


Далее уже идет список gem'ом которые нужны для работы приложения:

gem 'will_paginate'
gem 'oauth'
gem 'money'


Здесь нужно отметить, что gem'ы можно объединять в группы и далее устанавливать только определенные группы:

group :development do
  gem 'rspec'
  gem 'populator'
  gem 'faker'
end

group :production do
  gem 'memcache-client'
end


Доступна и другая форма объединения gem'ов в группы:

gem 'rspec', :group => 'development'
gem 'populator', :group => 'development'
gem 'memcache-client', :group => 'production'


По умолчанию все gem'ы включаются в группу default.
Если нужна именно конкретная версия gem'а то можно задать ее номер:

gem "rack", "1.0.1"
gem "rails", ">=2.3.2"


Есть возможность задать имя файла который будет подключен во время подключения библиотеки Bundler'ом. По умолчанию это имя gem'а поэтому в большинстве случаев ничего задавать не нужно. Опция которая позволяет задать имя файла для подключения называется require, используется она следующим способом:

gem 'gchartrb', :require => 'google_chart'

В случае если нужно указать git репозитория для скачивания gem'а то нужно использовать опцию git:

gem 'will_paginate', :git => 'git://github.com/mislav/will_paginate.git'

Использование


Как тока задали все нужные gem'ы, нужно выполнить команду:

bundle install

Эта команда решит все зависимости и установит недостающие gem'ы. При этом если выполнить:

gem list

То вы там не увидите gem'ы которые были установлены с помощью bundler'а. Все установленные gem'ы находится в директории ~/.bundler. Откуда он их и будет подключать.
Посмотреть список установленных gem'ов можно с помощью команды:

bundle show

Если нужный gem уже установлен в системе, то для него будет создана ссылка. После каждого изменения файла Gemfile, нужно выполнить команду install. Папка ~/.bundler не является обязательной, если вы хотите установить gem'ы в другую папку, это легко сделать:

bundle install ./vendor/bundler_gems

Если помните, то в конфиг файле есть возможность включать все gem'ы в группы, так вот при установки можно указать какие группы gem'ов не устанавливать:

bundle install —without test

Допустим зачем устанавливать gem'ы на production server который нужны только для тестирования.
Если gem имеет исполняемые файлы, то их можно запускать след образом:

bundle exec cassandra_helper cassandra

Как только вы закончили разработку приложения, нужно заблокировать изменение Gemfile:

bundle lock

После выполнения данной команды создастся файл Gemfile.lock, который будет содержать все зависимости на основе установленых gem’ов у вас на компьютере. Это делается для того чтоб зафиксировать версии gem’ов при которых приложение работает корректно. Данный файл будет иметь следующий вид:

---
dependencies:
  faker:
    group:
    - :development
    version: ">= 0"
  memcache-client:
    group:
    - :test
    version: ">= 0"
  sqlite3-ruby:
    group:
    - :default
    version: ">= 0"
  oauth:
    group:
    - :default
    version: ">= 0"
specs:
- stomp:
    version: 1.1.4
- populator:
    version: 0.2.5
- json:
    version: 1.2.0
- thrift:
    version: 0.2.0
- thrift_client:
    version: 0.3.3
- rspec:
    version: 1.3.0
- ruby-hmac:
    version: 0.4.0
- oauth:
    version: 0.3.6
hash: 0ac3c8666943a1e2294be2851316d83791479451
sources:
- Rubygems:
    uri: gemcutter.org


При этом если вы измените Gemfile и попробуете выполнить команду install, то установка не будет произведена, так как gem’ы заблокированы. Для того чтоб установить новые gem’ы уже в залоченном состоянии, выполняется команда install с параметром relockinstall stall --relock, выполняется командак л нужно заблокировать изминение:

bundle install --relock

В bundler’е предусмотрена возможность упаковки gem’ов:

bundle pack

После выполнения данной команды в директории vendor/cache будут сохранены все нужные gem’ы, впоследствии чего установка gem’ов будет происходить именно с этой директории. Эта опция будет полезна только для тех у кого нет возможности на production server устанавливать gem’ы с публичных репозиториев.

Вот и все, что я хотел вам рассказать об этой удобной утилите. Попробуйте поработать с ней хотя бы час и я думаю, она вам понравится.