ANT:如何读取foreach循环中设置的属性

时间:2011-03-16 12:27:11

标签: ant foreach properties ant-contrib

亲爱的,我目前面临一些问题,需要检索foreach循环中设置的属性的值。也许你们中的一个可以帮助我......

目的是检查自生成相应jar后是否已修改文件夹的一个文件。这样我知道是否必须再次生成jar。 我所做的是使用foreach循环遍历文件夹,如果一个文件与我的测试匹配,则将属性设置为true。

问题是我的循环后我的变量似乎不存在...这是一个简化的代码示例,它有同样的问题:

<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>

此代码的结果是:

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

似乎该变量已正确设置,因为它可以在“setVar”目标中打印,但无法从调用目标中检索值。

我也知道不可能两次为属性赋值。但问题甚至没有发生......如果是这样的话,我可以在分配之前添加对属性值的检查,以确保它尚未初始化...

你对我解决问题的方法有所了解吗?

非常感谢您的帮助:)

5 个答案:

答案 0 :(得分:7)

从ant-contrib而不是<for>尝试<foreach>任务。 <for>任务利用了稍后出现的Ant宏工具。它比旧的<foreach>任务更快,更灵活。使用<for>时,您处于相同的项目上下文中。这意味着循环中设置的属性将在循环外部可见。当然,属性的常规规则适用......你只需要设置一次......除非你使用ant-contrib中的<var>任务来覆盖或取消设置先前设置的属性。

蚂蚁黑客的欢乐啊。

答案 1 :(得分:3)

不确定您的foreach问题,但是您是否可以根据您的要求使用uptodate任务?

答案 2 :(得分:3)

即使我不再需要它了,感谢sudocode,我找到了解决问题的方法。也许它可能对其他人有用......

一位同事谈到了ant-contrib的“antcallback”目标:它允许将一个被调用目标的结果返回给调用目标。通过“for”目标和“antcallback”的组合,我可以做我想做的事情:

<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”包含目录中文件的名称。它被赋予被调用的目标作为参数,其值为“@ {file}”(“@”由于“for”目标实现而必需)。

在主目标的末尾,$ {retValue}包含“setVar”目标设置的第一个值。尝试多次设置时不会抛出任何错误,因此在“setVar”目标中设置变量之前,不必检查变量是否已经实例化。

答案 3 :(得分:1)

<foreach>任务使用与<antcall>相同的逻辑,并且<antcall>调用的目标内设置的任何属性都不具有超出该目标执行范围的范围。 / p>

换句话说,只要该目标的执行完成,您在env.myreturn目标中定义的setVar属性就会丢失。

这种脚本实际上不是Ant的设计目标。 Ant-contrib库试图修补这些洞,但它仍然会弯曲它的形状。

如果您需要编写此类脚本,并希望使用Ant任务来实现它们,请查看Gradle。它是Groovy(用于脚本)和Ant(用于任务)的相当可爱的混合。

答案 4 :(得分:0)

此处的其他方法(<for><var><groovy>properties.put(....)</groovy><property><antcallback>)不适用于ANT 1.9.4,因此我使用了与此类似的文件系统(伪代码):

<target name="outer">
  <for>  <antcall target="inner" />  </for>
  <loadproperties srcfile="tmpfile.properties" />
  <echo message="${outerprop}" />
</target>

  <target name="inner">
    <!-- did not work: -->
    <!--
      <property name="outerprop" value="true" /> 
      <var name="outerprop" value="true" /> 
      <groovy>properties.put('outerprop','true')</groovy>
      <antcallback target="setouterprop" />
    -->
    <echo message="outerprop=true" file="tmpfile.properties" />
  </target>

也许其他方法因我的<antcall>而无效,但我需要它。 (outerprop最初未设置)