Set ant property by invoking a shell script? - ant

Is there any way to set an ant property by capturing the output of a shellscript? (or another ant task)
Something like this:
<property name="foo">
<value>
<exec executable="bar" />
</value>
</property>
Thanks!

It seems that exec task has an outputproperty-property, like so:
<exec executable="bar" outputproperty="foo" />

From the ANT exec task
Set the output attribute : Name of a file to which to write the output.
As Marble has suggested - set the outputproperty
When I tested they came out to be mutually exclusive. So set only 1 of them at a time.

To expand on #Nim's answer, complex commands can be generated using arg tags:
<exec executable="/usr/bin/git" outputproperty="git.branch">
<arg value="rev-parse"/>
<arg value="--abbrev-ref"/>
<arg value="HEAD"/>
</exec>
This can be referenced later like:
<attribute name="Git-Branch" value="${git.branch}"/>

Related

Conditionally redirecting output in ant exec task

Is there a way of conditionally redirecting the output to property or the stdout stream as the non-working example below?
<macrodef name="mytask">
<attribute name="output" default="STDOUT"/>
<sequential>
<exec executable="my.exe" outputproperty="#{output}"/>
</sequential>
</macrodef>
The above example redirects the output by default to a property STDOUT. Instead I would like it to be directed to the stdout stream.
I could create mytask_with_stdout as a copy of the above macro and remove the exec outputproperty, but that would violate the DRY principle.
Is there some nice way of doing this?
There are two Ant features you can combine to get what you want.
First, a <macrodef> can be passed whatever <element> you want.
Second, a <redirector> can be used to capture the output of an <exec> command in a property.
I ran the following Ant script on a Windows machine so I could use cmd.exe's echo command. Replace the cmd.exe with your my.exe:
<project name="exec-redirector-example" default="run">
<macrodef name="mytask">
<attribute name="message"/>
<element name="myredirector" optional="true"/>
<sequential>
<exec executable="cmd.exe">
<arg value="/c"/>
<arg value="echo"/>
<arg value="#{message}"/>
<myredirector/>
</exec>
</sequential>
</macrodef>
<target name="run">
<!-- exec outputs to STDOUT by default -->
<mytask message="To STDOUT">
</mytask>
<!-- exec outputs to a property in this example -->
<mytask message="To property">
<myredirector>
<redirector outputproperty="my.property"/>
</myredirector>
</mytask>
<echo>${my.property}</echo>
</target>
</project>

Trouble passing argument to Ant exec task

I'm using Ant 1.8. I want to pass a property that I define in my script to an exec command. Although I can see the property has a value in my echo statements, when I pass it to the script and output its value in the script, its value prints out as "${myco.test.root}", without being converted. What is the correct way to pass the property's value to the script? Below is the relevant code from my build.xml file …
<target name="checkout-selenium-tests" depends="set-critical-path-test-suite,set-default-test-suite,check-local-folders-exist">
<echo message=" test root ${myco.test.root}" />
<stcheckout servername="${st.servername}"
serverport="${st.serverport}"
projectname="${st.myco.project}"
viewname="${st.myco.viewname}"
username="${st.username}"
password="${st.password}"
rootstarteamfolder="${myco.starteam.test.root}"
rootlocalfolder="${myco.test.root}"
forced="true"
deleteuncontrolled="true"
/>
<delete file="${myco.testsuite.file}" />
<echo message="test root ${myco.test.root}" />
<exec failonerror="true" executable="perl" dir="${scripts.dir}">
<arg value="generate_test_suite.pl" />
<arg value="My Tests" />
<arg value="${myco.test.root}" />
<arg value="${myco.testsuite.file}" />
</exec>
</target>
Thanks, - Dave
It actually looks good to me. Try running the build.xml with both the verbose and debug options turned on in Ant:
ant -d -v checkout-selenium-tests
That'll help trace down where the error could be coming from.

How to set the path environment variable from ant script

How to set the path environment variable from ant script
Is this for an <exec> task?
You can set environment variables when you run an <exec> task:
<exec executable="${my.command}">
<env key="foo" value="bar"/>
<arg line="some value"/>
</exec>
You can use <property environment="env"/> to expand the path:
<property environment="env"/>
<exec executable="${my.command}">
<env key="PATH" value="${env.PATH}:${my.directory}"/>
</exec>
If this is for some custom task that requires an environment variable, but doesn't allow you to set the environment variable in the task if one isn't set, you can try setting it in:
<property environment="env"/>
<property name="env.foo" value="bar!bar"/>
This might set an environment variable called foo to the value of bar!bar!. I remember something about this, but wasn't able to get it to work.
The other thing you can do is have one ant script execute another and have the first ant script set the environment value. I did this when I had to set ANT_OPT.
In ant, properties are immutable, so David's suggestion above:
<property name="env.foo" value="bar!bar"/>
won't work.
But (with the antcontrib-library) variables are mutable, so this works:
<var name="env.foo" value="bar!bar"/>
NOTE: to use the antcontrib-library download it from here: ANT Contrib - Download
This gets the job done, but seems like a dastardly trick.
So to your specific question, try:
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="${basedir}/lib/ant-contrib-1.0b3.jar" />
</classpath>
</taskdef>
<var name="env.PATH" value="some:custom:value"/>
You can use setx command to set the environment variables.
For setx command help refer http://ss64.com/nt/setx.html
<exec executable="setx.exe">
<arg line="Path C:\jdk1.5.0_12\bin"/>
<arg line="/m"/>
</exec>
I found it works by quote the value of variable
<exec executable="setx">
<arg line="Path "${env.Path};c:\testPath"" />
<arg line="/m" />
</exec>
You can use to expand the path:
And then you can execute for instance sh from ant to export the environment variable:
<property environment="env"/>
<exec executable="sh">
<arg value="-c"/>
<arg value="export PATH=${env.Path}:${myPath}"/>
</exec>
Or execute your command and set env with value, like so:
<property environment="env"/>
<exec executable="${your.command}">
<env key="PATH" value="${env.PATH}:${your.directory}"/>
</exec>
To set the environment variables through Ant, try calling exec task and set the command line values. I have not tried this by the way, but it should work.
since I don't have enough reputation to comment on the <variable ... suggestions my comment as an answer ... :-/
In ("newer") ant-contrib (extra ANT package) the task is not called <variable ... but <var ...!
(but it didn't work for me anyways since I think the manipulation of the env.* (created by <property environment="env" ... /> task) Java properties/variables is only relevant for tasks/processes evaluating these Java properties which are not automatically "synced back" to the OS environment variables)

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 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