Avoid Printing Build Successful after ant exits a target - ant

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.

Related

Retry task on exec task in Ant gives incorrect resultproperty

I have a piece of code in my ant build.xml
<retry retrycount="10" retrydelay="30000">
<exec executable="${env.M2_HOME}/bin/mvn.cmd" output="#{log}" failonerror="true" resultproperty="res" timeout="#{timeoutmillis}" errorproperty="error">
...
</exec>
</retry>
<echo message="${res}"/>
I retry my cmd task if if fails once upto 10 times. But even if it were to succeed after retrying a few turns, the value returned in res is 1 even though it is a build success. I expect it to be 0 as if it was SUCCESS.
Properties in Ant are immutable (they're not variables), so even if your exec task eventually succeeds, the result property will have already been set to whatever it got from the first run.
You can get past this by creating a sequential block and using the local task inside it to control your property scope.
<retry retrycount="10">
<sequential>
<local name="do.fail" />
<input addproperty="do.fail" validargs="y,n" message="fail?" />
<fail>
<condition>
<equals arg1="${do.fail}" arg2="y" />
</condition>
</fail>
</sequential>
</retry>
Running the above example will prompt the user until "n" is provided as input (or 10 retries).
This is not a direct answer to the question I asked. But taking into consideration what CAustin and jdpjamesp said, I'm reading the content of my output log to see whether the command failed or not.
The cmd will return 1 even if it passed after some n number of failures. But the output log in case of mvn will have "BUILD SUCCESS" only if the command passes at the end. So searching for this string works for me. The log should not be appended after every time though.
So I implemented this-
<property name="pass.string" value="BUILD SUCCESS" />
<resourcecount property="pass.string.count">
<fileset id="matches" file="#{log}">
<contains text="${pass.string}" />
</fileset>
</resourcecount>
<if>
<equals arg1="${pass.string.count}" arg2="0" />
<then>
..
</then>
<else>
..
</else>
</if>

Ant Successful even when Ant Task fails

There must be a simple setting I am missing so forgive me, but I've noticed on two occasions that my bad ant tasks do not cause the build to fail. For example:
Ant copy when source file does not exist ... BUILD SUCCESSFUL
Ant unzip, when task reports "can't write file" or similar message ... BUILD SUCCESSFUL
Ant exec error, invalid syntax ... BUILD SUCCESSFUL
How do I guarantee all ant task errors will result in a build failure?
<EXEC> tasks do no fail by default. You need to enable this with failonerror="true"
Failure of the Ant <COPY> task depends on what resource collection type is used. If you use a fileset or patternset, then all missing files are silently ignored. You can force a failure only by using the filelist type or the parameterized 'file` attribute is used.
Therefore what you want to use is either:
<copy todir="my_dir" file="foo" />
<copy todir="my_dir" flatten="true">
<filelist dir="" files="foo" />
</copy>
<copy todir="my_dir" flatten="true">
<filelist dir="">
<file name="foo" />
<file name="bar" />
<file name="zed" />
</filelist>
</copy>
Have you tried following:
<copy todir="your/path/details" failonerror="true">
</copy>
<zip destfile="your/path/details" whenempty="fail">
</zip>
<exec executable="your/path/details" failonerror="true">
</exec>

what's meaning of Ant exec Result:128

my ant was stoped when execute "<exec excultable="c:\myExe.exe"/>",the result code is just "<message priority="error"><![CDATA[Result: 128]]></message>".I don't know what's meaning of that.
I've tried to search some info like: error code 128---no such exe file,but I havn't.
some one could help me to explain what's the meaning?
Thanks
Oh sorry.
More info:
<macrodef name="gtest-layer-macro">
<attribute name="execfile"/>
<attribute name="layerpath" default=""/>
<attribute name="outputDir" default="${basedir}/${reports}/gtest"/>
<attribute name="reportfile" default="#{outputDir}/gtest_report.xml"/>
<sequential>
<check-layer-path layerpath="#{layerpath}"/>
<if>
<and>
<length string="#{execfile}" when="gt" length="0" trim="true"/>
<available file="#{execfile}"/>
</and>
<then>
<var name="##report.dir##" unset="true"/>
<dirname property="##report.dir##" file="#{reportfile}"/>
<mkdir dir="${##report.dir##}"/>
<exec executable="#{execfile}">
<arg value="--gtest_output="xml:#{reportfile}""/>
</exec>
</then>
</if>
</sequential>
</macrodef>
When I run the <exec>, there’s "error Result:128".
The “#{execfile}” is a gtest.exe file(a exe file to test a module),it could run correctly when I double-click it,it could print the unit test result in the console;Run in the CMD with “--gtest_output="xml:#{reportfile}"” is also could print the unit test result in the console,and output a unit test report(a .xml file).And I have changed another .exe instead of the “gtest.exe”,it’s right too.
So,I don’t know where I’m wrong.
An [exec] Result:128 is a process that can't be found/doesn't exist. At least this is what I've found out from my Ant target to kill any remaining processes at the end of certain tests. I get that result when the process I want to kill isn't running. My build log output looks like this;
[shutdown.server] exec
[13:45:33][exec] ERROR: The process "firefox.exe" not found.
[13:45:34][exec] Result: 128
So if that result is from the execution of your .exe then I'd check the path to ensure the exe is available.

ant script not expanding property value in exec arguments

i have an ant script as shown below:
<project name="nightly_build" default="main" basedir="checkout">
<target name="init">
<exec executable="C:/Work/Searchversion.exe"/>
<property file="initial.properties"/>
<property file="C:/Work/lastestbuild.properties"/>
<tstamp>
<format property="suffix" pattern="yyyyMMddHHmmss"/>
</tstamp>
</target>
<target name="main" depends="init">
<exec executable="C:/Program Files/True Blue Software/SnapshotCM/wco.exe">
<arg line='-h sinsscm01.sin.ds.net -S"/mobile/6.70_Extensions/6.70.102/ANT_SASE_RELEASE_${Version_Number}" /'/>
</exec>
</target>
</project>
i created the above script to replicate a command: wco -h sinsscm01.sin.ds.net -S"/mobile/6.70_Extensions/6.70.102/ANT_SASE_RELEASE_6.70.102.014" /
and 6.70.102.014 is found inside latestbuild.properties file in the form of:
Version_Number = 6.70.102.014
and this latestbuild.properties file is obtained when i execute C:/Work/Searchversion.exe
but when i execute this ant script using cruisecontrol, in my log file,
[Thread-24] INFO ScriptRunner - [exec] Cannot open snapshot 'sinsscm01.sin.ds.jdsu.net:/mobile/6.70_Extensions/6.70.102/ANT_SASE_RELEASE_${Version_Number}': No such snapshot
where ${Version_Number} should have been 6.70.102.014
How do i tackle this issue?
EDIT 1:
after trial and error and substituting with a built in property ${ant.version}, i realise that my property file could be loaded in correctly over here. can anyone point out my mistake? i dont see anything wrong though
EDIT 2:
Just additional infomation... This is actually a delegate ant script for cruisecontrol(used to perform nightly build). Here is my config.xml file for per minute build:
<cruisecontrol>
<project name="dms" buildafterfailed="true">
<listeners>
<currentbuildstatuslistener file = "logs/dms/status.txt"/>
</listeners>
<bootstrappers>
</bootstrappers>
<modificationset quietperiod="60">
<alwaysbuild/>
</modificationset>
<schedule interval="60">
<ant buildfile="nightly_build.xml" target="main"/>
</schedule>
<log dir="logs/dms">
<merge dir="checkout/dms/build/test-results" />
</log>
<publishers>
</publishers>
</project>
</cruisecontrol>
should properties file be loaded in config.xml?
Try breaking your arguments to wco.exe into separate child elements like this:
<exec executable="C:/Program Files/True Blue Software/SnapshotCM/wco.exe">
<arg value="-h" />
<arg value="sinsscm01.sin.ds.net" />
<arg value="-S" />
<arg value="/mobile/6.70_Extensions/6.70.102/ANT_SASE_RELEASE_${Version_Number}" />
<arg value="/" />
</exec>
I think ant isn't expanding ${Version_Number} because it is inside ' "..." ' in the version you posted.
As mentioned in the docs for <exec> you should avoid use of the <arg line=...> form.
You could add assertions in your init target that the required properties file exists and that the property is defined. For example:
<property name="version.file" value="C:/Work/lastestbuild.properties"/>
<available file="${version.file}" property="version.file.available"/>
<fail unless="version.file.available" message="file [${version.file}] is not available"/>
<property file="${version.file}"/>
<fail unless="version" message="property [version] is not defined"/>
<echo message="version: ${version}"/>
I think that will help you spot that the file does not exist.
I took a look at your other question about this script you're putting together. In the code which writes the version number to file, you use filename latestbuild.properties:
TextWriter latest = new StreamWriter("C:\\Work\\latestbuild.properties");
In your Ant script, you are loading a different filename lastestbuild.properties.
Unless you've fixed it since then, that will be your problem. (If you modified your external script to take the filename as a parameter, and defined the filename once as an Ant property - as in my sample above - it would help you avoid this kind of problem.)
Regarding your discovery that you need to wait for your external script before continuing in Ant, take a look at the Sleep task.

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