Running a BAT file from ANT - ant

I have gone through number of posts on the very forum but couldn't sort it out. I am trying to run a BAT file from ANT script. The folder hierarchy is like this
- Project
| - build.xml
| - build-C
| | - test.bat
The ANT file that i wrote so for is
<project name="MyProject" basedir=".">
<property name="buildC" value="${basedire}\build-C" />
<exec dir="${buildC}" executable="cmd" os="Windows XP">
<arg line="/c test.bat"/>
</exec>
</project>
The bat file content is
echo In Build-C Test.bat
It says that build failed .. :s i dun know what wrong am i doing ?

<property name="buildC" value="${basedire}\build-C" />
This should be ${basedir} I guess? Use
<echo>${buildC}</echo>
to make sure the dir is correct.
And shouldn't
<exec dir="${buildC}" executable="test.bat" os="Windows XP" />
do the job?

Hopefully this will help expand on the already given/accepted answers:
I suggest executing cmd with the batch script as a parameter:
<exec failonerror="true" executable="cmd" dir="${buildC}">
<arg line="/c "${buildC}/test.bat""/>
</exec>
Not sure if it is necessary to use the absolute path "${buildC}/test.bat" since dir is specified, but I put it just in case. It might be enough to use /c test.bat.
My project executes a batch script on Windows operating systems & a shell script on all others. Here is an example:
<target name="foo">
<!-- properties for Windows OSes -->
<condition property="script.exec" value="cmd">
<os family="windows"/>
</condition>
<condition property="script.param" value="/c "${basedir}/foo.bat"">
<os family="windows"/>
</condition>
<!-- properties for non-Windows OSes -->
<property name="script.exec" value="sh"/>
<property name="script.param" value=""${basedir}/foo.sh""/>
<echo message="Executing command: ${script.exec} ${script.param}"/>
<exec failonerror="true" executable="${script.exec}" dir="${basedir}">
<arg line="${script.param}"/>
</exec>
</target>

Related

How to conditionally execute batch scripts for different platforms using Ant?

I am attempting to use an Ant build script to build a project that already has nmake (Visual Studio) build scripts. Rather than redo the entire build script, I would like to have Ant reuse the existing scripts.
So, I have something like this which works for Windows Mobile 6 ARMV4I builds:
<project ...>
<target name="-BUILD.XML-COMPILE" depends="-init, -pre-compile">
<exec executable="cmd">
<arg value="/c"/>
<arg line='"${g.path.project}\build-wm6-armv4i.bat"'/>
</exec>
<antcall target="-post-compile" inheritall="true" inheritrefs="true" />
</target>
</project>
But I would also like it to work for other platforms like Win32 x86 and Windows CE6 x86.
How can I have the Ant script discriminate which batch file it should execute to perform the build?
The <os> condition may be used to set properties based on the operating system and the hardware architecture. Targets may be conditionally executed using the if and unless attributes.
<?xml version="1.0" encoding="UTF-8"?>
<project name="build" basedir="." default="BUILD.XML-COMPILE">
<condition property="Win32-x86">
<and>
<os family="windows" />
<or>
<os arch="i386" />
<os arch="x86" />
</or>
</and>
</condition>
<condition property="Win-ARMv4">
<os family="windows" arch="armv4" />
</condition>
<target name="-BUILD.XML-COMPILE_Win-ARMv4" if="Win-ARMv4"
depends="-init, -pre-compile">
<exec executable="cmd">
<arg value="/c"/>
<arg line='"${g.path.project}\build-wm6-armv4i.bat"'/>
</exec>
<antcall target="-post-compile" inheritall="true" inheritrefs="true" />
</target>
<target name="-BUILD.XML-COMPILE_Win32-x86" if="Win32-x86"
depends="-init, -pre-compile">
<exec executable="cmd">
<arg value="/c"/>
<arg line='"${g.path.project}\build-win32-x86.bat"'/>
</exec>
<antcall target="-post-compile" inheritall="true" inheritrefs="true" />
</target>
<!-- Execute the correct target automatically based on current platform. -->
<target name="BUILD.XML-COMPILE"
depends="-BUILD.XML-COMPILE_Win-ARMv4,
-BUILD.XML-COMPILE_Win32-x86" />
</project>
The paths to the batch files are both single and double quoted so that file paths with spaces will not break the script. I have not tested this script on Windows Mobile 6 ARMV4I, so you will want to use the Ant target below to verify the name.
<target name="echo-os-name-arch-version">
<echo message="OS Name is: ${os.name}" />
<echo message="OS Architecture is: ${os.arch}" />
<echo message="OS Version is: ${os.version}" />
</target>
Related stack overflow questions:
how to detect the windows OS in ANT
Using ant to detect os and set property

