Dry run mode for Ant (ant -n, ant --dry-run)
January 31, 2013 [Java, Tech, Test Driven]I am working on the problem of writing Ant build files in a test-driven way. One thing I found myself needing was a "dry run" mode, like many Unix tools have. For example, make has the -n or --dry-run option, which shows what it would have done, but doesn't really do it.
Today I found a partial solution to this problem, so that you can at least see which dependencies will be run when you run a particular ant target.
It's an horrific hack, but it's the best I can do at the moment.
We write some code in a <script> tag to hack all the targets in our project (at runtime). We modify the targets so they all have an "unless" attribute, set to a property name of "DRY-RUN". Then we set the "DRY-RUN" property, and execute our target.
Ant prints out the names of all the targets in the dependency chain, even if they are not executed because of an unless attribute.
Note: this code makes use of the Ant <script> script tag, which is an Ant 1.8+ feature. Using JavaScript inside this tag seems to be supported in Oracle, OpenJDK and IBM versions of Java, but is not guaranteed.
<?xml version="1.0" encoding="UTF-8"?>
<project default="build">
<target name="targetA"/>
<target name="targetB" depends="targetA">
<echo message="DON'T RUN ME"/>
</target>
<target name="targetC" depends="targetB"/>
<target name="build" depends="targetB"/>
<target name="dry-run">
<do-dry-run target="build"/>
</target>
<macrodef name="do-dry-run">
<attribute name="target"/>
<sequential>
<script language="javascript"><![CDATA[
var targs = project.getTargets().elements();
while( targs.hasMoreElements() ) {
var targ = targs.nextElement();
targ.setUnless( "DRY.RUN" );
}
project.setProperty( "DRY.RUN", "1" );
project.executeTarget( "@{target}" );
]]></script>
</sequential>
</macrodef>
</project>
Running this build file normally, the tasks in the targets execute, so we can see that the <echo> happens:
$ ant
Buildfile: build.xml
targetA:
targetB:
[echo] DON'T RUN ME
build:
BUILD SUCCESSFUL
Total time: 0 seconds
But when we run the dry-run target, only the target names are printed, and the <echo> task (and any other tasks) don't:
$ ant dry-run Buildfile: build.xml dry-run: targetA: targetB: build: BUILD SUCCESSFUL Total time: 0 seconds
A lot of pain, for a partial implementation of very simple functionality that you'd expect to be a built-in feature? I couldn't possibly comment.
Comments
Andy Balaam 2013-02-01
Hi Russell, yes it is. But, in case others are similarly doomed, I hope this might help them.
Russel Winder 2013-02-01
Isn’t the real problem here that you are using Ant? Perhaps try a modern build tool such as Gradle? (http://www.gradle.org).