Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to guarantee that an ant dependency is run only once?

Tags:

ant

My question is similar to avoiding-re-building-prerequisites-in-ant, except that my need doesn't involve created objects, but processes invoked, so the solutions discussed there won't work for me. At least I think so - but I'm new to ant.

My situation is that I'm writing a set of ant targets, and I need the lets-call-it setup target to be executed once and only once, no matter which target is invoked. Here's a greatly simplified example:


    <?xml version="1.0"?>
    <project name="Ant_Test" basedir=".">
      <target name="setup">
        <echo message="In setup" />
      </target>
      <target name="do.several" depends="setup">
        <echo message="In do.several, calling do.first" />
        <antcall target="do.first" />
        <echo message="In do.several, calling do.second" />
        <antcall target="do.second" />
      </target>
      <target name="do.first" depends="setup">
        <echo message="In do.first" />
      </target>
      <target name="do.second" depends="setup">
        <echo message="In do.second" />
      </target>
    </project>

I need setup to be invoked exactly once, regardless of whether do.several, do.first, or do.second are invoked. With my naive attempt above, invoking do.several results in three calls to setup.

I've thought of setting a property (let's call it setup.has.been.invoked), and using that to conditionally invoke setup from within each target, but it appears that property setting is limited to the scope it's done in, so if in setup, I set setup.has.been.invoked to true, that value only exists within setup.

What am I missing? Is there a section of the tutorials or online documentation I've skipped? Any pointers or hints?

like image 296
CPerkins Avatar asked Jan 29 '10 17:01

CPerkins


People also ask

How do I run a specific target in Ant?

To run the ant build file, open up command prompt and navigate to the folder, where the build. xml resides, and then type ant info. You could also type ant instead. Both will work,because info is the default target in the build file.

What does depends mean Ant?

The depend task works by determining which classes are out of date with respect to their source and then removing the class files of any other classes which depend on the out-of-date classes. To determine the class dependencies, the depend task analyzes the class files of all class files passed to it.

Can Ant download dependencies?

In a previous article I stepped through development of an Ant script to build a target JAR file and run unit tests against it. Where we left off, the project depended on the developer manually populating a library directory with JUnit and its dependency.


2 Answers

You should remove the antcalls and add do.first and do.second as dependencies of do.several:

<target name="do.several" depends="setup, do.first, do.second">
</target>

This will make sure, that setup is only called once:

setup:
     [echo] In setup

do.first:
     [echo] In do.first

do.second:
     [echo] In do.second

do.several:

BUILD SUCCESSFUL
Total time: 0 seconds

Documentation says why a property set in setup does not work with antcall:

The called target(s) are run in a new project; be aware that this means properties, references, etc. set by called targets will not persist back to the calling project.

like image 70
Peter Lang Avatar answered Sep 20 '22 06:09

Peter Lang


I just would like to add another possible way to do this.

<target name="setup" unless="setup.already.executed">
    <echo message="In setup" />
    <property name="setup.already.executed" value="x" />
</target>

This way you run it only once and then instantly set the flag that it was already executed once. Also it doesn't break the "depends" part of your code, since it only runs targets if it is possible/necessary, but it doesn't break the execution of the target dependent target.

Also this is the least amount of change in your scripts.

Edit: Explanation of the 'doesn't break the depends part' :

If 'ant do.first do.second' is invoked, it results in setup being called twice even with all targets using setup as a dependency. That would be a problem if setup is doing things like cloning a repo or other time consuming operations. This approach works for both cases - i.e. 'ant do.several' or 'ant do.first do.second' .

like image 44
Mensfeld Avatar answered Sep 19 '22 06:09

Mensfeld