Ant build.xml phpunit

I have a ant build.xml (below). I am able to run phpunit fine from the command line as follows:
D:> phpunit --verbose --testdox-html logs\today.html runtest
This runs all my phpunit tests within the folder d:\runtest.
My problem is when I run my build.xml as 'ant build' it tries to execute a file called runtest.php the output from ant is below:
D:\>ant build
Buildfile: D:\build.xml
check_os:
if_windows:
if_unix:
prepare:
phpunit:
[exec] PHPUnit 3.6.11 by Sebastian Bergmann.
[exec]
[exec] Cannot open file "runtest.php".
BUILD FAILED
D:\build.xml:48: exec returned: 1
Total time: 2 seconds
My Build.xml is as follows:
<!-- This project launches the test generator and execute all phpunit selenium tests -->
<project name="proj" default="build" basedir="">
<!--Get environment variables -->
<property environment="env" />
<property name="logFolder" value="${basedir}\logs"/>
<property name="testFolder" value="${basedir}\runtest"/>
<property name="test" value="**" />
<condition property="pattern" value="runtest/*.php">
<os family="windows" />
</condition>
<tstamp/>
<!-- Check Operating system to set phpunit path-->
<target name="check_os">
<condition property="isWindows">
<os family="windows" />
</condition>
<condition property="isLinux">
<os family="unix" />
</condition>
</target>
<target name="if_windows" depends="check_os" if="isWindows">
<property name="exe.phpunit" value="C:\\Program Files\\PHP\\phpunit.bat"/>
</target>
<target name="if_unix" depends="check_os" if="isLinux">
<property name="exe.phpunit" value="${env.PHP_HOME}/includes/PHPUnit-3.2.0/PHPUnit" />
</target>
<target name="prepare" depends="if_windows, if_unix">
<mkdir dir="${logFolder}"/>
</target>
<target name="phpunit">
<!-- Check if folder empty -->
<fileset id="fileset.test" dir="${testFolder}">
<include name="*.*"/>
</fileset>
<fail message="Files not found">
<condition>
<resourcecount refid="fileset.test" when="less" count="1"></resourcecount>
</condition>
</fail>
<!-- Execute phpunit tests -->
<exec executable="${exe.phpunit}" failonerror="true" dir="runtest">
<arg line="--verbose --testdox-html '${logFolder}\phpunit-report-${TODAY}.html' runtest" />
</exec>
</target>
<target name="build" depends="prepare,phpunit"/>
</project>
The problem was I specified dir="runtest" once I removed this from the Execute line it worked.
<target name="phpunit" unless="phpunit.done" depends="prepare" description="Run unit tests with PHPUnit">
<exec executable="${phpunit}" failonerror="true" dir="${basedir}/classes/tests/" resultproperty="result.phpunit">
${phpunit} - needs Path of phpunit installation, you can get it from where is phpunit command in linux
dir="${basedir}/classes/tests/" - Need only the folder path where your php application is present
<arg line="UserTest ${basedir}/classes/tests/userTest.php" />
line="UserTest ${basedir}/classes/tests/userTest.php" - Here UserTest is class name and ${basedir}/classes/tests/userTest.php it is path of test class file
<arg value="--configuration"/>
<arg path="${basedir}/classes/tests/UnitTest.xml"/>
path="${basedir}/classes/tests/UnitTest.xml" - Path of xml file
</exec>
<property name="phpunit.done" value="true"/>
</target>

modify ant classpath on the fly

I want to use resolvers (ssh) which are dependant on ant classpath.
Something like
<resolvers>
...
<ssh ...
...
</resolvers>
To use it I need jsch in ant classpath. Ant script should depends only on common lib (which also includes resolved jsch dependencies) - to use it on any client PC. Scenario is:
task to download lib.
Extract libs (jsch and etc.)
ivy:configure
But ivy:configure does not have any classpathref param, so it is unclear for me how to load jars I extracted.
Is it possible?
Or, probably, somehow run ant again internally with extended classpath?
Ok,
so my comment to question looked good for me but at the end it did not work.
The only way I found (working way I mean) is to to run ant script with
Download common-lib (with ) which includes all jar-libs required for optional ivy processing
Construct new classpath and run exec on same build file with required target:
<target name="call.task" if="wrapped.task.name">
<path id="ant.class.path">
<fileset dir="${tools.lib.dir}" >
<include name="*.jar" />
</fileset>
<pathelement location="${java.class.path}" />
</path>
<condition property="append.dest.dir" value="-Ddest.dir=${dest.dir}" else="">
<isset property="dest.dir"/>
</condition>
<exec executable="ant" failonerror="true">
<arg line="-f ivy-build.xml" />
<arg line='-lib "${toString:ant.class.path}"' />
<arg value="${wrapped.task.name}" />
<arg value="${append.dest.dir}" />
</exec>
</target>

