Merb Dependencies and Bundler: Conquered! (Screencast)

A lot of people have recently been expressing that, in general, they quite enjoy working with Merb. The only real pain (for me as well) has been dealing with all the dependencies. Well, fixing all those shenanigans has been the focus of this past week. I, for one, am quite happy with the new bundling solution that has been released with Merb 1.0.5. Mad props to Yehuda for all the hard work put into this.

The screencast

Alright, so this is the first screencast that I have ever done, so please be forgiving. I started recording way too late so I didn’t bother trying to make the editing perfect or intro screens and all that fun stuff. Also, I didn’t really watch the whole thing from start to end either, so if anything doesn’t make sense, feel free to ask.



I know that I didn’t quite size stuff up well when I recorded (it’s way too small), so I am providing a large (1024×768) video download where everything is visible.

Some extra notes

Alright, there are somethings to note with the new bundler. First, the default generated application does not add merb_datamapper to dependencies.rb. This is actually a dependency that needs to be specified so that it can be bundled (so will do_mysql and do_postgres). To do this, add the following to dependencies.rb

config/dependencies.rb

dependency "merb-exceptions", merb_gems_version
dependency "do_sqlite3",    dm_gems_version
# dependency "do_mysql",    dm_gems_version
# dependency "do_postgres", dm_gems_version

Second, I didn’t explain what thor merb:gem:confirm did. This command is actually run during the merb:gem:install task. What it does is make sure that your bundled environment is sane (this was somewhat demonstrated in the screencast). For example, if you have a bundled gem that requires extlib 0.9.8 and you have another gem that requires extlib 0.9.7, there is obviously a conflict there. The merb:gem:confirm command will also tell you where the culprit gem is required, which is a lot better than the previous error message we had.

Deploying bundled gems

Unfortunately, I didn’t really have time to touch on deploying bundled gems in the screencast, but it is really simple. All there is to do is call thor merb:gem:redeploy when the app is deployed.

If you are using something like Capistrano to deploy your app, there is a bit more to do. Capistrano will keep numerous versions of the application around and setup symlinks to any shared data such as configuration files, logs, etc… Now, you could just go with this and have capistrano run thor merb:gem:redeploy after each deploy, but this could end up taking a while.

The solution is to symlink the directories that bundled gems are expanded to into cap’s shared directory. The following snippet is an example of how this could be done. However, please note that I did not test this at all.

config/deploy.rb

namespace :bundlr do
  task :redeploy_gems, :roles => :app,
       :except => {:no_release => true} do
    run %{
      cd #{release_path} &&
      ln -nfs #{shared_path}/shared/gems/gems
              #{release_path}/gems/gems &&
      ln -nfs #{shared_path}/shared/gems/specifications
              #{release_path}/gems/specifications &&
      thor merb:gem:redeploy
    }
  end
end
 
after "deploy:symlink", "bundlr:redeploy_gems"

(Sorry about the syntax highlighting. I’m not sure how to fix it.)

I hope that all this will be useful. I hope that we’ll hear comments and feedback from everybody so that we can improve everything. You can always reach us on the mailing list or IRC, so be sure to hit us up.


About this entry