Expanding parameters in Apache Ant exec task - ant

I have a build that needs a task for starting a process, and one for killing it at the end.
I have a file with the process id in it, but cannot figure out how to make ant expand the command substitution in order to pass the contents of that file to the kill command.
I have tried:
<target name="kill process">
<exec executable="kill">
<arg value="`cat process-file`"/>
</exec>
...
And:
<target name="kill process">
<exec executable="kill">
<arg value="$(cat process-file)"/>
</exec>
but both are converted to string litterals, and so result in:
[exec] kill: failed to parse argument: '$(cat process-file)'
Is there a way to make ant expand these? Or an altogether different route to accomplish this?

You can use Ant's loadfile task to read the file's content into a property.
<loadfile srcFile="process-file" property="pid">
<filterchain>
<striplinebreaks/>
</filterchain>
</loadfile>
<exec executable="kill">
<arg value="${pid}"/>
</exec>
EDIT: added filterchain to deal with additional whitespace

Related

JSCover - Excluding coverage files

Currently trying to get JSCover to exclude js files that are used as libraries. I have a set of ant scripts below which will
start the JSCover server
Run & Generate Json report
Stop the server
Finally, i have a shell command to convert the Json file to LCov so that i can use it with sonarqube. I also get coverage in jscoverage.html but it includes every file under web/ which is something i do not want. Image below
Ant scripts below:
<target name="jstest-start">
<java jar=".../JSCover.jar" fork="true" spawn="true">
<arg value="-ws"/>
<arg value="--report-dir=coverage"/>
<arg value="--document-root=web"/>
<arg value="--port=8082"/>
<!-- Aim is to exclude folder js under web/ as it contains libraries, not source code. Currently does not work -->
<arg value="--no-instrument=web/js/"/>
<arg value="--no-instrument=js/"/>
</java>
<waitfor maxwait="5" maxwaitunit="second" checkevery="250" checkeveryunit="millisecond" timeoutproperty="failed">
<http url="http://localhost:8082/jscoverage.html"/>
</waitfor>
<fail if="failed"/>
</target>
<target name="jstest-run">
<exec dir="/usr/local/CI/phantomjs/bin/" executable="phantomjs" failonerror="true">
<arg line=".../run-jscover-qunit.js http://localhost:8082/index.html"/>
</exec>
</target>
<target name="jstest-stop">
<get src="http://localhost:8082/stop" dest="stop.txt" />
</target>
<target name="jstest" description="Run javascript tests">
<antcall target="jstest-start"/>
<antcall target="jstest-run"/>
<antcall target="jstest-stop"/>
</target>
My folder structure is:
And finally, my sonar standalone analysis settings:
So, what seems to be happening is that JSCover is recursively reading for all js files and i cannot prevent that from sonar or ant.
Can anyone shed some light?
<arg value="--no-instrument=/js/"/>
should work, and to remove the test itself,
<arg value="--no-instrument=/test/"/>
The paths are as seen by the web-server, so the 'web' prefix in:
<arg value="--no-instrument=web/js/"/>
has no effect.
i have resolved my own issue by correcting the shell command which generates an LCOV report.
java -cp JSCover.jar jscover.report.Main --format=LCOV /usr/local/CI/jenkins/workspace/PhantomJS/coverage/phantom/ /usr/local/CI/jenkins/workspace/PhantomJS/web/
Prior to this, the SRC-DIR and REPORT-DIR were the same which was an error on my part. As far as i can understand, SRC-DIR should point to the source folder and REPORT-DIR should point to where the lcov file exists.
I hope this helps someone

how to use exec exit status in ant target and other targets also

I am calling one target(targetCalled) from some other target(targetCaller), as follows:
<target depends="local.init"
description="creating application jar file of the classes dir"
name="run_check_server_client_jar_gen">
<antcall target="run_check_server_client_jar_callExec"/>
<if>
<isset property="result"/>
<then>
<echo>Result: ${result}</echo>
</then>
<else>
<echo>Propert result is not set yet !! </echo>
</else>
</if>
</target>
Now I call one exec from targetCalled as follows:
<target depends="local.init"
description="Running check for all classes in
client jar should also be present in server jar"
name="run_check_server_client_jar_callExec">
<exec executable="/bin/bash" resultproperty="${result}" failonerror="false">
<arg value="count_client_server_inner_classes.sh"/>
<arg value="gjf1common_client_classes.jar"/>
<arg value="gjf1common_classes.jar"/>
</exec>
<if>
<isset property="result"/>
<then>
<echo>Inside::Result: ${result}</echo>
</then>
<else>
<echo>Inside::Property result is not set yet !!!! </echo>
</else>
</if>
</target>
In my count_client_server_inner_classes.sh, i am exiting the status as:
exit "$result"
it is giving me ": numeric argument required"
i want that executable should return me a string, is that possible ??
I want to use this returned value in my targetCalled and targetCaller.
but when i am echoing the result property.. it is giving me 255.
Can anybody points out where i am going wrong ?
Ant isn't a scripting language. It's not a very good way to describe a build - but it's an awful scripting language. Trying to script in ant with pseudo-function calls and if/else like this is going to suck. In generally, stay away from if/else - if you find you need them you likely want to reevaluate your tool choice. Avoid antcall at all costs - it spins up a new jvm and makes for some crazy spaghetti - use depends to control the execution flow between targets.
To answer one of your question - the result property is always going to be the exit code, in the case of bash it's always goign to be an int 0-255.
The interesting part is in the bash script... post that. It's returning 255, which is a special code - means it's out of range. I suspect you're having it return a string?
You could simplify the whole mess by simply failing on error:
<target name="run-check-server-client-jar-gen" depends="local-init"
description="creating application jar file of the classes dir">
<exec executable="/bin/bash" failonerror="true">
<arg value="count_client_server_inner_classes.sh"/>
<arg value="gjf1common_client_classes.jar"/>
<arg value="gjf1common_classes.jar"/>
</exec>
</target>
If you really must give custom error status you can set the result property as you where and then you could:
<target name="run-check-server-client-jar-gen" depends="local-init"
description="creating application jar file of the classes dir">
<exec executable="/bin/bash" resultproperty="${return.code}">
<arg value="count_client_server_inner_classes.sh"/>
<arg value="gjf1common_client_classes.jar"/>
<arg value="gjf1common_classes.jar"/>
</exec>
<fail message="crazy shell script madness terminated abnormally.">
<condition>
<isfailure code="${return.code}"/>
</condition>
</fail>
</target>
I admit I didn't actually run the snippets above, you may have to massage a bit, but I'm pretty sure they'll go.
another editorial note on style: targets generally use - rather than _ or . to delimit word, where properties use .

