Skip to content

Phantom Build System Additions

Not long ago Jeremy Skinner created Phantom, a build system for .NET based on the Boo language. Since its creation, I have been following it with interest (and have forked it).

Up until recently despite my interest, I had not had the opportunity or reason to make any modifications to it. However, I have not long started developing a new site and I thought this was the perfect time to make use of it - it is clear that the clean Python-like Boo syntax is far more preferable than XML-based build files. However, it was missing a couple of features I wanted, so I have added them. I thought I'd briefly document them in this post for whoever might find it of interest.

Stop on Error for 'Exec'

Originally, Phantom had one major shortcoming which made it slightly impractical for anything other than really simple scenarios - if an external tool - be it nant or whatever else run through exec - exited with a non-zero exit code, Phantom would happily continue on to the rest of the tasks in the script. What this meant in real life for me is that even when a build error occured, it still went ahead and ran the unit tests and so on. That clearly would not do.

The solution was of course to check the exit code, and bail out of the build process if it was non-zero. This is fine for many (probably most) cases. However, there are stubborn tools out there which insist on returning non-zero codes for perfectly valid reasons - reasons which should not stop the build. To get around this problem, it is now possible to call exec with an option given in the options hash to allow continuing on non-zero exit codes.

Execute external command and fail on non-zero exit code:

exec("whatever.exe", "--args:here")

Execute external command and ignore non-zero exit code:

exec("whatever.exe", "--args:here", { @IgnoreNonZeroExitCode: true })

NUnit Include/Exclude Categories

This is another small tweak to one of the built-in functions. It is possible to run your NUnit tests using the nunit function within your boo script. However, it did not have any method of specifying which categories of test should or should not be run. I have added this feature and it may be used as demonstrated here:

desc "Runs all the tests"
target test, (compile,):
desc "Runs database tests only"
target database_tests, (compile):
    nunit(test_assembly, {@include: "Database"})
desc "Runs all tests excluding database tests"
target database_tests, (compile):
    nunit(test_assembly, {@exclude: "Database"})

Note that include and exclude are mutually exclusive and cannot be used together. For more information, see the NUnit documentation.

Give it a go

If you are looking for a build system which does away with the XML files of nant and so on, take a look at Phantom and see what you think.

Update (2 Jan 2010)

Since writing this, Phantom has been developed further and some changes have occurred affecting the contents of this post. Please see Jeremy's blog entry and the Phantom documentation for full details.

Addendum (24 Aug 2020)

Codehaus, where Boo was hosted, closed down a few years ago. I've updated my Boo link in the introductory paragraph to point to its current location on GitHub, but if you wanted to know more about the closure of Codehaus, check out this article.