Ant how disable print target name for foreach target - ant

I have code below:
...
<foreach target="each-time-target" param="file">
<fileset dir="${basedir}/target" casesensitive="yes">
<include name="libs/*.jar"/>
</fileset>
</foreach>
...
When I execute it I see in output
each-time-target:
each-time-target:
each-time-target:
....
Is there exists some option to disable target name printing for specific targets?

Use -emacs commandline option, f.e.
ant -emacs -f foobar.xml
see Ant Manual Options for details

Related

Avoid Printing Build Successful after ant exits a target

I have an ant script which calls a target from another script. When this target is fully executed, the second script exits with a "Build Successful" message, which is a bit confusing to the users. I dont want the second ant script to echo "Build Successful" on its exit.
My code is
<target name="startRemoteJboss" description="Starts Remote Instance of Jboss">
<echo message="starting Remote Jboss" />
<sshexec output="remoteJboss.txt" trust="true" host="${jboss.remote.host}" username="${jboss.remote.username}" password="${jboss.remote.password}" command="ant -f build.xml startJboss" port="${jboss.remote.port}" failonerror="no"/>
</target>
The second build file target looks like
<target name="startJboss" description="Starts Jboss">
<echo message="starting Jboss" />
<exec executable="${jboss.home}/bin/run.sh" spawn="true">
<arg line="-b 0.0.0.0 -c default" />
</exec>
<sleep seconds="150" />
<echo message="Jboss is UP" />
</target>
When the startJboss completes it execution, i would like it to not print "Build Successful"
[sshexec] BUILD SUCCESSFUL
[sshexec] Total time: 10 seconds
Since you're capturing the output to a file (<sshexec output="remoteJboss.txt" ...), then you should be able to strip these lines from it, e.g.:
<concat>
<fileset dir="." includes="remoteJboss.txt" />
<filterchain>
<linecontains negate="true">
<contains value="[sshexec] BUILD SUCCESSFUL"/>
</linecontains>
<linecontains negate="true">
<contains value="[sshexec] Total time:"/>
</linecontains>
</filterchain>
</concat>
To printout to the user (assuming you're using concat already), or use the destFile attribute to specify a copy of the output file where these lines are stripped out:
<concat destfile="remoteJboss_short.txt" >
Best practice is to use macrodef for sharing functionality, means make a macrodef of your startJboss target instead of starting another ant instance with new project scope.
This will also avoid the BUILD SUCCESSFUL output.
EDIT
The "BUILD SUCCESSFUL" string comes from ant's DefaultLogger#getBuildSuccessfulMessage(). You may write your own logger that returns an empty string or any other string instead, see ant manual listeners and loggers for details.

Build multiple environments with a single target and single command(Anding -D and property file)

I have to create a single command to create multiple(dev|qa|uat) war/ear.
Something like :
ant -f build.xml -Denv=dev|qa|uat -propertyfile= devProp|qaProp|uatProp
-Dstage.dir=devdir|qadir|uatdir
I already have different properties file, different staging, deploying target for each environment. I also have different .cmd files to build each of them separately.
What I am stuck at is: How do I build them all in one go?
You can use the <subant /> instruction in your target.
Write down a new ant script (namely master.xml), assuming that your original build is in script build.xml, you can have something like:
<target name="build-all">
<subant target="build-prod">
<fileset dir="." includes="build.xml"/>
<propertyset ......../> <!-- properties for the prod build -->
</subant>
<subant target="build-dev">
<fileset dir="." includes="build.xml"/>
<propertyset ......../> <!-- properties for the dev build -->
</subant>
</target>

How to show Assembled Ant Classpath

I'm developing a Java project using Eclipse, and Ant as a build tool. When I run "ant all" from the command line, my project builds without any errors, but on Eclipse I get many compilation errors.
So I thought I'd copy Ant's Classpath onto my Eclipse Project's Build Path.
Is there an Ant task/command to show that? Like "ant just show me your assembled classpath" or something?
If you run Ant with the -verbose and -debug flags, you'll see all gory details of what javac is doing, including the classpath.
I would introduce a task for printing the classpath, and call that task with antcall. The classpath would be given as a parameter to that task.
You can do something like this in your target, so for example
lets say you've defined your classpath as
<path id="project.classpath">
<fileset dir="${SERVER_DEV}/classes">
<include name="*.zip"/>
<include name="*.jar"/>
</fileset>
<pathelement location="${SERVER_DEV}/3rdParty/jre/NT/1.5.0/lib/jsse.jar"/>
</path>
then you can do something like
<target name="compile" depends="init" description="Compiles All Java Sources">
<property name="myclasspath" refid="project.classpath"/>
<echo message="Classpath = ${myclasspath}"/>
<javac ...>
....
</javac>
</target>
It will print out the classpath used to run the specific target

fileset doesn't support the "erroronmissingdir" attribute

I am using ant 1.7, getting following error:
build.xml:55: fileset doesn't support the "erroronmissingdir" attribute
what is the alternative attribute for erroronmissingdir( it is in 1.8) in 1.7
The fileset erroronmissingdir attribute is available since Ant 1.7.1. You must be using an earlier release of 1.7.
The attribute is used to tell the build to silently ignore filesets for which the base dir does not exist at execution time:
<copy todir="tmp">
<fileset dir="foo" erroronmissingdir="false">
<include name="**/*"/>
</fileset>
</copy>
If you do not specify erroronmissingdir="false" (or cannot, because your version of Ant does not support it), then the default result is build failure if the dir foo does not exist.
If you need your build to succeed whether or not the dir exists, and you cannot use the erroronmissingdir attribute, you have some options.
For example, you could specify the base dir of the fileset to be a known-to-exist parent of your target dir, something like this:
<copy todir="tmp">
<fileset dir=".">
<include name="foo/**/*"/>
</fileset>
</copy>
(Note in this case, the copy will now create dir foo in the todir of the copy. You could strip that using a glob mapper.)
Another alternative would be to execute your conditionally available fileset operations in targets, guarded by a condition, e.g.
<available property="foo.available" file="foo"/>
<target name="test" if="foo.available">
<copy todir="tmp">
<fileset dir="foo">
<include name="**/*"/>
</fileset>
</copy>
</target>
Output with ant -v will show:
[available] Unable to find foo to set property foo.available
test: Skipped because property 'foo.available' not set.
BUILD SUCCESSFUL Total time: 0 seconds

How do I pass an argument to an Ant task?

I'm not very good with Ant, but we're using it as a build tool. Right now, we can run "ant test" and it'll run through all the unit tests.
However, I'd love to be able to do something like ant test some_module and have it accept some_module as a parameter, and only test that.
I haven't been able to find how to pass command line args to Ant - any ideas?
One solution might be as follows. (I have a project that does this.)
Have a separate target similar to test with a fileset that restricts the test to one class only. Then pass the name of that class using -D at the ant command line:
ant -Dtest.module=MyClassUnderTest single_test
In the build.xml (highly reduced):
<target name="single_test" depends="compile" description="Run one unit test">
<junit>
<batchtest>
<fileset dir="${test.dir}" includes="**/${test.module}.class" />
</batchtest>
</junit>
</target>
You can also define a property with an optional default value that can be replaced via command line, e.g.
<target name="test">
<property name="moduleName" value="default-module" />
<echo message="Testing Module: ${moduleName}"/>
....
</target>
and run it as:
ant test -DmoduleName=ModuleX
What about using some conditional in your test target and the specifying -Dcondition=true?
<target name="test" depends="_test, _test_if_true>
...
</target>
<target name="_test_if_true" if="condition">
...
</target>
<target name="_test" unless="condition">
...
</target>
Adapted a bit from the ant faq.
You can define a property on commandline when invoking ant:
ant -Dtest.module=mymodulename
Then you can use it as any other ant property:
...
<fileset dir="${test.dir}" includes="**/${test.module}.class" />
...
Have a look at Ant's manual.
I tried the solutions posted here for the very same original question. Yes just use ant -D<arg_name>. THe -D is a "keyword" I guess. I'm no ant expert and have not read the manuals in detail. Then inside the ant XML files can be accessed like: ${arg_name}
For instance you can have an argument name like: arg.myarg, so in XML ${arg.myarg}.
Ant really doesn't have parameters_ for the build file. I can think of a few ways to do this:
Use a special target to specify the tests. You can use the <for/> task from AntContrib to allow you to specify multiple tests. You'll need to download the Ant-Contrib jar file. I recommend placing it inside your project under the `${basedir}/antlib/antcontrib" directory. That way, when others checkout your project, they get the needed Ant-Contrib jar file.
<property name="antlib.dir" value="${basedir}/antlib"/>
<property name="antcontrib.dir" value="${antlib}/antcontrib"/>
<!-- Set up the ant contrib tasks for your use -->
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<fileset dir="${antcontrib.dir}"/>
</classpath>
</taskdef>
<target name="select-test"
description="Select the tests to run"
depends="test-compile"
if="junit-tests">
<for parameter="module"
list="${junit-tests}"
delimiter=" ">
<sequential>
<junit
fork="true"
...>
<batchtest todir="$target/unit-tests">
<fileset dir="${test.destdir}">
<include name="**/#{module}.class"/>
</fileset>
</junit>
</sequential>
</for>
</target>
You cab now run multiple tests like this:
$ ant -D"test-one test-two test-three" select-test
You could try this to access one target at a time. Add these lines to your build.xml file :
<project name="whatever" default="default">
<input message="Please select module:" addproperty="mod" />
<target name="default" depends="${mod}/>
...
</project>
This allows you to enter the module you want to execute and execute that itself instead of running the whole build.xml
You might need to make a few more changes to your build.xml for this to work perfectly.
For the arguments , there is Facility called property. You need to set the property. As in ANT plain arguments is taken as target name.
Lest say you have two modules in your project ModuleX and ModuleY where ModuleX has 2 testcases to run and ModuleY with 10 testcases.
You could do something like this :
ant runTestsOnModule -Dtestmodule="ModuleX"
OR to test all modules by calling
ant tests
<target name="runTestsOnModule">
<antCall target="testcase${testmodule}"/>
</target>'
<! -- run single module -->
<target name="runTestsOnModule">
<antCall target="testcase${testmodule}"/>
</target>
<!--run all tests-->
<target name="tests">
<antcall target="testcaseModuleX">
<antcall target="testCaseModuleY">
</target>
<target name="testcaseModuleX">
..run junit task to call 2 testcase
</target>
<target name="testcaseModuleY">
....run junit task to call 10 testcase
</target>

Resources