Ayende @ Rahien

Refunds available at head office

Introducing Boobs: Boo Build System

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.

Comments

Aaron Erickson
09/21/2007 11:24 PM by
Aaron Erickson

nice... only issue... how do you google for help on boobs without... ahem... throwing all the red flags up on the corp firewall?

Pierre Henri Kuaté
09/22/2007 05:29 AM by
Pierre Henri Kuaté

Damn, somebody has beaten me at the first joke about ... boobs :)

What are the odds of a software being (unintentionally) called like that? Scott Adams would like that.

On a little bit more serious tone: Is it really necessary to add the word "Set" at the end of "SourcesSet" and "ReferencesSet"?

Georges Benatti
09/22/2007 05:43 AM by
Georges Benatti

Hehe,

As a Brazilian, I had no problem choosen that name to the project, but i can't really say that it was unintentional.

In a serious note, if it gets used, may be we should change the name.

Chris Carter
09/22/2007 02:47 PM by
Chris Carter

don't change the name! it's hilarious, I need to be able to put that on my resume and use it in interviews.

Interviewer: "What experience do you have?"

Me:"Boobs"

Interviewer: "Did you say boobs?"

Me:"Yep. I have extensive experience in Boobs, some would even say that I'm an expert"

Njy
09/22/2007 03:12 PM by
Njy

Try this, it's a __very simple Google CSE to start with. Iit's just a beginng, but everyone can contribute ;) !

Georges Benatti
09/22/2007 03:45 PM by
Georges Benatti

Hehehe,

Cool

As a note, there are Tasks, and FileTasks, just like Rake,

so a conditional copy can be done as:

FileTask "targetfilename", ["sourcefilename"] do

Cp("targetfilename", "targetfilename"

Bas Jansen
09/22/2007 04:55 PM by
Bas Jansen

I wondered if the code is right

The definition of the methode is:

def IsUpToDate(target as string, source as string):

and then the it is used like this:

Cp("source.big", "dest.big") if not IsUpToDate("source.big", "dest.big")

Now the first parameter is source so it is a bit confusing, for me.

But it looks nice and it again remembers me that I want to dive in Boo and even in Boops...

Comments have been closed on this topic.