I tied together a couple of RubyGem irritations and an idea tonight.

The first is the Hoe problem. Hoe is a gem that helps people write gems. However, it also metastasises, making itself a dependency of those gems in turn. The result is that if you install a gem that was created with Hoe, you end up having to install Hoe. And yet Hoe is useless unless you’re actually developing that gem. Even then, it doesn’t really add anything.

That was historically the case, anyway. RubyGems now has the notion of development dependencies, and newer versions of Hoe are polite enough to use that. As a result, simply installing a Hoe-dependent gem for use won’t install Hoe.

… unless the gem is old, or was created with an old version of Hoe, or depends on a gem which in turn was created with an old version of Hoe. And that turns out to be rather a lot of gems. It’s almost impossible to avoid Hoe.

I admit, it’s not a huge burden to have to install Hoe. But being reminded of the annoyance earlier in the week made me wonder: what if we were to create an empty/stub/null gem that was called Hoe? We could install that instead. The dependency would be satisfied, and we’d never actually have to install Hoe.

The second irritation came to mind because I reinstalled Ubuntu on my laptop last weekend. I preserved my home directory but reinstalled the OS itself from scratch. As a result, I’ve been slowly reinstalling dependencies over the past week as I find them lacking.

I installed Mechanize via apt-get—it depends on Nokogiri, which requires a binary module which in turn depends on a couple of libraries (libxml2 and libxslt, I think). It’s a lot easier to install one package and have the package manager satisfy the dependencies than it is to find the dependencies, install those via the package manager, then install the Ruby library via RubyGems.

However, RubyGems doesn’t know that I’ve installed Mechanize or Nokogiri. If I install a third package via RubyGems that depends on either of those two, I’ll end up installing them again.

Creating a fake gem that would make RubyGems think that it’s already got, say, Nokogiri 1.3.1 installed would prevent RubyGems from building it unnecessarily.

So that’s what I’ve done. I’ve written a small library that extends RubyGems with a gem fake command. It installs an empty gem of the specified name and version, fooling RubyGems into believing that the dependency is satisfied. The default version is 99.0.0—that should be high enough that it will supersede any actually existing gem versions.

You can install it via:

gem install fake-gem

To prevent Hoe from getting installed:

gem fake hoe

To say that Nokogiri 1.3.1 is already installed:

gem fake -v 1.3.1 nokogiri

You can find more information along with the code at GitHub.