So Your Ruby Gem Won't Install, Huh?

I'm one of like three people in the world that does anything with Ruby on Windows, so I run into all kinds of fun things, because everything was written and tested on Linux. Fun, fun. For instance, a pretty common problem I've hit is not being able to install some gem.

Usually it will be some configuration issue or compiler error in code that wasn't quite cross-platform, so I'll need to go in and edit a Makefile and recompile an extension. In some cases, the gem comes with both a native extension and a Ruby wrapper, so all parts need to be installed. Copying them by hand into the proper places is fraught with peril.

I ran into this the other day and beat my head against the wall trying to figure out how to properly install the gem from the local sources that I'd fixed up. First, I tried typing rake, which looks like it should process the Rakefile much like a Makefile. Unfortunately, this spit out an error.

rake aborted!
No such file or directory - git ls-files
somegem.gemspec:19:in ``'
somegem.gemspec:19:in `block in <top (required)>'
somegem.gemspec:5:in `new'
somegem.gemspec:5:in `<top (required)>'
(See full trace by running task with --trace)

Wat. Who is trying to use git? Unpopular though I may be, I don't use git currently, and don't have it installed. So I peek into somegem.gemspec and what do I see?

  s.files = `git ls-files`.split("\n")

Uh, well, okay. A bit weird for it to try to pull in files from git. What weirdo would do this? As it turns out, almost every gem I have (each of which, successfully installed, mind you) has this line in there. Somehow gem is doing some magic with this and interpreting it, itself.

At this point I was able to kind of plot out a potential solution: I would "gem unpack" the somegem.gem file, modify the sources, repack it with "gem build", and do "gem install somegem.gem" to install from the file rather than pulling the source from the server.

This was all going so well until repacking the gem failed with the same git error. Turns out it tries to read the gemspec file, sees the git command, and tries to run it. UGH. But this blog has a happy conclusion, so read on.

I was able to make the gem commands do my bidding, actually. I used the command "gem spec --ruby somegem.gem > somegem.gemspec" to parse the gem file and rewrite it with the file list expanded. Something in there handled the git command; I don't know what, and I don't really care. This puts an expanded file list in the gemspec, so I can now repack it with "gem build" and finally install.



Post a Comment