Monday, January 23, 2006

Rake NUnit Task

The adoption rate of rake is strongly slowed by the lack of prebuilt tasks. Despite NAnt's flaws, it is attractive to those who need only simple tasks such as compile (solution task) or unit test (nunit task).

I have word from a good source that Jim Weirich is working on a plug-in architecture for Rake that will allow for easy rake task creatioin. With more tasks available the adoption rate will increase.

This is great news; however, you don't have to wait for this architecture to create your own rake tasks. On my current project I wanted to make the rakefile more readable for the developers who were less familiar with rake. One way to accomplish this is to abstract a few variables and a shell execute into a task.

I chose to use NUnit as the example; however, the idea can be applied to any task that is completed by a commandline application (Simian, Devenv.com, etc). The NUnit task requires only the Library value; however, it does allow you to specify optional xml and config information. Adding other commandline switches could be accomplished very easily by following the same model. To use this task all you need to do is save the code to nunittask.rb in the lib folder.
#!/usr/bin/env ruby

require 'rake'
require 'rake/tasklib'

module Rake

class NUnitTask < TaskLib
# Name of the main, top level task. (default is :nunit)
attr_accessor :name, :library, :xml, :path_to_console, :config

# Create an NUnit task named nunit. Default task name is +nunit+.
def initialize(name=:nunit) # :yield: self
@name = name
@path_to_console = "lib/nunit-console.exe"
yield self if block_given?
define
end

# Create the tasks defined by this task lib.
def define
task name do
sh "#{@path_to_console} #{xml} #{config} #{library}"
end
self
end

def xml
"/xml=#{@xml}" if @xml
end

def config
"/config=#{@config}" if @config
end
end
end
Now that you have NUnitTask saved it can be used in your rakefile simply by adding an NUnitTask.
require 'lib/nunittask'
...
Rake::NUnit.new do |nunit|
nunit.library = "foo.dll"
end
You can wrap any commandline task in the exact same way. If you create enough of them, your rakefile reads much more like a specification than a ruby program.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.