antcall in foreach is not executing loop - ant

I want to build couple of projects based on no of .composites by using ant scripts.
i added all the taskref tags,lib path every thing in my build.xml file.
i wrote the following piece of code for the same and i am getting the error
foreach doesn't support the nested "antcall" element.
<target name="createApplicationDAA">
<foreach param="program">
<path>
<fileset dir="${soaProjectName}/Composites" includes="**/*.composite"/>
</path>
<antcall target="createDAA"/>
</foreach>
</target>
<target name="createDAA">
..........
....
</target>
clearly,
my requirement is to create all DAAs by building all the composites by using foreach or for loop in ant script.
can anybody please let me know,where am i doing wrong?

foreach doesn't use nested elements to determine what to run, it takes a target attribute:
<target name="createApplicationDAA">
<foreach param="program" target="createDAA">
<path>
<fileset dir="${soaProjectName}/Composites" includes="**/*.composite"/>
</path>
</foreach>
</target>
<target name="createDAA">
<echo>${program}</echo>
</target>
Alternatively, use <for>, which takes a nested <sequential>
<target name="createApplicationDAA">
<for param="program">
<path>
<fileset dir="${soaProjectName}/Composites" includes="**/*.composite"/>
</path>
<sequential>
<echo>#{program}</echo>
</sequential>
</for>
</target>

Related

using ant read the build.xml ,according to the order written in <include >tag

Here i want to compile/run first ExceuteLeadTest.class and then ExceuteContactTest.class by the ant ..But while exceuting it first it comipling/running ExcecuteContactTest.java/ExceuteContactTest.class
<project>
<target name="run" depends="compile">
<include name="testScript/ExceuteLeadTest.class" />
<include name="testScript/ExceuteContactTest.class" />
</target>
<project>
In Ant you can use the sequential tag to run tasks in order. Normally Ant processes dependencies and runs each only once if they are included repeatedly in depends.
Example
<target name="run" depends="compile">
<sequential>
<antcall target="run1"/>
<antcall target="run2"/>
</sequential>
</target>
<target name="run1" depends="compile">
<!-- however you run the 1st class -->
</target>
<target name="run2" depends="compile">
<!-- however you run the 2nd class -->
</target>

Ant objects and references: what is the scope of a reference's ID?

Seems odd that there is no documentation about it (at least no documentation that I'm aware of; and I'll be happy to stand corrected).
When I do this:
<fileset id="my.fs" dir="..."/>
What is the scope of the ID my.fs?
The entire Ant execution cycle?
The current target (and any target that depends on the current target)?
And, lastly, what happens if multiple threads (spawned using the parallel task) attempt to define filesets with the same ID?
References are visible across the project in which they are defined. For example, if <fileset id="my.fs" dir="..."/> is placed outside any target, it will be visible for all targets in the buildfile. If it is defined in target A, then it will be visible in target B if B depends on A:
Example 1:
<project name="Project1" default="doIt">
<fileset id="my.fs" dir="some_dir"/>
...
<target name="doIt">
<copy todir="some_dir_copy">
<fileset refid="my.fs" /> <!-- this will work -->
</copy>
</target>
</project>
Example 2:
<project name="Project1" default="doIt">
<target name="prepare">
<fileset id="my.fs" dir="some_dir"/>
</target>
<target name="doIt" depends="prepare">
<copy todir="some_dir_copy">
<fileset refid="my.fs" /> <!-- this will work -->
</copy>
</target>
</project>
However, if you are invoking a subproject, e.g. using the ant or antcall tasks, the subproject by default will not inherit the references defined in the parent project (unlike Ant properties). To inherit them, you can set the inheritrefs attribute to true when invoking the subproject:
Example 3:
<project name="Project1" default="doIt">
<target name="doIt">
<fileset id="my.fs" dir="some_dir"/>
<ant antfile="./build.xml" target="run" />
</target>
<target name="run">
<copy todir="some_dir_copy">
<fileset refid="my.fs" /> <!-- this will fail -->
</copy>
</target>
</project>
Example 4:
<project name="Project1" default="doIt">
<target name="doIt">
<fileset id="my.fs" dir="some_dir"/>
<ant antfile="./build.xml" target="run" inheritrefs="true" />
</target>
<target name="run">
<copy todir="some_dir_copy">
<fileset refid="my.fs" /> <!-- this will work -->
</copy>
</target>
</project>
In case you have parallel tasks executing inside a parallel task, and both defined the same reference ID, then depending on the order of execution, the last one to finish will override the other task's reference.
<parallel>
<fileset id="my.fs" dir="some_dir"/>
<fileset id="my.fs" dir="another_dir"/>
</parallel>
...
<target name="doIt">
<copy todir="some_dir_copy">
<fileset refid="my.fs" /> <!-- this may copy either some_dir or another_dir, depending on which parallel task finished last -->
</copy>
</target>

