1 min read

Awesome bundling in Merb 1.0 final

Since we released RC1, people have had persistent issues with bundling Merb gems. It turns out that the most common reason, by far, is conflicts between gems bundled in your app with gems available in your system.

When we first set up bundling, we thought it would be convenient to be able to bundle only some of the dependencies for your application. As it turns out, that blunts the reason for bundling in the first place: hassle-free, write-once-run-anywhere applications.

Through the course of four RCs, we've tried a number of things, none of which were really effective. The only full solution that guarantees that your bundled app runs correctly on development boxes and production boxes is to bundle everything in your app, and completely ignore your system gem repository.

While it is easy enough to mix and match, the number of reports of failure, combined with failures by the core team itself, leads us to believe that this is a bad idea, especially given some of the current assumptions made by Rubygems (which causes it to activate the latest version of a gem, which might conflict with a different dependency).

A simple example of a failure:

  • merb-haml 0.9.12 relies on merb-core 0.9.12
  • Imagine you have merb-core 0.9.13 installed in your system
  • running the merb binary loads the latest merb from all your repositories.
  • this will load merb-core 0.9.13
  • a dependency on merb-haml 0.9.12 will try to activate merb-core 0.9.12, which will conflict with the already loaded 0.9.13.
This is just one example of many issues that people had. The solution is to rely entirely on bundled gems, and remove system gems from bundled binaries.

The side-effect is that you will need to bundle gems like mongrel, rake, etc. But it's clear to me that even bundling mongrel and rake is a good idea, as different versions of mongrel or rake can have subtle differences that lead to infuriating bugs. I personally have experienced some of these bugs in my day, and being able to package up an entire working app would have been a godsend!

RC5, which should be the final release before 1.0 final is released at RubyConf, will include bundle-everything by default, as well as more support for webrat, JRuby, and Windows.