I hate XML, a long time ago, I also hated XML, but I also had some free time, and I played with building a build system in Boo. To match NAnt, I called it NUncle.
It never really gotten anywhere, but Georges Benatti has taken the code and created the Boo Build System. I am just taking a look, and it is fairly impressive. It has the concept of tasks and dependencies between them, as well as action that it can perform.
Here is a part of Boobs' own build script:
Task "build boobs", ["build engine", "build extensions"]: bc = Booc( SourcesSet : FileSet("tools/boobs/**/*.boo"), OutputFile : "build/boobs.exe" ) bc.ReferencesSet.Include("build/boobs.engine.dll") bc.ReferencesSet.Include("build/boo.lang.useful.dll") bc.Execute() Task "build engine": Booc( SourcesSet : FileSet("src/boobs.engine/**/*.boo"), OutputFile : "build/boobs.engine.dll", OutputTarget: TargetType.Library ).Execute() Task "build extensions", ["build io.extensions", "build compiler.extensions"] Task "build io.extensions": Booc( SourcesSet : FileSet("src/extensions/boobs.io.extensions/**/*.boo"), OutputFile : "build/boobs.io.extensions.dll", OutputTarget: TargetType.Library ).Execute() Task "build compiler.extensions": bc = Booc( SourcesSet : FileSet("src/extensions/boobs.compiler.extensions/**/*.boo"), OutputFile : "build/boobs.compiler.extensions.dll", OutputTarget : TargetType.Library ) bc.ReferencesSet.Include("build/boobs.io.extensions.dll") bc.Execute()
I don't know about you, but this makes me feel very nice.
The concept is pretty obvious, I feel, and the really nice thing is that extending it is a piece of cake. Here is how you validate dates of two files:
def IsUpToDate(target as string, source as string): return true unless File.Exists(source) return false unless File.Exists(target) targetInfo = FileInfo(target) sourceInfo = FileInfo(source) return targetInfo.LastAccessTimeUtc >= sourceInfo.LastAccessTimeUtc
And its usage:
Cp("source.big", "dest.big") if not IsUpToDate("source.big", "dest.big")
Or, you know what, this is fairly routine, and it comes as part of the standard library for Boobs. Let us create something new, ConditionalCopy:
def ConditionalCp(src as string, dest as string): Cp(src, dest) if not IsUpToDate(src, dest)
Usage should be clear by now, I hope.