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

Ser*_*nov 3 ant ant-contrib

我在我的ant脚本中使用ant-contrib库,但是我不知道如何使用foreach标签创建固定数量的循环?通过固定的迭代次数,我不是指一些硬编码值,而是指从命令行提供的ant属性.

hal*_*bit 11

以下代码创建一个固定数量为5次迭代的循环:

<target name="example">
    <foreach param="calleeparam" list="0,1,2,3,4" target="callee"/>
</target>
<target name="callee">
    <echo message="${calleeparam}"/>
</target>
Run Code Online (Sandbox Code Playgroud)

它打印

example:
callee:
     [echo] 0
callee:
     [echo] 1
callee:
     [echo] 2
callee:
     [echo] 3
callee:
     [echo] 4
Run Code Online (Sandbox Code Playgroud)

编辑

如果您需要可变数量的迭代,那么您可能希望尝试以下方法之一(它们支持的迭代次数和可读性不同).第一种方法可以处理几次迭代.它使用固定列表,使用正则表达式截断该列表以获得固定数量的字符.

<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>
Run Code Online (Sandbox Code Playgroud)

第二种方法可以处理相当多的迭代:它读取文本文件并替换每个字符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>
Run Code Online (Sandbox Code Playgroud)

第三种方法使用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>
Run Code Online (Sandbox Code Playgroud)

第四种方法不使用,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 &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>
Run Code Online (Sandbox Code Playgroud)


Mar*_*nor 5

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

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

$ ant -Dtimes=3

loop:

dosomething:
     [echo] hello world

dosomething:
     [echo] hello world

dosomething:
     [echo] hello world
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

可以添加额外的"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>
Run Code Online (Sandbox Code Playgroud)