problem with ant script properties - ant

The following is my ant script:
<project name="nightly_build" default="main" basedir="C:\Work\6.70_Extensions\NightlyBuild">
<target name="init">
<sequential>
<exec executable="C:/Work/Searchlatestversion.exe">
<arg line='"/SASE Lab Tools" "6.70_Extensions/6.70.102/ANT_SASE_RELEASE_"'/>
</exec>
<property file="C:/Work/latestbuild.properties"/>
<sleep seconds="10"/>
<echo message="The product version is ${Product_Version}"/>
<exec executable="C:/Work/checksnapshot.exe">
<arg line='"ANT_SASE_RELEASE_${Product_Version}_SASE Lab Tools-NightlyBuild" ANT_SASE_RELEASE_${Product_Version}_AnalyzerCommon-NightlyBuild ${Product_Version}-AppsMerge' />
</exec>
<property file="C:/Work/checksnapshot.properties"/>
<tstamp>
<format property="suffix" pattern="ddMMyyyyHHmm"/>
</tstamp>
</sequential>
</target>
<target name="main" depends="init">
<echo message="loading properties files.." />
<sleep seconds="10"/>
<echo message="Backing up folder" />
<move file="C:\NightlyBuild\NightlyBuild" tofile="C:\NightlyBuild\NightlyBuild.${suffix}" failonerror="false" />
<parallel>
<exec executable="C:/Work/sortfolder.exe">
<arg line="6" />
</exec>
<exec executable="C:/Work/6.70_Extensions/NightlyBuild/antc.bat">
</exec>
</parallel>
</target>
</project>
Basically the sequence goes something like this:
I will run Searchlatestversion.exe and write latestbuild.properties
Using the latestbuild.properties i will obtain ${Product_Version} and would like to allow checksnapshot.exe access to latestbuild.properties and obtain ${Product_Version}
checksnapshot.exe will then generate checksnapshot.properties which will then be used by the target in main antc.bat
am i doing something wrong over here? seems like ${Product_Version} is not being received well by checksnapshot.exe

You appear to have a hard coded wait period of 10 seconds for Searchlatestversion to write out your file. If the executable does not complete inside that time, ${Product_Version} cannot be read from file.
Have you considered using the Waitfor Ant Task? As the name implies, this will wait for a certain condition before it will allow the rest of the task to progress. You could do something like
<property name="props.file" value="C:/Work/latestbuild.properties"/>
<waitfor maxwait="10" maxwaitunit="second">
<available file="${props.file}"/>
</waitfor>
<property file="${props.file}"/>

Does Searchlatestversion.exe produce the file C:/Work/latestbuild.properties?
If so, should you not sleep/wait before you load that properties file?
You have this:
<exec .../>
<property file="C:/Work/latestbuild.properties"/>
<sleep seconds="10"/>
Should you not have this:
<exec ... />
<sleep seconds="10"/>
<property file="C:/Work/latestbuild.properties"/>

Related

how to test symlinks with ant 1.9

