Search code examples
antforeachpropertiesant-contrib

ANT: How to read property setted in a foreach loop


Dear, I currently face some problem to retrieve the value of a property setted in a foreach loop. Maybe one of you could help me...

The purpose is to check if one file of a folder has been modified since the corresponding jar has been generated. This way I know if I have to generate the jar again. What I do is to go through the folder with a foreach loop and if one file match my test, set a property to true.

The problem is that my variable doesn't seems to exist after my loop... Here is a simplified code example that has the same problem:

<target name="target">
    <taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${lib.dir}/ant-contrib.jar"></taskdef>
    <foreach target="setVar" param="var" list="a,b"/>
    <echo>myreturn in target: ${env.myreturn}</echo>
    <property name="env.myreturn" value="c"/>
    <echo>myreturn in second: ${env.myreturn}</echo>
</target>
<target name="setVar">
    <property name="env.myreturn" value="${var}"/>
    <echo>myreturn in setVar: ${env.myreturn}</echo>
</target>

The result of this code is:

target:
setVar:
 [echo] myreturn in setVar: a
setVar:
 [echo] myreturn in setVar: b
 [echo] myreturn in target: ${env.myreturn}
 [echo] myreturn in second: c
BUILD SUCCESSFUL

It seems that the variable is correctly set as it could be printed in the "setVar" target but no way to retrieve value from the calling target.

I also know it's not possible to assign a value to a property twice. But the problem doesn't even occurs... When it'll be the case I could add a check on the value of the property before to assign it to be sure it is not already initialized...

Do you have a clue on the way I can solve my problem ???

Many thanks in advance for your help :)


Solution

  • Even if I don't need it anymore thanks to sudocode, I found a solution for my question. Maybe it could be useful for someone else...

    A collegue talked about the "antcallback" target of ant-contrib: it allows to return a result from a called target to the calling one. With a combination of "for" target and "antcallback" it is possible to do what I wanted to do:

    <target name="target">
        <taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${lib.dir}/ant-contrib.jar"></taskdef>
        <for param="file">
            <path>
                <fileset dir="../myDirectory" includes="**/*" />
            </path>
            <sequential>
                <antcallback target="setVar" return="retValue">
                    <param name="file" value="@{file}"/>
                </antcallback>
            </sequential>
        </for>
        <echo>result: ${retValue}</echo>
    </target>
    <target name="setVar">
        <property name="retValue" value="${file}"/>
    </target>
    

    "file" contains the name of the file in the directory. It is given to the called target as parameter with value "@{file}" ('@' necessary due to "for" target implementation).

    At the end of the main target, ${retValue} contains the first value setted by the "setVar" target. No error is thrown when trying to set it multiple times, so it's not necessary to check if variable has already been instantiated before to set it in "setVar" target.