antconditional-statementstargetantcall

Ant: How to test if a target exist (and call it not if it doesn't)?


I have a set of build files, some of them calling others -- importing them first. End of line builds may have or may not have a specific target (e.g. "copyother"). I want to call it from my main build file if that target is defined within the end-of-line build script. How can I do it?

Part of the calling script:

<!-- Import project-specific libraries and classpath -->
<property name="build.dir" value="${projectDir}/build"/>
<import file="${build.dir}/build_libs.xml"/>

...

<!-- "copyother" is a foreign target, imported in build_libs.xml per project -->
<target name="pre-package" depends="    clean,
                                        init,
                                        compile-src,
                                        copy-src-resources,
                                        copy-app-resources,
                                        copyother,
                                        compile-tests,
                                        run-junit-tests"/>

I do not want every project to define "copyother" target. How can I do a conditional ant call?


Solution

  • I'm guessing you aren't importing the "other" build scripts into your main build.xml. (Because that wouldn't work. Ant treats imports as local.)

    At the same time, you are using depends and not ant/ant call so maybe you are importing them, but one at a time.

    You can't do what you want in native Ant. As you noted testing for a file is easy but a target is not. Especially if that other project isn't loaded yet. You definitely have to write a custom Ant task to accomplish what you want. Two avenues:

    1) Call project.getTargets() and see if your target is there. This involves refactoring your script to use ant/antcall instead of pure depends, but doesn't feel like a hack. Writing a custom Java condition isn't hard and there is an example in the Ant manual.

    2) Add a target to the current project if not already there. The new target would be a no-op. [not sure if this approach works]