I need to perform a command if the jar file is a file instead of a symlink. I have found a solution that works only with ant 1.10.
Does anyone know how to do it with ant 1.9 ?
Here is my build.xml.
<?xml version="1.0"?>
<project name="AsterixDecoder" default="bm" basedir=".">
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<property environment="env"/>
<condition property="exists.CCM_ADDR">
<isset property="env.CCM_ADDR"/>
</condition>
<target name="compile" description="compile the source " >
<mkdir dir="${build}"/>
<javac srcdir="${src}" destdir="${build}" includeantruntime="false"/>
<mkdir dir="${build}/resources"/>
<copy todir="${build}/resources">
<fileset dir="resources"/>
</copy>
</target>
<target name="checkout" if="exists.CCM_ADDR">
<ccmcheckout file="${dist}/AsterixDecoder.jar"/>
</target>
<target name="dist" depends="compile, checkout"
description="generate the distribution" >
<jar jarfile="${dist}/AsterixDecoder.jar" filesetmanifest="mergewithoutmain">
<manifest>
<attribute name="Main-Class" value="fr.eurocontrol.escape.ground.asterixdecoder.AsterixDataTree"/>
<attribute name="Class-Path" value="."/>
</manifest>
<fileset dir="${build}"/>
</jar>
</target>
<target name="check.symlink">
<fileset dir="${dist}" id="fileset" includes="AsterixDecoder.jar">
<symlink/>
</fileset>
<pathconvert refid="fileset" property="is.symlink" setonempty="false"/>
</target>
<target name="reconcile" depends="check.symlink" if="exists.CCM_ADDR" unless="is.symlink">
<exec executable="ccm">
<arg value="reconcile"/>
<arg value="-udb"/>
<arg value="${dist}/AsterixDecoder.jar"/>
</exec>
</target>
<target name="bm" description="build management" depends="dist, reconcile">
</target>
</project>
Do not hesitate to make any suggestion of improvements. I am still a beginner in writing ant files.
The most straightforward way to do this would be to use the record function of Ant's symlink task. This creates a property file that lists all of the symlinks found within a given resource collection. Here's an example target:
<target name="default">
<symlink link="testdir" resource="build" />
<symlink action="record" linkfilename="links.record">
<fileset dir="." includes="*" />
</symlink>
<property file="links.record" />
<condition property="testdir.is.symlink">
<isset property="testdir" />
</condition>
<echo message="${testdir.is.symlink}" />
</target>

Ant Script Loop through property file and replace values dynamically

