亲爱的,我目前面临一些问题,需要检索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”目标中打印,但无法从调用目标中检索值。
我也知道不可能两次为属性赋值。但问题甚至没有发生......如果是这样的话,我可以在分配之前添加对属性值的检查,以确保它尚未初始化...
你对我解决问题的方法有所了解吗?
非常感谢您的帮助:)
答案 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
最初未设置)