【发布时间】:2013-12-14 10:13:09
【问题描述】:
我在我的 ant 脚本中使用 ant-contrib 库,但我不知道如何才能获得固定数量 使用 foreach 标记的循环? 我所说的固定迭代次数并不是指一些硬编码的值,而是从命令行提供的 ant 属性。
【问题讨论】:
标签: ant ant-contrib
我在我的 ant 脚本中使用 ant-contrib 库,但我不知道如何才能获得固定数量 使用 foreach 标记的循环? 我所说的固定迭代次数并不是指一些硬编码的值,而是从命令行提供的 ant 属性。
【问题讨论】:
标签: ant ant-contrib
以下代码创建了一个固定次数为 5 次迭代的循环:
<target name="example">
<foreach param="calleeparam" list="0,1,2,3,4" target="callee"/>
</target>
<target name="callee">
<echo message="${calleeparam}"/>
</target>
打印出来
example:
callee:
[echo] 0
callee:
[echo] 1
callee:
[echo] 2
callee:
[echo] 3
callee:
[echo] 4
编辑
如果您想要可变数量的迭代,那么您可能想尝试以下方法之一(它们支持的迭代数量和可读性不同)。第一种方法可以处理几次迭代。它使用一个固定列表,该列表使用正则表达式截断以获得固定数量的字符。
<target name="example1">
<property name="n" value="17"/>
<property name="maxlist" value="00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19"/>
<propertyregex property="list" input="${maxlist}" regexp="(^.{${n}}.{${n}}.{${n}})" select="\1"/>
<foreach param="calleeparam" list="${list}" target="callee"/>
</target>
第二种方法可以处理相当多的迭代:它读取一个文本文件并将每个字符替换为X, 以形成一个列表,该列表会像前一种方法一样被截断:
<target name="example2">
<property name="n" value="170"/>
<loadfile property="chars" srcfile="${ant.file}"/><!-- some large text file -->
<propertyregex property="maxlist" input="${chars}" regexp="((?:.|[\r\n\t]))" replace="X," global="true"/>
<propertyregex property="list" input="${maxlist}" regexp="(^.{${n}}.{${n}})" select="\1"/>
<foreach param="calleeparam" list="${list}" target="callee"/>
</target>
第三种方法使用 JavaScript 为 foreach 准备列表:
<target name="example3">
<property name="n" value="330"/>
<property name="target" value="callee"/>
<property name="param" value="calleeparam"/>
<script language="javascript">
var list="", n=parseInt(project.getProperty("n"),10);
for (var i = 0; i < n; i++) list += i + ",";
project.setProperty("list", list);
</script>
<foreach param="calleeparam" list="${list}" target="callee"/>
</target>
第四种方法不使用foreach,而是使用JavaScript 使用动态创建的antcalls 对目标进行所需数量的调用:
<target name="example4">
<property name="n" value="3300"/>
<property name="target" value="callee"/>
<property name="param" value="calleeparam"/>
<script language="javascript">
// does n antcall's with iteration number param
var n = parseInt(project.getProperty("n"),10);
for (var i = 0; i < n; i++) {
var t = project.createTask("antcall");
t.setTarget(project.getProperty("target"));
var p = t.createParam();
p.setName(project.getProperty("param"));
p.setValue(""+i);
t.perform();
}
</script>
</target>
【讨论】:
<taskdef resource="net/sf/antcontrib/antcontrib.properties" classpath="/path/to/ant-contrib/ant-contrib-1.0b3.jar"/>
ANT 不是编程语言,我也不是 ant-contrib 的粉丝,我认为它试图改进这个功能......
我的建议是将脚本语言嵌入到您的构建中。 javascript 的优点是它不需要额外的 jar,但我想你会发现 groovy ANT task 非常强大。
$ ant -Dtimes=3
loop:
dosomething:
[echo] hello world
dosomething:
[echo] hello world
dosomething:
[echo] hello world
<project name="demo" default="loop">
<property name="times" value="2"/>
<target name="loop">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>
<groovy>
def count = properties.times.toInteger()
(1..count).each {
ant.ant(target: "dosomething")
}
</groovy>
</target>
<target name="dosomething">
<echo message="hello world"/>
</target>
</project>
可以添加一个额外的“引导”目标来自动安装 groovy jar 依赖项
<target name="bootstrap">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/groovy-all.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.2.1/groovy-all-2.2.1.jar"/>
</target>
【讨论】: