Rake vs NAnt - a real-life example

  • Thread starter Alexey Verkhovsky
  • Start date
A

Alexey Verkhovsky

Is it a good idea to replace some or all of your [N]Ant build with Rake?
I finally decided to find it out, by actually doing it (*)

The story begins with a fairly normal, run of the mill, Nant build for a
NET project, building a fairly normal, run of the mill, enterprise
application. Broadly, the build consists of three parts: database,
compile/test and packaging for deployment. It took me several evenings
(~20 hours total) to reimplement it with Rake and a couple of weeks to
get pretty much everybody in the project to switch over to it.

My conclusion is "Rake rocks", and here is why:

* Our Rake build is a lot smarter about build product dependencies. For
example, if I say 'rake test' and nothing has changed within the ./sql
directory since the last build, the step for recreating the database is
skipped. The same can be done with NAnt, however it would make it a lot
more complex than I would personally be comfortable with (been there
with a 3 kLOC Ant build once). I think that this feature alone saves
about an hour of unproductive time per day across the project. Which
makes it a worthwhile thing right away, and is the main reason why build
users voluntarily use Rake in their development environments instead of
NAnt (I keep both builds alive).

* Even when it has to do everything from scratch, our Rake build is
slightly faster than our NAnt build, despite doing more than NAnt (such
as checking tkmestamps etc). I half-expected it to be somewhat slower,
and was afraid to find it much slower. It turns out that I was wrong.

* Custom tasks are very easy to write. E.g., the source for my csc task
(compiles a FileList of C# sources) is mere 40 lines. Because they are
so easy to write, it is affordable to have all sorts of small nice
touches in the build, such as this method:

# Decides where should the database files be placed
def database_path
return @database_path if @database_path
path = PROPS['database_path']
if path == '%default'
# try to place database on the RAMDrive
if File.exists?('B:/')
path = 'B:\Databases'
else
path = 'C:\Databases'
end
end

mkdir_p path unless File.exists? path
return @database_path = path
end

Doing the same thing in NAnt build is, again, possible, but I would shy
away from the extra complexity in this case.

* Custom tasks for Rake are written in the same language as the build
file itself, require no compilation, and can be included in the build as
easily as "require 'rake_helpers'".

* Ruby syntax is conveniently non-invasive, so it was trivial to give
the aforementioned csc task an interface like this:
csc :eek:ut => TEST_DLL,
:sources => TEST_SOURCES,
:resources => 'src/test/**/EmbeddedResources/**/*',
:references => [APP_DLL, WEB_CONTROLS_DLL,
'tools/nunit/nunit.framework.dll', 'tools/nmock/NMock2.dll',
'lib/log4net/log4net.dll']

* I can use breakpoint.rb anywhere in the build file, custom tasks file
or even Rake sources, therefore it tends to be much easier to
troubleshoot the build problems.

* Since extraction of custom tasks and helper methods into a separate
file is so easy, the build file itself is considerably shorter than
Nant's and mostly deals with target dependencies. Not to mention the
absence of closing XML tags and other such syntactic noise. The end
result is something that conveys the big picture (what is built from
what) much better.

* Finally, the icing on the cake: sh 'tools\nunit.exe ...' prints out a
new dot after every test, rather than writing six lines of dots at once
in the end, as Nant does... :)

Morale: if you cannot have Ruby in production code, you may still find
it useful for project automation and other non-production uses. Speaking
of which, one day I may write about using ActiveRecord as a way to talk
to the database in Watir tests. I am actually doing it, but not enough
to be sure if it really was a good idea yet.

Best regards,
Alexey Verkhovsky

Footnotes:
* My _real_ purpose was adding another .rb file to our CVS, and
eventually world domination (of course).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,052
Latest member
LucyCarper

Latest Threads

Top