How to fetch files from a directory and execute them parallely 5 at a time

I'm Using to ant to fetch all files in a directory and execute only 5 files parallely and next 5 five again. Already executed file should not be executed again.
<target name="ParallelTest" description="Checking the parallelTest">
<for param="file" >
<path>
<fileset dir="C:/RCBuild3/ofs/bin/prd1">
<include name="*.xml"/>
</fileset>
</path>
<sequential>
<antcall target="parallelexecutoin">
<param name="productfile" value="#{file}"/>
</antcall>
</sequential>
</for>
</target>
<target name="parallelexecutoin">
<exec dir="C:/RCBuild3/ofs/bin/" executable="cmd">
<arg value="/c"/>
<arg value="productupload.bat"/>
<arg value="-fileName"/>
<arg value="${productfile}"/>
</exec>
</target>
The Above code executes sequentially .
Code first:
<fileset dir="C:/RCBuild3/ofs/bin/prd1" id="src.files">
<include name="*.xml"/>
</fileset>
<pathconvert pathsep="," property="file.list" refid="src.files"/>
<for list="${file.list}" delimiter="," param="file" parallel="true" threadCount="5">
<sequential>
<antcall target="parallelexecutoin">
<param name="productfile" value="#{file}"/>
</antcall>
</sequential>
</for>
Explain:
First of all, you prepare a fileset for all the files that need to be processed.
Then, use pathconvert to convert the fileset to a property "file.list" like: filename1.xml,filename2.xml,filename3.xml.
for task's java code (which hides behind your Ant file) will split "file.list" using comma into a List, and loop through the List. For each element in the List, the loop body (sequential part) will run.
parallel tells for task to run the loop body with multiple threads, and threadcount is the maximium number of threads that could be running at the same time.
So with parallel = true and threadcount = 5, is acts exactly as what you described: 5 files a time.

How do I select the first element of a filelist in ant?

How do I take only the first element of an ant <filelist> and also <echo> that filename as a string?
Here's a solution that doesn't require external tasks
<project name="demo" default="run">
<path id="files.path">
<first>
<filelist dir="dir1" files="foo.jar,file1.jar,file2.jar"/>
</first>
</path>
<target name="run">
<pathconvert property="path.output" refid="files.path"/>
<echo message="Output: ${path.output}"/>
</target>
</project>
You will need ant-contrib and the trick used in the code is the fact that properties cannot be changed once they are set.
<for param="file">
<path>
<filelist
id="docfiles"
dir="toto"
files="foo.xml
bar.xml"/>
</path>
<sequential>
<basename property="package" file="#{file}"/>
</sequential>
</for>
<echo>${package}</echo>
EDIT:
An alternative solution is using the break task from Antelope

ant build.xml target to check for debug code

When debugging it's quite common for me to use things such as Zend_Debug and die() in the PHP to locate an issue. Occasionally I forget to take these out before committing my code. So I was wondering...
How do I write an ant build.xml target which checks all the files in my application for specific strings and fails if they have been found?
Basically, I'm after a reverse grep command which fails when it finds a string.
Any ideas?
Also, given my build.xml file looks like this (I've removed most of my targets to make it short), how do I make it work?
I don't know how ant works, so I'm after a 'drop-in' solution or good instructions.
<?xml version="1.0" encoding="UTF-8"?>
<project name="API" default="build" basedir=".">
<property name="source" value="application"/>
<target name="build" depends="prepare,lint,phpcpd,phpdox,phpunit,phpcb"/>
<target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/build/api"/>
</target>
<target name="lint">
<apply executable="php" failonerror="true">
<arg value="-l" />
<fileset dir="${basedir}/${source}">
<include name="**/*.php" />
</fileset>
<fileset dir="${basedir}/tests">
<include name="**/*.php" />
</fileset>
</apply>
</target>
</project>
Within the lint target (after the apply element) add
<fileset id="die-files" dir="${basedir}/${source}">
<include name="**/*.php" />
<contains text="die()"/>
</fileset>
<fail message="The following files contain "die()": ${ant.refid:die-files}">
<condition>
<resourcecount when="greater" count="0" refid="die-files"/>
</condition>
</fail>
If you can use ant-contrib than:
<for param="file">
<path>
<fileset dir="/path/to/application/"/>
</path>
<sequential>
<if>
<contains string="#{file}" substring="bad elements"/>
<then>
<fail>warning! substring is present in directory</fail>
</then>
</if>
</sequential>
</for>

Resources