Skip to content

Instantly share code, notes, and snippets.

@basinilya
Last active September 28, 2022 06:41
Show Gist options
  • Select an option

  • Save basinilya/9369e34c737350a6748b519b3037877a to your computer and use it in GitHub Desktop.

Select an option

Save basinilya/9369e34c737350a6748b519b3037877a to your computer and use it in GitHub Desktop.
Apache Ant loops and foreach without ant-contrib
<?xml version="1.0" encoding="utf-8"?>
<project default="x">
<!-- params: -->
<!-- repeat.target the target to repeat -->
<!-- repeat.n the times to repeat -->
<!-- available in repeat.target: -->
<!-- repeat.i current iteration no -->
<property name="repeat.method" value="repeat.recursive" />
<property name="repeat.method" value="repeat.script" />
<property name="repeat.method" value="repeat.predefined" />
<target name="x">
<antcall target="${repeat.method}">
<param name="repeat.target" value="realTarget" />
<param name="repeat.n" value="3" />
</antcall>
</target>
<target name="realTarget">
<antcall target="${repeat.method}">
<param name="repeat.target" value="realTarget2" />
<param name="repeat.n" value="3" />
<param name="parent.repeat.i" value="${repeat.i}" />
</antcall>
</target>
<target name="realTarget2">
<echo message="${parent.repeat.i} ${repeat.i}" />
</target>
<!-- does <antcall/> allowing to override one property using the "propertycopy" trick -->
<!-- see http://ant.apache.org/faq.html#propertyvalue-as-name-for-property -->
<macrodef name="ANT_CALL">
<attribute name="target" />
<attribute name="dstparam" />
<attribute name="srcpropname" />
<element name="elements" implicit="yes" optional="yes" />
<sequential>
<antcall target="@{target}">
<param name="save.repeat.grow" value="${repeat.grow}" />
<!-- reset in case of nested loops -->
<param name="@{dstparam}" value="${@{srcpropname}}" />
<elements />
</antcall>
</sequential>
</macrodef>
<!-- repeat using recursion -->
<target name="repeat.recursive">
<!-- default value -->
<property name="repeat.grow" value="" />
<condition property="repeat.break">
<length string="${repeat.grow}" length="${repeat.n}" />
</condition>
<antcall target="_repeat.recursive" />
</target>
<!-- helper for forbidden recurse self -->
<target name="_repeat.recursive" unless="repeat.break">
<!-- ${len.x}==1,${len.xx}==2, etc. -->
<length property="len.${repeat.grow}" string="${repeat.grow}" />
<ANT_CALL target="${repeat.target}" dstparam="repeat.i" srcpropname="len.${repeat.grow}">
<!-- reset -->
<param name="repeat.grow" value="" />
</ANT_CALL>
<antcall target="repeat.recursive">
<param name="repeat.grow" value="${repeat.grow}x" />
</antcall>
</target>
<target name="repeat.script">
<script language="javascript">
<![CDATA[
for (var i = 0; i < 3; i++) {
var t = project.createTask("antcall");
t.setTarget(project.getProperty("repeat.target"));
var p = t.createParam();
p.setName("repeat.i");
p.setValue(""+i);
t.perform();
}
]]>
</script>
</target>
<!-- repeat using predefined targets -->
<!-- TODO: check ${repeat.n} -->
<target name="repeat.predefined" depends="repeat.0, repeat.1, repeat.2">
</target>
<target name="repeat.0">
<antcall target="${repeat.target}">
<param name="repeat.i" value="0" />
</antcall>
</target>
<target name="repeat.1">
<antcall target="${repeat.target}">
<param name="repeat.i" value="1" />
</antcall>
</target>
<target name="repeat.2">
<antcall target="${repeat.target}">
<param name="repeat.i" value="2" />
</antcall>
</target>
</project>
<?xml version="1.0" encoding="utf-8"?>
<project default="build">
<!-- unzip each archive in a fileset into its own directory -->
<!-- requires ant 1.7 -->
<fileset dir="." id="archives.to.expand">
<include name="*.jar"/>
</fileset>
<!-- number of cycles for our 'foreach' -->
<resourcecount property="count.archives.to.expand">
<fileset refid="archives.to.expand"/>
</resourcecount>
<target name="build">
<antcall target="repeat.recursive">
<param name="repeat.target" value="expand-archive" />
<param name="repeat.n" value="${count.archives.to.expand}" />
</antcall>
</target>
<target name="expand-archive">
<length property="repeat.base1.i" string="x${save.repeat.grow}" />
<resources id="nth.archive">
<last>
<first count="${repeat.base1.i}">
<fileset refid="archives.to.expand"/>
</first>
</last>
</resources>
<pathconvert property="extract.dir" refid="nth.archive">
<!-- replace last dot with underscore -->
<mapper type="regexp" from="(.*)[.](.*)" to="\1_\2" />
</pathconvert>
<delete dir="${extract.dir}"/>
<unzip dest="${extract.dir}">
<resources refid="nth.archive"/>
</unzip>
</target>
<!-- repeat using recursion -->
<target name="repeat.recursive">
<!-- default value -->
<property name="repeat.grow" value="" />
<condition property="repeat.break">
<length string="${repeat.grow}" length="${repeat.n}" />
</condition>
<antcall target="_repeat.recursive" />
</target>
<!-- helper for forbidden recurse self -->
<target name="_repeat.recursive" unless="repeat.break">
<antcall target="${repeat.target}">
<param name="save.repeat.grow" value="${repeat.grow}" />
<!-- reset in case of nested loops -->
<param name="repeat.grow" value="" />
</antcall>
<antcall target="repeat.recursive">
<param name="repeat.grow" value="${repeat.grow}x" />
</antcall>
</target>
</project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment