Apache ANT If Else Condition without ANT-Contrib

Sometimes I must make an ANT Build file that will need to work on many different machines, where I cannot be sure of the version or configuration of ANT nor the environment it is running in. This can cause some discomfort when it comes to complex builds involving conditions. The ANT-Contrib library has a convenient If/Else condition but this library is not always installed with ANT or even when it is, the build environment may not be configured to use it. So in either case, I use the following method which, though a little wordy, gets the job done without relying on anything beyond a standard ANT install. The method uses three ANT targets to do the work, one for the <if>, one for the <then> and one for the <else>. As you can see it creates a bit of extra code, but I believe the portability is worth it.

Below the explanation, the example referred to in the post will be made available. Now lets get started.

First Create a target that should do some bit of work based on a condition. Make the target depend on two other targets (here these are “setup” and “fail”), and only allow it to execute if a boolean variable has the right value, using the “if” attribute of the “target” element.

<target name=”go” depends=”setup, fail” if=”allIsWellBool”>
<!– SOME WORK HAPPENS HERE –>
</target>

Next, have one of the dependencies create a boolean property based on the condition. The process is a little convoluted, in that you need to use a <condition> construct that has an <equals> test against text to create a boolean property. For instance, in the example for this post, this dependency target, “setup”, asks for some user input, then checks to see if an empty string was entered. A new boolean property is added based on the test.

<target name=”setup”>
<input message=”Please enter something:” addproperty=”somethingProp”/>

<condition property=”allIsWellBool”>
<not>
<equals arg1=”${somethingProp}” arg2=”” trim=”true”/>
</not>
</condition>
</target>

After this target either there is a new boolean property called “allIsWellBool” or there is not. Subsequent test for this property will pass if the property is there, and true, or fail if it is not.

Finally, create a target to execute if the test fails, the else condition basically. This is done by only allowing it to execute if a boolean variable has the right value again, but this time using the “unless” attribute of the “target” element. In the case of the example for this post, this target will execute unless the “allIsWellBool” exists and is true.

<target name=”fail” depends=”setup” unless=”allIsWellBool”>
<fail message=”You must enter something”/>
</target>

See also that we are adding the dependency for the “setup” target here as well. This is because this target depends on a property that is set in the “setup” target, and “setup” should therefore happen first.

The full source of the example mentioned in this post is below.

<?xml version="1.0" encoding="UTF-8"?>
<!--
    Simple example of how to do an If/Else condition in
    your build file without using the ANT-Contrib libs

    This source code is provided free of charge and placed in the
    public domain. It is not supported by anyone.

    Use this at your own risk.
-->
<project name="Test If Else Condition without ANT-Contrib" default="go">

    <!-- ======================= -->
    <!-- THE START OF THE SCRIPT -->
    <target name="go" depends="setup, fail" if="allIsWellBool">

        <echo message="Great, passed the test, lets do something!"/>
        <!-- SHOULD DO SOMETHING -->

    </target>

    <!-- =================================================== -->
    <!-- SETUP, GETS SOME INPUT THAT WE WILL TEST WITH LATER -->
    <target name="setup">

        <input message="Please enter something: " addproperty="somethingProp"/>

        <!-- SET A BOOLEAN PROPERTY IF WE GOT SOME INPUT  -->
        <condition property="allIsWellBool">
            <not>
                <equals arg1="${somethingProp}" arg2="" trim="true"/>
            </not>
        </condition>
    </target>

    <!-- ============================================ -->
    <!-- FAIL, WE DID NOT GET ANY INPUT FROM THE USER
         THIS DEPENDSON THE SETUP TASK AND WILL
         EXECUTE ONLY IF THE PROPERTY allIsWellBool
         IS FALSE
    -->
    <target name="fail" depends="setup" unless="allIsWellBool">
        <fail message="You must enter something"/>
    </target>

</project>

About these ads

About Jayson
Father, mountain biker, Software developer at a wire service, and also work with the IPTC (iptc.org)

16 Responses to Apache ANT If Else Condition without ANT-Contrib

  1. Thank you for the tip

  2. Jeff Olson says:

    Thanks, exactly what I needed!

    • Jayson says:

      Glad it came in handy for someone else. It seems I did quite a lot of searching, without much luck, when I first needed to do this.

      Thanks for commenting BTW.

  3. rits says:

    Exactly, what I am looking for. Very well explained.
    But following point is not clear to me :

    code is working perfectly fine as described, when I remove the dependency of fail task over setup task.

    Can you please explain in detail, why fail task is dependent over setup.

    • Jayson says:

      Thanks and I hope it helps but I am afraid that I do not understand your question. I just copied the source, I put into the post, out to a build.xml file and ran it and it works fine. Is the source and the explanation out of sync or something?

      j

    • Gerhard says:

      Why the “fail” target depends on “setup”: ant executes dependent tasks before other tasks. So in this case “setup” is executed before “fail”. That’s necessary because fail uses a property named “allIsWellBool” which is declared in the setup target (condition task…). At least I think this is what your question was about.

      @Jayson Thanks for this blog entry. I was just searching for a solution of a problem where an ant task should be executed only if a certain property is set. Well, it’s some kind of incredible that ant doesn’t provide something easier for this situation… but ok, at least it works now. :-)

      • Jayson says:

        Thanks Gerhard, glad it could help someone else (sorry not to reply sooner BTW, was traveling)

  4. Thank you Jayson, saved my day, well presented as well.

  5. Shane says:

    Huge help man. Thanks a ton I was beating my head against a wall with this one. I really appreciate it!

    • Jayson says:

      No prob, it is not exactly intuitive but was necessary for me as well. Now with Maven replacing ANT in most cases, we will beating ourselves up once again figuring these things out. Been finding out that profiles the Assembly plugin are our friends for these sorts of things.

      j

  6. Patryk says:

    I want to use if/else in macro (created with ) so I need to do it without using targets. Any idea?

    • Patryk says:

      I want to use if/else in macro (created with antlib) so I need to do it without using targets. Any idea?

      • Jayson says:

        Sorry I did not respond to this, or even approve it. It was not mailed to me for some reason, or the mail was filtered accidentally. I do not know how to do that actually. I have long since moved from ANT to Maven and have never looked back.

  7. John Ennew says:

    This is brilliant – many thanks – trying to get ant-contrib working was causing actual pain.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: