Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ant target calling

Tags:

ant

I would like to call target backup.yes only if the condition is true.

<condition property="directory.found.yes">
<equals arg1="${directory.found}" arg2="true"/>
</condition>

<antcall target="update.backup"/>

Is there any way to do this.

like image 869
jerin john Avatar asked Apr 08 '13 11:04

jerin john


2 Answers

Instead of <antcall/>, do the following:

Imagine you're calling target foo, and you want to do a backup before, but only if that condition exists:

<target name="foo"
    depends="update.backup">
    <..../>
</target>

<target name="update.backup.test">
    <condition property="directory.found.yes">
         <equals arg1="${directory.found}" arg2="true"/>
    </condition>
</target>

<target name="update.backup"
    depends="update.backup.test"
    if="directory.found.yes">
    <.../>
</target>

The problem with <antcall/> is that it is used when the dependency matrix Ant uses is broken, and it's used to force a task to be done before another task is complete. When really abused, you'll end up calling the same task multiple times. I had a project here that literally called each target between 10 to 14 times, and there were over two dozen targets. I rewrote the entire build sans <antcall/> and by using true dependency setup, cut the build time by 75%.

From my experience 90% of <antcall/> is due to poor target dependency management.

Let's say you want to execute target foo. (The target the user wants to really execute), and before foo is called, you want to do your backup, but only if the directory actually exists.

In the above, foo is called. It depends upon update.backaup. The target update.backup is called, but it depends upon update.backup.test which will test whether or not the directory actually exists.

If the directory exists, the if clause on the update.backup task is true, and the task will actually execute. Otherwise, if the directory isn't there, it won't execute.

Note that update.backup first calls any dependencies before it checks whether the property on the if or unless parameter for the target entity is checked. This allows the target to call a test before it attempts to execute.

This is not a mere side effect, but built into the design of Ant. In fact, the Ant Manual on Targets](http://ant.apache.org/manual/targets.html) specifically gives a very similar example:

<target name="myTarget" depends="myTarget.check" if="myTarget.run">
    <echo>Files foo.txt and bar.txt are present.</echo>
</target>

<target name="myTarget.check">
    <condition property="myTarget.run">
        <and>
            <available file="foo.txt"/>
            <available file="bar.txt"/>
        </and>
    </condition>
</target>

And states:

Important: the if and unless attributes only enable or disable the target to which they are attached. They do not control whether or not targets that a conditional target depends upon get executed. In fact, they do not even get evaluated until the target is about to be executed, and all its predecessors have already run.

like image 172
David W. Avatar answered Oct 21 '22 11:10

David W.


You can do the following

In the other target:

<antcall target="update.back">
    <param name="ok" value="${directory.found.yes}"/>
</antcall>

And in the update.backup target:

<target name="update.backup" if="ok">

But I think you can also do the following using the if statement from ant-contrib:

<if>
     <equals arg1="${directory.found.yes}" arg2="true" />
     <then>
           <antcall target="update.back" />
     </then>     
 </if>
like image 23
VirtualTroll Avatar answered Oct 21 '22 12:10

VirtualTroll