6

亲爱的,我目前在检索 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”目标中,但无法从调用目标中检索值。

我也知道不可能为一个属性赋值两次。但问题甚至没有发生......当这种情况发生时,我可以在分配之前添加对属性值的检查以确保它尚未初始化......

你知道我可以解决我的问题的方法吗???

非常感谢您的帮助:)

4

5 回答 5

7

尝试<for>来自 ant-contrib 而不是<foreach>. 该<for>任务利用了后来出现的 Ant 宏工具。<foreach>它比旧任务工作得更快,更灵活。使用<for>. 这意味着在循环中设置的属性将在循环之外可见。当然,适用于属性的正常规则...您只能设置一次...除非您使用<var>ant-contrib 中的任务来覆盖或取消设置以前设置的属性。

啊,蚂蚁黑客的乐趣。

于 2011-03-17T02:12:11.480 回答
3

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.

于 2011-03-22T09:25:13.167 回答
3

不确定您的 foreach 问题,但您不能使用最新任务来满足您的要求吗?

于 2011-03-16T12:43:06.890 回答
1

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

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

这种类型的脚本真的不是 Ant 的设计目的。Ant-contrib 库试图修补这些漏洞,但它仍在弯曲变形。

如果您需要编写这样的脚本,并且想使用 Ant 任务来实现它们,请改用Gradle。它是 Groovy(用于脚本)和 Ant(用于任务)的完美结合。

于 2011-03-16T12:34:37.970 回答
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最初未设置)

于 2017-11-10T12:41:43.023 回答