property.import task for Ant

I have Ant build scripts that can be run on either Windows or Linux. There are a few properties that need to be set differently, depending on the platform in use. Been using this little snippet for a while now.

import.js

Array.prototype.map = function(f) {
    var a = [];
    for (var i=0; i<this.length; ++i) {
        a.push(f(this[i],i));
    }
    return a;
};
Array.as = function(v) {
    var a = [];
    for (var i=0; i<v.length; ++i) {
        a.push(v[i]);
    }
    return a;
}

var PROPERTY = (function(){
    var t = {};
    var _get = function(k) {
        return project.getProperty(k);
    };
    t.get = _get;
    t.verbose = function(n) {
        n = 1 * n;
        if (0 < n) {
            t.get = function(k) {
                var v = project.getProperty(k);
                self.log("get " + k + " = " + v);
                return v;
            };
        } else {
            t.get = _get;
        }
    };
    t.low = function(s) { var v = t.get(s); return v && v.toLowerCase(); };
    var os_name = t.low("os.name");
    var user_name = t.low("user.name");
    if (os_name.match(/^windows/)) {
        os_name = "win32";
    }
    t.byUser = function(s) {
        return t.get(s + "." + user_name);
    };
    t.byOS = function(s) {
        return t.get(s + "." + os_name);
    };
    t.byPlatform = function(s) {
        return t.get(s + "." + os_name + "." + user_name);
    };
    t.pick = function() {
        return Array.as(arguments).map(function(k){
            var v = t.get(k) || t.byPlatform(k) || t.byUser(k) || t.byOS(k);
            project.setProperty(k,v);
            self.log("set " + k + " = " + v);
            return v;
        });
    };
    return t;
})();

PROPERTY.verbose(attributes.get("verbose"));
PROPERTY.pick(attributes.get("name"));

Task definition from Ant build file:

    <scriptdef
        name        = "property.import"
        language    = "javascript"
        src         = "import.js"
        >
        <attribute name="name" />
        <attribute name="verbose" />
    </scriptdef>

Example contents of build.properties:

nsis.home.win32=c:/Program Files/NSIS
launch4j.home.win32=c:/tools/launch4j
launch4j.home.linux=${user.home}/tools/launch4j

Usage is simple:

    <property.import
        name        = "launch4j.home"
        verbose     = "0"
    />

The property.import task looks for variants of the named property suffixed with user.name, os.name or both. For the above import of launch4j.home the property.import task when run by user “preston” on Windows gets the value from the first of:

launch4j.home.win32.preston
launch4j.home.win32
launch4j.home.preston

This allows checkin of build.properties while picking up appropriate per-user and per-platform property values when run.

blogroll

social