Bundler-Fastupdate - A faster way to update gems with bundler
Bundler is slow. It's not entirely bundler's fault, but there are some assumptions in its design that can cause some serious slowness (which can't be blamed on rubygems). It all boils down to the design decision for bundler to recursively manage all dependencies. (That is, after all, what it is supposed to do.) But in some cases all you want to do is upgrade a given gem without upgrading all of its dependencies ad infinitum. If that gem happens to have a lot of dependencies, you can find yourself watching your screen do needless work for minutes.
The first workaround to this solution is to just bypass bundler for these scenarios:
sudo gem install some_gem && bundle
However, this has two problems: 1) It will always install the new gem even if the latest version is already installed 2) There is no safety net in place to ensure that the latest version of the gem has dependencies which don't match what was previously installed or is otherwise not met in the current system. In either of these cases, you'll need to do the good old fashion bundle update some_gem and let Bundler do its magic.
Bundler + bundler-fastupdate: With this in place, updates will:
grab the first latest spec it finds from sources (rather than consult all sources) – helpful if your gem is located in a private server as it avoids hits to rubygems server
verifies dependencies match and are met (otherwise defaults to normal update
installs the latest version of the requested gem (if not already installed)
updates Gemfile.lock with latest version
gem install bundler-fastupdate
This depends on bundler, of course.
To avoid getting in the way, this installs a bin called bundle-fastupdate. You can, of course, use this as a replacement for bundle, but the intended use is to create an alias so that its use becomes transparent:
Since bundle-fastupdate is an extension of bundle, it does everything bundle does plus one additional new method:
bundle fastupdate some_gem
Does it work?
For us it sure did. We have a Rails::Engine gem with LOTS of dependencies. Updating sites with new versions of that gem would take approximately 83.2 seconds. Worse yet, even if the latest version of the gem was already installed, it still took bundler 63.6 seconds just to update Gemfile.lock.
With fastupdate, however, those times dropped to 6.7s and 1.2s respetively. That's an insanely good improvement, if I do say so!
David McCullars <dmccullars@ePublishing.com>
(C) 2011 ePublishing