how to detect tomcat version installed and set CATALINA_HOME env variable using Ant Apache script?

I have a script which detects OS using Catalina.bat for windows and Catalina.sh for UNIX..it executes successfully for UNIX but for windows its not able to extract OS version from Catalina.bat..the reason i find out is because in Catalina.bat when it executes this line
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome
then OS version statement is not reached in catalina.bat file,so the solution to this is i guess; explicitly set CATALINA_HOME environment variable using my Ant script itself; how to do that plz suggest any solution.
i was using this code, here OS.version property should have cached the OS version from catalina.bat file similar code in UNIX is working fine but win i wonder whats wrong
<property name="version" location="${My_proj}\tomcat\bin\catalina.bat"/>
<exec executable="${version}" outputproperty="OS.version">
<arg value="version" />
<redirector>
<outputfilterchain>
<tokenfilter>
<containsstring contains="OS Name:"/>
<replacestring from="OS Name: " to=""/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
PROBLEM O SOLVED: you were right ..
<exec executable="cmd" outputproperty="tomcat.version">
<arg value="/c"/>
<arg value="${MY_PROJ}\tomcat\bin\version.bat"/>
<env key="CATALINA_HOME" value="${MY_PROJ}\tomcat\"/>
<redirector>
<outputfilterchain>
<tokenfilter>
<containsstring contains="Server version"/>
<replaceregex pattern="Server version: Apache Tomcat/(.*)$" replace="\1"/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
<echo message="tomcat.version: ${tomcat.version}"/>
OUTPUT:
versioncat:
[echo] tomcat.version: 6.0.33
LAST BUL NOT THE LEAST CAN ANY1 ANSWER OR SUGGEST A WORKAROUND FOR MY LAST COMMENT QUERY THE SILLY QUESTION
If I understand correctly, you are executing this OS detection from Ant. In that case, can you not instead use Ant's built-in support for OS identification - in the os condition?
However, if you really need to execute catalina.bat while setting CATALINA_HOME, you could do so using a nested env element in you exec task.
Here is a sample build file which uses both approaches:
<project default="test">
<target name="test">
<!-- Execute a command, in this case a simple bat file
which echoes the value of the var set in the env block
-->
<exec executable="cmd">
<arg value="/c"/>
<arg value="test.bat"/>
<env key="CATALINA_HOME" value="whatever"/>
</exec>
<!-- echo the values of built-in OS related properties -->
<echo message="os.arch: ${os.arch}"/>
<echo message="os.name: ${os.name}"/>
<echo message="os.version: ${os.version}"/>
<!-- test one of the os conditions -->
<condition property="is.windows">
<os family="windows"/>
</condition>
<echo message="is.windows ? ${is.windows}"/>
</target>
</project>
Here is the content of test.bat:
echo CATALINA_HOME=%CATALINA_HOME%
Here is the output:
test:
[exec]
[exec] C:\tmp\ant>echo CATALINA_HOME=whatever
[exec] CATALINA_HOME=whatever
[echo] os.arch: x86
[echo] os.name: Windows XP
[echo] os.version: 6.1 build 7601 Service Pack 1
[echo] is.windows ? true
Regarding your subsequent question (in comments) about tomcat version...
I now guess you are executing this version detection via Ant in your runtime environment.
Ant and Java don't know about your Tomcat environment, so now you're back to executing %CATALINA_HOME%\bin\catalina.bat -version and parsing what you need from the output.
Here's a working example:
<project default="version">
<property environment="env"/>
<condition property="script.ext" value="bat">
<os family="windows"/>
</condition>
<condition property="script.ext" value="sh">
<os family="unix"/>
</condition>
<target name="version">
<exec executable="${env.CATALINA_HOME}/bin/version.${script.ext}" outputproperty="tomcat.version">
<redirector>
<outputfilterchain>
<tokenfilter>
<containsstring contains="Server version"/>
<replaceregex pattern="Server version: Apache Tomcat/(.*)$" replace="\1"/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
<echo message="tomcat.version: ${tomcat.version}"/>
</target>
</project>
And here is the output:
version:
[echo] tomcat.version: 5.5.33
Note that this example assumes that you have the CATALINA_HOME (and JAVA_HOME) environment variable set in your terminal.
Alternatively, you could pass these variables using a nested <env> element as previously discussed. But it seems more likely that these should come from the runtime environment rather than embedded in your build file.
Do it like this :
<condition property="catalina.path" value="C:\Foo\catalina.bat">
<os family="windows"/>
</condition>
<condition property="catalina.path" value="/home/foo/catalina.sh">
<os family="unix"/>
</condition>
<exec> ... execute your script here </exec>
Depending on your situation, you may find this approach a little more platform agnostic and less error prone as you do not need to fork off a shell. This works at least as far back as Tomcat 6.x
<property environment="env"/>
<loadproperties>
<zipentry zipfile="${env.CATALINA_HOME}/bin/bootstrap.jar" name="META-INF/MANIFEST.MF"/>
<filterchain>
<prefixlines prefix="tomcat."/>
</filterchain>
</loadproperties>
<!-- Prints MAJOR.MINOR version, e.g.: 8.0 -->
<echo message="Tomcat Version: ${tomcat.Specification-Version}"/>
<!-- Prints full version, e.g.: 8.0.26 -->
<echo message="Tomcat Release: ${tomcat.Implementation-Version}"/>

