Skip to content

HOWTO Using the Bundler

ngollan edited this page Jul 20, 2011 · 2 revisions

Migrating a Merb application to Bundler

Also there are other changes to make Merb independent on the Rubygems to allow RIP or other package managers to handle gems. And moving dependency management out of the Framework to the GEMs where it should be!

In order to migrate your current Merb app to the Merb with Bundler you need to do following simple tasks:

  • Install the "bundler" gem
  • Migrate your dependencies.rb to a Gemfile, see below. You can remove dependencies.rb, since it is no longer used.
  • Run bundle install in your application directory, possibly with a --path parameter to install as a separate gemset. This will install all necessary gems and allow you to run Merb with bundle exec merb.
  • You should add c[:kernel_dependencies] = false to your init.rb file. This will disable the old dependency handling and use Bundler exclusively.

Among other things, this also makes the bin/merb in your application unnecessary, since it is just a wrapper script. You can and should run the binary with the proper version for your application, as well as rake, rspec and other tools directly through bundler.

Migration dependencies.rb to Gemfile

  • Create an empty Gemfile in your application root directory
  • Check the examples below and gists 173739 and 177705.

dependencies.rb

merb_gems_version = '1.1'
dependency "merb-core", merb_gems_version
dependency "merb-assets", merb_gems_version
dependency "merb-actionorm", merb_gems_version
dependency "merb-helpers", merb_gems_version
dependency "merb-mailer", merb_gems_version
dependency "merb-auth-core", merb_gems_version
dependency "merb-auth-more", merb_gems_version
dependency "merb-param-protection", merb_gems_version
dependency "merb-exceptions", merb_gems_version
dependency "merb-gen", merb_gems_version
dependency "merb-slices", merb_gems_version
dependency "merb_parts", '0.9.13'
dependency 'merb_has_flash', '1.0'
dependency 'merb_jquery', '0.9.13'
dependency 'merb_messenger', '0.0.1'
dependency 'pk-merb_history', '0.0.2', :require_as => 'merb_history'
dependency 'json', '1.1.9'
dependency 'pg', '0.8.0'
dependency 'sequel', '3.4.0'
dependency 'pk-merb_sequel', '1.0.5', :require_as => 'merb_sequel'
dependency 'geokit'
dependency 'mongrel', '1.1.4', :require_as => nil
dependency 'rmagick', '2.11.0', :require_as => 'RMagick'
dependency 'carrierwave', '0.3.2'
dependency 'rdiscount', '1.3.5'
#dependency 'roman-merb_cucumber', :require_as => nil
dependency 'cucumber', '0.3.97', :require_as => nil
dependency 'webrat', '0.5.1', :require_as => nil
dependency 'nokogiri', '1.3.3', :require_as => nil
dependency 'rspec', '1.2.8', :require_as => nil

Gemfile

merb_gems_version = '1.1'
gem 'merb-core',             merb_gems_version
gem 'merb-assets',           merb_gems_version
gem 'merb-actionorm',        merb_gems_version
gem 'merb-helpers',          merb_gems_version
gem 'merb-mailer',           merb_gems_version
gem 'merb-auth-core',        merb_gems_version
gem 'merb-auth-more',        merb_gems_version
gem 'merb-param-protection', merb_gems_version
gem 'merb-exceptions',       merb_gems_version
gem 'merb-gen',              merb_gems_version
gem 'merb-slices',           merb_gems_version

gem 'merb_parts',            '0.9.13'
gem 'merb_has_flash',        '1.0'
gem 'merb_jquery',           '0.9.13'
gem 'merb_messenger',        '0.0.1'
gem 'pk-merb_history',       '0.0.2', :require => 'merb_history'

gem 'json',                  '1.1.9'
gem 'pg',                    '0.8.0'
gem 'sequel',                '3.4.0'
gem 'pk-merb_sequel',        '1.0.5', :require => 'merb_sequel'
gem 'geokit'
gem 'mongrel',               '1.1.4', :group => :bundle
gem 'rmagick',               '2.11.1', :require => 'RMagick'
gem 'carrierwave',           '0.3.5'
gem 'rdiscount',             '1.3.5'

group :test do
  gem 'cucumber',            '0.3.99'
  gem 'pk-merb_cucumber'
  gem 'webrat',              '0.5.3'
  gem 'nokogiri',            '1.3.3'
  gem 'machinist'
  gem 'faker'
  gem 'rspec',               '1.2.8', :require => 'spec'
end

as a side note if you are having trouble starting up your app and you see erorrs to loading diff. gems you might be running into this problem -- http://yehudakatz.com/2010/04/17/ruby-require-order-problems/ -- simply find out what gem it is and require it before you do your gem includes for everything else. for example I had to do a require 'dm-core' before I loaded do_mysql and other friends

Development: git Repository as Gem Source

Bundler supports getting gems directly from a git repository, which is good for quick integration testing. To use that functionality for merb core gems, use a gemfile like:

source :rubygems

merb_auth_gems_version = "~> 1.0"
dm_gems_version        = "~> 1.1"
do_gems_version        = "~> 0.10"

gem "json_pure", ">= 1.1.7", :require => "json"

git 'file:///scratch/merb-project/merb/', :branch => 'active_support' do
  gem "merb-core"
  gem "merb-action-args"
  gem "merb-assets"
  gem "merb-helpers"
  gem "merb-mailer"
  gem "merb-slices"
  gem "merb-param-protection"
  gem "merb-exceptions"
  gem "merb-gen"
  gem "merb-cache" do
    Merb::Cache.setup do
      register(Merb::Cache::FileStore) unless Merb.cache
    end
  end
end

gem "merb-auth-core",           merb_auth_gems_version
gem "merb-auth-more",           merb_auth_gems_version
gem "merb-auth-slice-password", merb_auth_gems_version

# ... remainder (ORM, other support libs)

Note two important things:

  • Do not specify versions for gems sourced from a git repository. Otherwise, bundler will seem to install right, but fail in interesting ways afterwards.
  • Take care to separate core gems from support gems like the auth family, since not everything merb comes from the same repository.

After updating the repository, you can use the normal bundle update command to use the updated gems. You can also take things further and use either the git block or normal gem declarations depending on the environment you are running, so you don't need to keep different Gemfiles for development and deployment.

Migrating your own slices, plugins

Because I've removed all the dependency handling from the Merb you now need to define your dependencies in the Rake file for your slices or plugins. If you have any statements of dependency 'foo' or dependencies 'foo', 'bar' you just remove these lines and move your dependencies to the Rakefile and rebuild your gem.

This way all plugins and slices dependencies are defined on the Gem level and not on the Framework level. Bundler than handle loading of the gem and requiring the files.

Another thing which should be safe to do is remove any require 'rubygems' from your code.

Don't use :require_as => nil

The modifier used to be the default strategy when you wanted to bundle a gem, but didn't want it to be required by default. This was useful for things like rake tasks and bin libraries.

The bundler gem no longer supports this, as :require_as => nil is the same as not passing the :require_as option at all. This means it will ignore the nil and still require the gem by its name.

You will need to change all references of :require_as => nil to :group => :bundle

For example, the old format (in dependencies.rb):

dependency 'mongrel', '1.1.4', :require_as => nil

Converts to this new format (in Gemfile):

gem 'mongrel', '1.1.4', :group => :bundle