CNK's Blog

Packaging Ruby Code

For the last month or so the LA Ruby Study group has been reading “Building Awesome Command-Line Applications in Ruby”. For the most part it is a pretty good book and I think it makes a good intro book for folks who are new to Ruby, new to programming, and new to Unix. I get the sense that not everyone in the group is enjoying the tour of ‘the Unix way’ as much as I am but perhaps someday they will have reason to need ‘man’ or pipe (‘|’) and will remember that they heard about that in study group.

The examples the author chose - a script to backup MySQL databases and a to do application - are pretty good: small enough to be understood in 5 minutes but with plenty of room to add features, make tweaks, improve things in some small way. I am particularly enjoying the to do app because I haven’t written a command suite before. Judging from dependencies I have see while installing other gems, the thor gem seems to be a more popular then the GLI gem the author chose but I am pretty impressed with the breadth of support GLI’s scaffold created for us. For example the scaffold generates a Rakefile with a nicely tailored task for building Rdoc documentation. Before I found that, I had tried just ‘rdoc todo’ but that tried process every file in the directory - including several that had no reason to be in my Rdocs. I could have read the rdoc docs and figured out how to document only the project fieles I need to, but the generated rake task is a LOT easier - and gave me some examples of parameters I might want to set to customize further.

This week we are discussing how to distribute your code - as a Gem, an RPM, and as source on GitHub. The generated gemspec looks pretty straightforward and the gem builds and installs. And there are instructions on how to distribute opensource gems on and how to run a private gem server if you need to do that.

The author then goes on to repackaging your gem as an RPM using gem2rpm. His instructions seem to work - though these are a bit more concise. The generated RPM spec file looks reasonable - except for the fact that the development/testing dependencies are listed as full on ‘Requires’ when they are not actually needed to run the program. This Stack Overflow post notes the same issue and suggests a patch to gem2rpm but for just a handful of things to make into RPMs, it may be just as satisfactory to remove the development dependencies by hand while you are inspecting the RPM spec file.

A bigger issue is the value it automatically picked up for ‘gemdir’; it is my personal .rvm gemset directory. I wonder what the correct answer should be. If I just need to match where the rubygems installed via RPM expects gems, then I can probably hardcode a guess. But that seems less than ideal. I see that gem2rpm tries to calculate the correct value using:

    %global gemdir %(ruby -rubygems -e 'puts Gem::dir' 2>/dev/null)
    %global geminstdir %{gemdir}/gems/%{gemname}-%{version}

Poking around in the gem2rpm gem README, I found a link to the official packaging guidelines. I’ll have to read that and see if there is an official resolution for this.