How to get a local IP address in ant 1.5.1

I was wondering, if there is a way to figure out the local IP address with ant. I cannot use the hostinfo task, since I am bound to ant 1.5.1. Now I would write little scripts for each platform and use ant conditional mechanics to execute the appropriate script for each platform. However, maybe any of you know a more elegant way? Thanks in advance.
Benjamin
This works on my mac running os x 10.8.2 :
<target name="getCurrentIP">
<exec executable="/usr/sbin/ipconfig" outputproperty="currentIP">
<arg value="getifaddr"/>
<arg value="en0"/>
</exec>
<echo>currentIP : ${currentIP}</echo>
</target>
<target name="checkos">
<condition property="isWindows" value="true">
<os family="windows" />
</condition>
<condition property="isLinux" value="true">
<os family="unix" />
</condition>
</target>
<target name="if_windows" depends="checkos" if="isWindows">
<exec executable="cmd" outputproperty="myHostName">
<arg value="/c" />
<arg value="hostname"/>
</exec>
<exec executable="cmd" outputproperty="infraServerIPTemp" >
<arg value="/c"/>
<arg value="FOR /f "tokens=1 delims=:" %d IN ('ping ${myHostName} -4 -n 1 ^| find /i "reply"') DO FOR /F "tokens=3 delims= " %g IN ("%d") DO echo infraServerIP=%g > myIP.properties"/>
</exec>
<property file="myIP.properties"/>
</target>
<target name="if_unix" depends="checkos" if="isLinux">
<exec executable="hostname" outputproperty="infraServer">
<arg line="-i"/>
</exec>
<property name="infraServerIP" value="${infraServer}"/>
</target>
<target name="checkOSType" depends="if_windows, if_unix"/>
<target name="do-something" depends="checkOSType">
</target>
with the help of Ant addon Flaka you might use :
<project xmlns:fl="antlib:it.haefelinger.flaka">
<!-- on windows -->
<exec executable="cmd" outputproperty="winip">
<arg value="/c" />
<arg value="ipconfig" />
</exec>
<!-- simple echo -->
<fl:echo>localip => #{replace('${winip}', '$2' , '\s(IP.+):\s?(\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)')}</fl:echo>
<!-- set property -->
<fl:let>localip := replace('${winip}', '$2' , '\s(IP.+):\s?(\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)')</fl:let>
<!-- on linux -->
<exec executable="hostname" outputproperty="linuxip">
<arg value="-i" />
</exec>
<!-- simple echo -->
<fl:echo>localip => #{replace('${linuxip}', '$1' , '(\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)\s(.+)')}</fl:echo>
<!-- set property -->
<fl:let>localip := replace('${linuxip}', '$1' , '(\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)\s(.+)')</fl:let>
</project>
Our solution to the problem is, that we built a little Java program, which prints the local ip to the standard output. We store this output in an ant property. (We use Java instead of a scripting language of some sort, because we would otherwise have to deploy the language runtime on many systems and Java is already deployed throughout our system landscape)

Resources