HOWTO Using the 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 aGemfile
, see below. You can removedependencies.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 withbundle exec merb
. - You should add
c[:kernel_dependencies] = false
to yourinit.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.
- Create an empty Gemfile in your application root directory
- Check the examples below and gists 173739 and 177705.
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
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
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.
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.
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