alem0lars alem0lars - 5 months ago 11
Java Question

Ant cleanup if not uptodate

In ANT I have a build file with these targets:

INIT <-- CLEAN <-- COMPILE <-- TEST


I would like to keep the build environment clean by removing unnecessary files from previous builds.

The problem is that in the test phase I want to check if test sources are uptodate with test classes, so I don't run tests. To check that I need to compare last build classes with source files, like this:

<uptodate property="tests.unnecessary">
<srcfiles dir="src" includes="**/*.java"/>
<mapper type="glob" from="*.java" to="${build.dir}/classes/*.classes"/>
</uptodate>


So I would like to check if tests are necessary and:

- if they are, clean the classes and re-run compilation and tests;

- if they aren't, don't do anything.

How can I do that?

Answer

Your example of the uptodate task is close - you probably need to tweak the mapper and take care with absolute versus relative paths. Perhaps:

<uptodate property="tests.unnecessary">
    <srcfiles dir="src" includes="**/*.java"/>
    <mapper type="glob" from="*.java" to="../${build.dir}/classes/*.class"/>
</uptodate>

Note the .. in the mapper to= attribute - presumably the build.dir is at the same level in the directory hierarchy as src. Also note that the compiled classes have the extension .class rather than '.classes'.

Once you've run the above, you can use the if/unless attributes of Ant targets to control execution. There are a number of approaches, the most basic might be something like the below. When ant test is run, Ant will determine whether any files are out-of-date, and skip the clean, compile and test if not. Another approach might be to call a series of target invocations from within a single target using the antcall task.

<target name="check" depends="init">
    <uptodate property="tests.unnecessary">
        <srcfiles dir="src" includes="**/*.java"/>
        <mapper type="glob" from="*.java" to="${build.dir}/classes/*.class"/>
    </uptodate>
</target>

<target name="init">
    <echo message="Running init" />
</target>

<target name="clean" depends="check" unless="tests.unnecessary">
    <echo message="Running clean" />
</target>

<target name="compile" depends="clean" unless="tests.unnecessary">
    <echo message="Running compile" />
</target>

<target name="test" depends="compile" unless="tests.unnecessary">
    <echo message="Running test" />
</target>