使用固定数量的迭代迭代for循环

时间:2013-11-28 11:29:58

标签: ant ant-contrib

我在我的蚂蚁脚本中使用ant-contrib库,但是我不知道怎样才能获得固定数量 使用foreach标签的​​循环? 通过固定的迭代次数,我不是指一些硬编码值,而是指从命令行提供的ant属性。

2 个答案:

答案 0 :(得分:11)

以下代码创建一个固定数量为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 &lt; n; i++) list += i + ",";  
    project.setProperty("list", list);
    </script>
    <foreach param="calleeparam" list="${list}" target="callee"/>
</target>

第四种方法不使用foreach,而是使用JavaScript通过动态创建的antcall s对目标执行所需的调用量:

<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 &lt; 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>

答案 1 :(得分:5)

ANT不是一种编程语言而且我不是ant-contrib的粉丝,我认为它试图改进这个功能......

我的建议是在您的构建中嵌入脚本语言。 javascript的优点是它不需要额外的罐子,但我想你会发现groovy ANT task非常强大。

实施例

$ ant -Dtimes=3

loop:

dosomething:
     [echo] hello world

dosomething:
     [echo] hello world

dosomething:
     [echo] hello world

的build.xml

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

可以添加额外的“bootstrap”目标来自动安装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>