hi folks, i've been working with ant 1.2 for a while. i have implemented an ant based development workspace for an iPlanet eCommerce application, taking care of building, deploying and installing all the components of a j2ee application (30K+ source files, including jsps, java, properties, xml, etc.)
while designing an implementing this little monster i've run into some limitations on ant 1.2 and we did some extensions to it. i've finally had some time to download ant 1.4B2 and i've seen that many of the issues have been addressed completely or partially, it took me a couple of hours to port the extensions i did for 1.2 to 1.4B2. from the implementation perspective, all this changes consist on adding one or two new methods to the corresponding class and minor modifications to existing ones to invoke the new ones (in ant 1.2 the changes to get this functionality were much more complex). following you'll find a list of these enhancements with a short description.. i'll be glad to share these improvements and integrate them into the ant code base if you agree so. thxs and regards. alejandro. --------------------------------------------------------------------- list of enhancements: 1* <target>, modified "if" and "unless" attributes 2* <property> task, new "override" attribute 3* <property> task, new "eval" attribute 4* <antcall> task, new "iterate" and "iterator" attributes 5* "*DEFAULT*" target name 6* <ant> task, new "fallbackantfile" attribute 1* <target>, modified "if" and "unless" attributes the value of the if an unless can be a property name (as it is right now in ant) or a property name/value, i.e: <target name="tomcatDeploy" if="server.type=tomcat"> this target will only be executed if "server.type" is defined and and its value is "tomcat" this feature proved to be useful to execute targets depending on properties values. for example depending on the server the developer is deploying to (i.e. information stored in a properties file, server.type=tomcat"). this contribute to reduce the number of entry targets from the developer's perspective, in the given example a single deploy target would invoke all the <SERVER>Deploy targets, only the one matching the developer configuration will be executed. 2* <property> task, new "override" attribute if present and set to true or false, the override attribute, allows to change the value of an existing project property (user properties are not affected). this functionality works with all the flavors of the property task (value, file, etc.) an example for this is when loading global, group specific and developers specific properties files: <property file="config/project.properties"/> <property file="config/${group}.properties" override="yes" /> <property file="config/${machine}/${developer}/${configuration}/user.properties" override="yes" /> this allows groups and developers to override global (default) values. 3* <property> task, new "eval" attribute the eval is a new way of setting a property (as value or file do). it allows to assign to a property the value of other property, where the name of the other property has been resolved in the build file, for example: <property name="jmsHelper.name" value="jmsHelper"/> <property name="jmsHelper.version" value="0015"/> <property name="jdbcHelper.name" value="jdbcHelper"/> <property name="jdbcHelper.version" value="0014"/> <property name="module" value="jmsHelper"/> <property name="module.name" eval="${module}.name"/> <property name="module.version" eval="${module}.version"/> <property name="module.file" value="${module.name}_${module.version}"/> in the case of module.name, first the the eval attribute is resolved to "jmsHelper.name", a property "jmsHelper.name" is looked up and if exists its value is assigned to the module.name property. 4* <antcall> task, new "iterate" and "iterator" attributes it allows to execute the antcall task in a looping way. the iterate attribute contains the list (space separated) to iterate through, the iterator attribute defines the name of the property that will contain the element of the current iteration. for example: <target name="buildModule" if="module"> <echo message="building module ${module}"/> ... </target> <target name="build"> <property name="modules" value="frontend backend reporting"/> <antcall target="buildModule" iterate="${modules}" iterator="module" /> </target> the antcall task will invoke the buildModule target 3 times, each time the value of the iterator variable -module- will be set to "frontend", "backend" and "reporting". 5* "*DEFAULT*" target name if a target in the ant build file is named "*DEFAULT*", it will be invoked if the invoked target does not exist. this provides a mechanism similar to the default in a switch statement. a property named "target.name" will contain the name of the invoked target. <target name="*DEFAULT*" depends="init"> <echo message="Missing target [${target.name}] delegating to custom.xml"/> <ant antfile="custom.xml" target="${target.name}"/> </target> this provides a useful hook to delegate targets to other ant build files without having to know them. 6* <ant> task, new "fallbackantfile" attribute if present, the build file specified in the fallbackantfile attribute will be used if the file specified in the antfile is not found. <target name="buildModule" if="module"> <ant target="build" antfile="${module}/config/buildModule.xml" fallbackantfile="default/config/buildModule.xml"/> </target> the fallbackantfile attribute provides a hook to customize parts of the build process without changing the common build files.