Adding child elements from script task - ant

I have an ivy:resolve task as a part of my ant script. I also have a script task that does some processing and generates zero or more module descriptors that need to be excluded from the ivy:resolve.
So I need a way for the script task to generate some exclude elements and add them as children to the ivy:resolve task, so that ultimately it ends up with:
<ivy:resolve file="${ivy.file.path}">
<exclude org="generated" module="by a script task" />
<exclude org="generated" module="by a script task" />
<exclude org="generated" module="by a script task" />
</ivy:resolve />

You don't you use ANT properties?
<target name="init">
<script language="javascript"><![CDATA[
project.setProperty("org.to.exclude", "log4j");
project.setProperty("module.to.exclude", "log4j");
]]></script>
</target>
<target name="resolve" depends="init">
<ivy:resolve>
<dependency org="org.apache.cxf" name="cxf-api" rev="2.7.8"/>
<exclude org="${org.to.exclude}" module="${module.to.exclude}" />
</ivy:resolve>
</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>

ant build script don't run on windows using command line

i have written an ant script, which runs ok and generate the .jar file when i use it with eclipse.
But when i use it on command prompt on windows xp, it's shows successfull, but nothing happens. ant is properly configured and also i can run other ant scripts.
here is my build.xml file
<?xml version="1.0"?>
<project name="TaskNodeBundle" basedir=".">
<!-- Sets variables which can later be used. -->
<!-- The value of a property is accessed via ${} -->
<property name="bundlename" value="task-node-bundle" />
<property name="src.dir" location="../src" />
<property name="lib.dir" location="../lib" />
<property name="build.dir" location="/buildoutput" />
<property name="build.dest" location="build/dest" />
<!--
Create a classpath container which can be later used in the ant task
-->
<path id="classpath">
<fileset dir="${lib.dir}/">
<include name="*.jar" />
</fileset>
</path>
<target name="clean">
<delete dir="${build.dir}" />
<delete dir="${build.dest}" />
</target>
<!-- Deletes the existing build directory-->
<target name="mkdir" depends="clean">
<mkdir dir="${build.dest}"/>
</target>
<!-- Compiles the java code -->
<target name="compile" depends="mkdir">
<javac srcdir="${src.dir}" destdir="${build.dest}" classpathref="classpath" />
</target>
<target name="package-bundle" depends="compile" description="Generates the bundle">
<jar destfile="${dist.dir}/${bundlename}.jar">
<fileset dir="${src.dir}">
<include name="**/**.class" />
<include name="**/**.properties"/>
<include name="/META-INF/**.*" />
<include name="/META-INF/spring/**.*" />
</fileset>
</jar>
</target>
</project>
When you execute an ant script from the command line it will execute the first target defined in the build.xml file (in your case clean).
You can specify the target(s) to be executed on the command line
$ ant target1 target2
or define a default target in your build.xml file with the default attribute of the <project> tag:
<project name="TaskNodeBundle" basedir="." default="package-bundle">

Ant not running all targets

I have the following ant file that is not running the targets "prepForDeployment" and "deployToStaging". This task is being run by Jenkins and I'm not getting any build errors when I look at the console output of the test.
<?xml version="1.0" encoding="UTF-8"?>
<project name="deploy" default="runUnitTests" basedir=".">
<description>
Deploys to staging.
</description>
<target name="init">
<taskdef name="mxunittask" classname="org.mxunit.ant.MXUnitAntTask" classpathref="project.classpath" />
<!-- dump the properties -->
<echoproperties prefix="test" />
</target>
<target name="clean" depends="init">
<mkdir dir="${test.junitoutput}" />
</target>
<target name="runUnitTests" depends="init,prepForTests">
<mkdir dir="${test.output.xml}/unit" />
<runTestDirectory directoryName="." excludes=""/>
</target>
<target name="runAllTests" description="Make output directories and run the MXUnit task" depends="init,clean,runUnitTests">
<!-- generate pretty reports -->
<antcall target="junitreport" />
<fail if="tests.bombed" message="Failing the build due to test failures"/>
</target>
<target name="junitreport" depends="init" description="Runs the report without running the tests">
<junitreport todir="${test.junitoutput}">
<fileset dir="${test.output.xml}">
<include name="*.xml" />
</fileset>
<report format="frames" todir="${test.junitoutput}" />
</junitreport>
</target>
<target name="prepForTests">
<!-- just a bunch of replace tasks, runs OK -->
</target>
<target name="prepForDeployment" depends="init">
<replace file="Application.cfc">
<replacetoken>dbcreate="dropcreate"</replacetoken>
<replacevalue>dbcreate="update"</replacevalue>
</replace>
<replace file="Application.cfc">
<replacetoken>logSQL = true</replacetoken>
<replacevalue>logSQL = false</replacevalue>
</replace>
<echo message="Prepping for deployment done." />
</target>
<target name="deployToStaging" depends="prepForDeployment">
<sequential>
<!--copy the files to a temp directory-->
<copy todir="${staging}_temp" overwrite="true">
<!-- -->
</copy>
<!-- delete applicaiton files on staging -->
<delete quiet="true" includeemptydirs="true">
<fileset dir="${staging}" />
</delete>
<!-- copy files from temp dir to application dir -->
<copy todir="${staging}" overwrite="true">
<fileset dir="${staging}_temp" />
</copy>
<!-- remove temp dir -->
<delete quiet="true" includeemptydirs="true">
<fileset dir="${staging}_temp" />
</delete>
</sequential>
<echo message="The files have been copied to staging." />
</target>
<macrodef name="runTestDirectory">
<attribute name="directoryName"/>
<attribute name="excludes" default=""/>
<sequential>
<mxunittask server="${test.server}" port="${test.serverport}" defaultrunner="${test.runner}" outputdir="${test.output.xml}/#{directoryName}" verbose="true" failureproperty="tests.bombed" errorproperty="tests.bombed">
<directory path="${test.dir.location}/#{directoryName}" recurse="true" packageName="${test.cfcpath}.#{directoryName}" componentPath="${test.cfcpath}.#{directoryName}" excludes="#{excludes}" />
</mxunittask>
</sequential>
</macrodef>
</project>
If you're not telling Jenkins to run the prepForDeployment and deployToStaging targets then it won't run them, just the same as when you run Ant on the command line.
If you want those targets to run, add them to the target list under your "Invoke Ant" build step.

