You are viewing a read-only archive of the Blogs.Harvard network. Learn more.
Skip to content

Making Rake create a gem as the default task Rufus

Yet another reason to like Open Source

One thing I can say that I really enjoy about working with an Open Source project rather than commercial software is I can feel free to blog as many details as I want about getting something done in the hopes it helps me remember what I’ve done and perhaps be useful to others. No need to wrack my brains on whether I can or can’t release the information due to NDAs or other stupidity. The only thing holding me back is my laziness to actually say what I’ve done.

Not happy with the current Rakefile

Today, once again I couldn’t come up with a good idea how to start writing the documentation so I ended taking a detour and staring at the Rakefile (It’s pretty much a copy and paste of the Programming Ruby with parameters changed):

require 'rubygems'
Gem::manage_gems
require 'rake/gempackagetask'

spec = Gem::Specification.new do |s|
    s.name       = "openwferu"
    s.version    = "0.9.0"
    s.author     = "John Mettraux"
    s.email      = "john at openwfe dot org"
    s.homepage   = "http://rubyforge.org/projects/openwferu"
    s.platform   = Gem::Platform::RUBY
    s.summary    = "An OpenWFE-compatible workflow engine in Ruby"
    s.files      = FileList["{bin,docs,lib,test}/**/*"].exclude("rdoc").to_a
    s.require_path      = "lib"
    s.autorequire       = "openwferu"
    s.test_file         = "test/runtest.rb"
    s.has_rdoc          = true
    s.extra_rdoc_files  = ['README']
end

Rake::GemPackageTask.new(spec) do |pkg|
    pkg.need_tar = true
end

While the above Rakefile is quite short and is capable of making a gem via rake openwferu-0.9.0.gen I wasn’t happy I had to explicitly type out the name all the time. However, the Pickaxe book stopped at this point so guidance after this stage relied on my own motivation to go find out where I need to look next.

Getting Rake to build the gem easily

When I typed rake I got an error. I understood this to mean that rake had no idea what the default task so just bailed. So my current goal became, learning how to make the default task in a Rakefile create a gem.

I didn’t really know where to start so I flipped through the Rake Documentation and stared at the Rake API docs. After diddling around trying to use the User Guide and Tutorial to get me somewhere (they didn’t) I stared at the API again. This time I focused on the GemPackageTask object and what the heck it was doing. The above Rakefile creates a new instance of GemPackageTask and sends it a block. Okay fair enough. I tried adding a bit of stuff to get the Rakefile to default to building the package but was getting more confused. What was that block doing exactly anyways? I mean, glancing at it I sort of understood it but what was pkg really?

After digging through the source in the API docs (rdoc is really awesome for giving you quick access to the source code like this) I finally realized that the pkg variable is actually a reference to GemPackageTask itself however I couldn’t find need_tar in GemPackageTask. However, if you look at GemPackageTask’s parent PackageTask many of the details became much clearer. PackageTask holds the need_tar attribute which tells PackageTask to create a gzipped tarball.

One other thing that also became clear is that PackageTask also creates 3 extra tasks automatically on instantiation:

  • :package
  • :clobber_package
  • :repackage

What this means is you get the following 3 commands available in rake automagically:

  • rake package
  • rake clobber_package
  • rake repackage

At this point the dim light bulb in my head turns on. I only need to add one lousy line to the Rakefile:

task :default => [:package]

That’s it you say? Yep. That’s it. Now rake will default to creating a package if you type rake. Remember you also have rake package, rake repackage, rake clobber_package AND rake gem. When you create a task, it means you can also call that task from the rake utility by feeding it as a parameter to rake.

Now the Rakefile (gem spec elided) looks like this:

require 'rubygems'
Gem::manage_gems
require 'rake/gempackagetask'

spec = Gem::Specification.new do |s|
  ...
end

task :default => [:package]

Rake::GemPackageTask.new(spec) do |pkg|
    pkg.need_tar = true
end

Nifty, eh?

Cleaning up

Now that I was creating packages on the whim. I really wanted to be sure they got cleaned out so after a little more looking at the Rake documentation I noticed it was only an extra line I needed to add to indicate to the clean task which files I wanted deleted. The clean task is a built-in freebie with Rake however without some prodding on what to delete it won’t do much. I would suggest you be very careful not to setup an expression like CLEAN.include("**/*.rb") unless you’re itching for a rewrite. Here’s what I added above the Gem Specification object.

CLEAN.include(“pkg”)

Now I can type rake clean and it will clean out everything under the directory ‘pkg’ so I can rebuild a gem from scratch without worrying if there’s any cruft lying around. I also decided to modify the default task to rely on :clean as well as :repackage in order to really sure things were being cleaned up (this might be completely unncessary but it works for now). So my final Rakefile is now:

require 'rubygems'
Gem::manage_gems
require 'rake/gempackagetask'

CLEAN.include("pkg")

spec = Gem::Specification.new do |s|
  ...
end

task :default => [:clean, :repackage]

...

After adding only 2 lines, I gained a lot of functionality from this Rakefile. It was all there but heck if I knew it did that. I guess now I know. Later on, I also added unit tests and rdoc generation to the Rakefile but I’ll save that for another post.

Be Sociable, Share!

{ 1 } Comments