I got a requirement to loop through some XML files, replace the environment specific values in it and create new set of XML files. The environment specific values are to be taken from property file. I am able to loop through a directory to read all the files and replace some specific value using xmltask as below.
<target name="updateConfig" description="update the configuration" depends="init">
<xmltask todir="${ConfigDestDirectory}" report="false" failwithoutmatch="true">
<fileset dir="${ConfigSourceDirectory}">
<include name="*.xml"/>
</fileset>
<replace path="/:application/:NVPairs/:NameValuePair[:name='Connections/HTTP/HostName']/:value/text()" withXml="localhost"/>
</xmltask>
<echo>Replaced Successfully</echo>
</target>
But I would like to read through a property file and get the path/value from it.
I tried using property selector,property,var as different options for this case and manage to get the path but not the value. Below are the snippet of property file and the target that I am using.
#DEV.properties
HostName.xpath=/:application/:NVPairs/:NameValuePair[:name='Connections/HTTP/HostName']/:value/text()
HostName.value=localhost
<project name="TestBuild" default="ReadPropertyFile" basedir=".">
<target name="init">
<property file="DEV.properties"/>
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask" classpath="${xmltaskPath}"/>
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${antcontribPath}"/>
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
</target>
<target name="ReadPropertyFile" description="update the configuration" depends="init">
<property file="DEV.properties" prefix="x"/>
<propertyselector property="propertyList" delimiter="," select="\0" match="([^\.]*)\.xpath" casesensitive="true" distinct="true"/>
<for list="${propertyList}" param="sequence">
<sequential>
<propertyregex property="destproperty" input="#{sequence}" regexp="([^\.]*)\." select="\1" />
<property name="tempname" value="${destproperty}.value" />
<var name="localprop" value="${tempname}"/>
<echo> #{sequence} </echo>
<echo> ${x.#{sequence}} </echo>
<echo>destproperty --> ${destproperty}</echo>
<echo>tempname --> ${tempname}</echo>
<echo> localprop --> ${localprop}</echo>
<echo>${x.${localprop}} </echo> <!--This is not working -->
</sequential>
</for>
</target>
It would be really helpful if you guys can throw some light.
Thanks,
Venkat
Would this work better ?
I think you got yourself confused with the "x." prefix.
<project name="TestBuild" default="ReadPropertyFile" basedir=".">
<target name="init">
<property file="DEV.properties"/>
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask" classpath="${xmltaskPath}"/>
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${antcontribPath}"/>
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
</target>
<target name="ReadPropertyFile" description="update the configuration" depends="init">
<property file="DEV.properties" prefix="x"/>
<local name="propertyList"/>
<propertyselector property="propertyList" delimiter="," select="\1" match="x\.([^\.]*)\.xpath" casesensitive="true" distinct="true"/>
<for list="${propertyList}" param="sequence">
<sequential>
<echo> #{sequence} </echo>
<echo> #{sequence}.xpath = ${x.#{sequence}.xpath} </echo>
<echo> #{sequence}.value = ${x.#{sequence}.value} </echo>
</sequential>
</for>
</target>
</project>

ant build.xml target to check for debug code

When debugging it's quite common for me to use things such as Zend_Debug and die() in the PHP to locate an issue. Occasionally I forget to take these out before committing my code. So I was wondering...
How do I write an ant build.xml target which checks all the files in my application for specific strings and fails if they have been found?
Basically, I'm after a reverse grep command which fails when it finds a string.
Any ideas?
Also, given my build.xml file looks like this (I've removed most of my targets to make it short), how do I make it work?
I don't know how ant works, so I'm after a 'drop-in' solution or good instructions.
<?xml version="1.0" encoding="UTF-8"?>
<project name="API" default="build" basedir=".">
<property name="source" value="application"/>
<target name="build" depends="prepare,lint,phpcpd,phpdox,phpunit,phpcb"/>
<target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/build/api"/>
</target>
<target name="lint">
<apply executable="php" failonerror="true">
<arg value="-l" />
<fileset dir="${basedir}/${source}">
<include name="**/*.php" />
</fileset>
<fileset dir="${basedir}/tests">
<include name="**/*.php" />
</fileset>
</apply>
</target>
</project>
Within the lint target (after the apply element) add
<fileset id="die-files" dir="${basedir}/${source}">
<include name="**/*.php" />
<contains text="die()"/>
</fileset>
<fail message="The following files contain "die()": ${ant.refid:die-files}">
<condition>
<resourcecount when="greater" count="0" refid="die-files"/>
</condition>
</fail>
If you can use ant-contrib than:
<for param="file">
<path>
<fileset dir="/path/to/application/"/>
</path>
<sequential>
<if>
<contains string="#{file}" substring="bad elements"/>
<then>
<fail>warning! substring is present in directory</fail>
</then>
</if>
</sequential>
</for>

Ant build to fail but always execute a target in Jenkins

[Solved] - The correct ant contrib jar was not getting picked up from the default location on my system. Have to give path manually in the build xml like this:
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="/usr/share/ant/lib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
-------------------------------------------
Q: I have a python script that is run through ant/Jenkins like this:
<project name="prjName">
<target name="preRun" description="do something">
....
</target>
<target name="Run" description="Run the python script">
<exec executable="python" failonerror="true">
<arg value="${basedir}/run.py" />
<arg value="something" />
</exec>
</target>
<target name="other1" description="do something">
....
</target>
<target name="other2" description="do something">
....
</target>
</project>
Now this python script runs an external tool (web-inject which produces some result files) and keeps on scanning for the word FAIL in the logs. As soon as it finds FAIL, it does sys.exit("Error")
Thus the build fails but I still want to execute the target - other1. Is it possible through try-catch? I am doing it like this but it isn't working
<macrodef name="test-case">
<sequential>
<trycatch>
<try>
<exec executable="python" failonerror="true">
<arg value="${basedir}/read.py" />
</exec>
</try>
<catch>
<echo>Investigate exceptions in the run!</echo>
</catch>
<finally>
<antcall target="other1" />
</finally>
</trycatch>
</sequential>
</macrodef>
<target name="other1" description="do something">
....
</target>

ANT script to compile all (css) LESS files in a dir and subdirs with RHINO

I want do compile all *.less scripts in a specific folder and it subdirs with less-rhino-1.1.3.js.
There is an example on github for doing this for a specific file, which works perfect. But I want to do the same for a complete folder. I tried a lot, here is my last try.
It doesn't work, propertyregex seems not to be standard ANT, I don't want to use such things. I am not even sure if this code would work.
<project name="test" default="main" basedir="../../">
<property name="css.dir" location="public/css"/>
<property name="tool.less" location="bin/less/less-rhino-1.1.3.js"/>
<property name="tool.rhino" location="bin/tools/rhino/js.jar"/>
<macrodef name="lessjs">
<attribute name="input" />
<attribute name="output" />
<sequential>
<java jar="${tool.rhino}" fork="true" output="#{output}">
<arg path="${tool.less}"/>
<arg path="#{input}"/>
</java>
<echo>Lessjs: generated #{output}</echo>
</sequential>
</macrodef>
<target name="main">
<echo>compiling less css</echo>
<fileset dir="${css.dir}" id="myfile">
<filename name="**/*.less" />
</fileset>
<property name="lessfilename" refid="myfile"/>
<propertyregex property="cssfilename"
input="${lessfile}"
regexp="^(.*)\.less$"
replace="^\1\.css$"
casesensitive="true" />
<lessjs input="lessfile" output="cssfilename"/>
</target>
</project>
You could use the <fileset> to include all the less files need to be compiled. Later, you could use<mapper> to mark the corresponding detination css file.
<project name="test" default="main" basedir="../../">
<property name="css.dir" location="public/css"/>
<property name="tool.less" location="bin/less/less-rhino-1.1.3.js"/>
<property name="tool.rhino" location="bin/tools/rhino/js.jar"/>
<target name="less" description="Convert LESS to CSS then concatenate and Minify any stylesheets">
<echo message="Converting LESS to CSS..."/>
<!-- Clear the former compiled css files -->
<delete includeemptydirs="true">
<fileset dir="${css.dir}" includes="*.css, **/*.css" defaultexcludes="false"/>
</delete>
<apply dir="${css.dir}" executable="java" parallel="false" failonerror="true">
<!-- Give the input bundle of less files-->
<fileset dir="${css.dir}">
<include name="*.less"/>
</fileset>
<arg value="-jar" />
<arg path="${tool.rhino}" />
<arg path="${tool.less}" />
<srcfile/>
<!-- Output the compiled css file with corresponding name -->
<mapper type="glob" from="*.less" to="${css.dir}/*.css"/>
<targetfile/>
</apply>
</target>
</project>
I was able to piece together a working solution with the help of a couple of SO answers:
ANT script to compile all (css) LESS files in a dir and subdirs with RHINO
How to correctly execute lessc-rhino-1.6.3.js from command line
I had to download LESS 1.7.5 from GitHub and modify the Ant target to look like this. The -f argument and LESS JavaScript was key:
<property name="css.dir" value="WebContent/css"/>
<property name="less.dir" value="less"/>
<property name="tool.rhino.jar" value="test-lib/rhino-1.7R4.jar"/>
<property name="tool.rhino.lessc" value="test-lib/lessc-rhino-1.7.5.js"/>
<property name="tool.rhino.less" value="test-lib/less-rhino-1.7.5.js"/>
<target name="compile-less" description="compile css using LESS">
<apply dir="${css.dir}" executable="java" parallel="false" failonerror="true">
<fileset dir="${less.dir}">
<include name="styles.less"/>
</fileset>
<arg value="-jar"/>
<arg path="${tool.rhino.jar}"/>
<arg value="-f"/>
<arg path="${tool.rhino.less}"/>
<arg path="${tool.rhino.lessc}"/>
<srcfile/>
<mapper type="glob" from="*.less" to="${css.dir}/*.css"/>
<targetfile/>
</apply>
</target>
If anyone else is coming to this question recently, as I did, they may find that the less-rhino-1.1.3.js file given in the other answers does not work with the latest version of Rhino (which for me, as of now, is 1.7R4 from MDN). But the 1.4.0 version does, which can be obtained from Github here. So the relevant snippet from my build.xml, using these later versions, is shown. Note that I'm only compiling a single .less file to a single .css file, so no iteration or mappers are used (but obviously you can get those from the other answers). Other tweaks I made were to provide the output file as the final arg to less instead of capturing output from the Ant forked process, and to remove the dependency on ant-contrib stuff (not needed for the simple one-file case).
<property name="tool.rhino" value="build/lesscss/rhino1_7R4/js.jar" />
<property name="tool.less" value="build/lesscss/less-rhino-1.4.0.js" />
<property name="single-input-lesscss-file" value="/path/to/my/style.less" />
<property name="single-output-css-file" value="/output/my/style.css" />
<target name="compileLessCss" description="Compile the single less file to css">
<sequential>
<java jar="${tool.rhino}" fork="true">
<arg path="${tool.less}" />
<arg path="${single-input-lesscss-file}" />
<arg path="${single-output-css-file}" />
</java>
</sequential>
</target>
If maven is an option for you, you could try wro4j-maven-plugin or wro4j-runner (which is a command line utility).
Using one of these, all you have do is to create an resource model descriptor (wro.xml):
<groups xmlns="http://www.isdc.ro/wro">
<group name="g1">
<css>/path/to/*.less</css>
</group>
</groups>
The rest will be handled by the wro4j library. No need to carry about how rhino works or other details.
Disclaimer: I'm working on wro4j project
I had the same issue. I developed a solution using ant-contrib. It expects all of your .less files to be in one flat directory and to be moved to another flat directory. It will change the file extension to .css in the process.
<property name="tool.rhino" value="/rhino/js.jar" />
<property name="tool.less" value="src/js/less-rhino-1.1.3.js" />
<property name="tool.ant-contrib" value="/ant-contrib/ant-contrib-1.0b3-1.0b3.jar" />
<property name="less-files-dir" value="src/css/" />
<property name="css-files-dir" value="build/css/" />
<target name="compilecss" depends="setup-ant-contrib-taskdef, get-less-files-in-dir" description="DO THIS THING">
<for list="${less-files-to-convert}" param="file-name" trim="true" delimiter=",">
<sequential>
<propertyregex property="file-name-without-extension"
input="#{file-name}"
regexp="(.*)\..*"
select="\1"
override="yes" />
<java jar="${tool.rhino}" fork="true" output="${css-files-dir}${file-name-without-extension}.css">
<arg path="${tool.less}" />
<arg path="${less-files-dir}#{file-name}" />
</java>
<echo>Lessjs: generated ${css-files-dir}${file-name-without-extension}.css</echo>
</sequential>
</for>
</target>
<target name="check-for-ant-contrib">
<condition property="ant-contrib-available">
<and>
<available file="${tool.ant-contrib}"/>
</and>
</condition>
<fail unless="ant-contrib-available" message="Ant-Contrib is not available."/>
</target>
<target name="setup-ant-contrib-taskdef" depends="check-for-ant-contrib">
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<path location="${tool.ant-contrib}" />
</classpath>
</taskdef>
</target>
<target name="get-less-files-in-dir">
<var name="files-list" value="" />
<for param="file">
<path>
<fileset dir="${less-files-dir}" includes="**/*.less" />
</path>
<sequential>
<propertyregex property="file-name-and-relative-path"
input="#{file}"
regexp=".*\\(.*)"
select="\1"
override="yes" />
<echo>file name: ${file-name-and-relative-path}</echo>
<if>
<equals arg1="${files-list}" arg2="" />
<then>
<var name="files-list" value="${file-name-and-relative-path}" />
</then>
<else>
<var name="files-list" value="${files-list},${file-name-and-relative-path}" />
</else>
</if>
</sequential>
</for>
<property name="less-files-to-convert" value="${files-list}" />
<echo>files to convert: ${less-files-to-convert}</echo>
</target>
I was unable to get this to run using a JDK 1.6 since the javascript stuff has been incorporated to the JDK. The JDK does have a jrunscript executable in the distribution but when I try to run the less-rhino.js file it fails to recognize any readFile() function. Has anyone looked into that. Otherwise I may be giving the lesscss-engine a shot and enhancing it to understand filesets.

Resources