How to get %ERRORLEVEL% from batch file in Ant

I want to know if its possible to get the return value from batch file in Ant build xml.
My batch file returns %ERRORLEVEL% value (batch file returns 2 in my case). I want to know if it's possible to capture this and mark as error in Ant. Below is the code snippet I use:
<exec executable = "cmd">
<arg value="/c"/>
<arg value="C:\workspace\Build\cross_Compile.bat"/>
</exec>
Currently after the batch file call, build is reported as success always. It looks like Ant is not processing the %ERRORLEVEL% or I am not sure. How I can make Ant process the %ERRORLEVEL%?
Use the resultproperty and failonerror. By default, the errocode is ignored.
<property name="Batcherrcode" value="0"/>
<exec executable = "cmd" failonerror="true" resultproperty="Batcherrcode">
<arg value="/c"/>
<arg value="C:\workspace\Build\cross_Compile.bat"/>
</exec>
<echo message="Error Code:=${Batcherrorcode}" />

Running a .cmd file from Ant

Is it possible to run a command (.cmd file) from Ant? Would I need to write Java code for this?
<exec executable="cmd" os="Windows XP">
<arg value="/C"/>
<arg value="command to run"/>
</exec>
You can do this by using the exec task. From the ant exec documentation:
Note that .bat files cannot in general by executed directly. One normally needs to execute the command shell executable cmd using the /c switch.
So you would need to do something like:
<exec executable="cmd">
<arg value="/c"/>
<arg value="batchfile.cmd"/>
</exec>
Note that by doing this you have created a dependency of running your ant script in windows.
Adding to eradicus answer, you can also execute .bat, .cmd, ... from any directory with argument on your Window machine by
<target name="test">
<exec executable="cmd" dir="C:/Users/mydir/">
<arg value="/C" />
<arg value="myjob.bat arg1 arg2" />
</exec>
</target>

How can I get current PID from within Ant?

I have an ant task, and within it I'd like to get the current process id (a la echo $PPID from command line).
I'm running ksh on Solaris, so I thought I could just do this:
<property environment="env" />
<target name="targ">
<echo message="PID is ${env.PPID}" />
<echo message="PID is ${env.$$}" />
</target>
But that didn't work; the variables aren't substituted. Turns out PPID, SECONDS, and certain other env variables don't make it into Ant's representation.
Next I try this:
<target name="targ">
<exec executable="${env.pathtomyfiles}/getpid.sh" />
</target>
getpid.sh looks like this:
echo $$
This gets me the PID of the spawned shell script. Closer, but not really what I need.
I just want my current process ID, so I can make a temporary file with that value in the name. Any thoughts?
You can find PID using java process monitoring tool JPS, then output stream can be filtered and if needed process can be killed. check out this tomcat pid kill script:
<target name="tomcat.kill" depends="tomcat.shutdown">
<exec executable="jps">
<arg value="-l"/>
<redirector outputproperty="process.pid">
<outputfilterchain>
<linecontains>
<contains value="C:\tomcat\tomcat_node5\bin\bootstrap.jar"/>
</linecontains>
<replacestring from=" C:\tomcat\tomcat_node5\bin\bootstrap.jar"/>
</outputfilterchain>
</redirector>
</exec>
<exec executable="taskkill" osfamily="winnt">
<arg value="/F"/>
<arg value="/PID"/>
<arg value="${process.pid}"/>
</exec>
<exec executable="kill" osfamily="unix">
<arg value="-9"/>
<arg value="${process.pid}"/>
</exec>
</target>
Why not just use the tempfile Ant task, instead? It does what you really want to do, while hiding all the gory details.
See http://ant.apache.org/manual/Tasks/tempfile.html.
your second method doesn't get ANT's pid. Change the shell script to (I use bash, I don't know if ksh is the same):
echo "$PPID"

Resources