« Just switched hosts, some things broken | Main | fat kitty vs mac »
Sunday
Jun112006

making ant easier to deal with using scripts

A major complaint with ant is that it's a purely declarative language, and some build tasks really want to be expressed procedurally. Scott Evans summed this up by saying ant is a hateful language. But when I was tasked with improving the build system, I wanted to work through the hate.
Inspired by dojo, I handled some tricky parts in the OpenLaszlo ant build files by inserting small java-via-javascript script tasks. Our "old" (ant 1.5.1) files had to deal with some bend-over-backwards structures to fake procedural logic, or used <if> tasks from antcontrib. I was dissatisfied with antcontrib because it seemed abandoned, and the bend-over-backwards was hard to read, understand, maintain. The general approach I've taken here is described in the ant manual.

Consider this problem: we want to build a platform-specific installer. The ant 1.5.1/antcontrib build file looked like this:


<if><equals arg1="${build.platform}" arg2="unix"/><then>
<!-- tar up a bunch of stuff -->
....
</then><else><if><equals arg1="${build.platform}" arg2="macosx"/><then>
<ant target="pkg-dev" />
</then><else><if><equals arg1="${build.platform}" arg2="windows"/><then>
<ant target="nsi-dev" />
</then></if></else></if></else></if>

The main problem with this is that it's hard to read the semantics from all of the pointy brackets. I prefer this alternate formation, where we use javascript to just express an if/then/else procedurally:

<script language="javascript"><![CDATA[
var pkgtask = lps.createTask("ant");
if (lps.getProperty("build.platform") == "unix") {
pkgtask.setTarget("pkg-gzfile");
} else if (lps.getProperty("build.platform") == "macosx") {
pkgtask.setTarget("pkg-dev")
} else if (lps.getProperty("build.platform") == "windows") {
pkgtask.setTarget("nsi-dev");
} else {
var f = lps.createTask("fail");
f.setMessage("Unknown OS. Failing.");
f.execute();
}
pkgtask.execute();
]]> </script>

This formulation is, imho, cool. It's using ant's Java api via javascript via rhino via the Apache Bean Scripting Framework to let us express procedural logic procedurally. We can use the ant java api to get access to ant tasks, properties, and targets, but use javascript logic structures to make decisions.

Yes, it's syntactic sugar, but when I'm maintaining a build file of more than 1300 lines, I'll take some sugar if it makes it easier to read, understand, and maintain.

(BTW, it looks like there's a logic problem in my javascript; you'll still get to the final pkgtask.execute() even if you don't know the platform. But no! The else-unknown-platform case creates and executes a fail task, which pops us out of that scope, and we never get to the pkgtask.execute() line.)

(Meta-problem: examples of cases which would benefit from javascript-ificiation instead of built-in ant task composition are by definition very complicated. A small example isn't as compelling as a big one would be, but for the purposes of pedagogy, I'm using a small example.)

Reader Comments (1)

Hi

I read on openlaszlo that you have implemented the rich text editor. Could you please help me on that? I can not put the rich text in my laszlo application. If I can see the code how you did it, it's great.

Thanks in advance. Plz email me to sporemax@yahoo.com.

6.21.2006 at 08:40 PM | Unregistered CommenterAnonymous

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>