How do I "expand" an ant path (accessed with refId=..) to all files in the path except some?

I am trying to get ant4eclipse to work and I have used ant a bit, but not much above a simple scripting language. We have multiple source folders in our Eclipse projects so the example in the ant4eclipse documentation needs adapting:
Currently I have the following:
<target name="build">
<!-- resolve the eclipse output location -->
<getOutputpath property="classes.dir" workspace="${workspace}" projectName="${project.name}" />
<!-- init output location -->
<delete dir="${classes.dir}" />
<mkdir dir="${classes.dir}" />
<!-- resolve the eclipse source location -->
<getSourcepath pathId="source.path" project="." allowMultipleFolders='true'/>
<!-- read the eclipse classpath -->
<getEclipseClasspath pathId="build.classpath"
workspace="${workspace}" projectName="${project.name}" />
<!-- compile -->
<javac destdir="${classes.dir}" classpathref="build.classpath" verbose="false" encoding="iso-8859-1">
<src refid="source.path" />
</javac>
<!-- copy resources from src to bin -->
<copy todir="${classes.dir}" preservelastmodified="true">
<fileset refid="source.path">
<include name="**/*"/>
<!--
patternset refid="not.java.files"/>
-->
</fileset>
</copy>
</target>
The task runs successfully, but I cannot get the to work - it is supposed to copy all non-java files over too to emulate the behaviour of eclipse.
So, I have a pathId named source.path which contains multiple directories, which I somehow needs to massage into something the copy-task like. I have tried nesting which is not valid, and some other wild guesses.
How can I do this - thanks in advance.
You might consider using pathconvert to build a pattern that fileset includes can work with.
<pathconvert pathsep="/**/*," refid="source.path" property="my_fileset_pattern">
<filtermapper>
<replacestring from="${basedir}/" to="" />
</filtermapper>
</pathconvert>
That will populate ${my_fileset_pattern} with a string like:
1/**/*,2/**/*,3
if source.path consisted of the three directories 1, 2, and 3 under the basedir. We're using the pathsep to insert wildcards that will expand to the full set of files later.
The property can now be used to generate a fileset of all the files. Note that an extra trailing /**/* is needed to expand out the last directory in the set. Exclusion can be applied at this point.
<fileset dir="." id="my_fileset" includes="${my_fileset_pattern}/**/*">
<exclude name="**/*.java" />
</fileset>
The copy of all the non-java files then becomes:
<copy todir="${classes.dir}" preservelastmodified="true">
<fileset refid="my_fileset" />
</copy>
That will copy the source files over retaining the source directory structure under todir. If needed, the flatten attribute of the copy task can be set to instead make all the source files copy directly to todir.
Note that the pathconvert example here is for a unix fileseystem, rather than windows. If something portable is needed, then the file.separator property should be used to build up the pattern:
<property name="wildcard" value="${file.separator}**${file.separator}*" />
<pathconvert pathsep="${wildcard}," refid="source.path" property="my_fileset">
...
You could use the foreach task from the ant-contrib library:
<target name="build">
...
<!-- copy resources from src to bin -->
<foreach target="copy.resources" param="resource.dir">
<path refid="source.path"/>
</foreach>
</target>
<target name="copy.resources">
<copy todir="${classes.dir}" preservelastmodified="true">
<fileset dir="${resource.dir}" exclude="**/*.java">
</copy>
</target>
If your source.path contains file paths as well then you could the if task (also from ant-contrib) to prevent attempting to copy files for a file path, e.g.
<target name="copy.resources">
<if>
<available file="${classes.dir}" type="dir"/>
<then>
<copy todir="${classes.dir}" preservelastmodified="true">
<fileset dir="${resource.dir}" exclude="**/*.java">
</copy>
</then>
</if>
</target>

Resources