how to write ant script to check a given string is a file or directory - ant

how to use write ant script to check a file is a file or directory???
Given a string "C:\test\application\Services\Test"
I need to know this string
"C:\test\application\Services\Test"
is a file or directory,
I use following script to check, looks like cannot decide it is s a file or directory
<if>
<available file="${sourceFile}" />
<then>
<echo> It is a File ${sourceFile}</echo>
<copyfile src="${sourceFile}" dest="${targetFile}" />
<echo> Single file copied: sourceFile = ${sourceFile}</echo>
</then>
<else>
<if>
<available file="${dir}" type="dir" />
<then>
<echo> It is a Directory: ${sourceFile}</echo>
<copy todir="${targetFile}">
<fileset dir="${sourceFile}" />
</copy>
<echo> Single dir copied: sourceFile = ${sourceFile}</echo>
</then>
</if>
</else>
</if>
How to use ant to do it???
Thanks

The if/else tasks are not part of standard ANT (requires 3rd party jar)
Conditional execution of targets is performed as follows:
<project name="demo" default="process">
<property name="sourceFile" location="C:\test\application\Services\Test"/>
<available property="sourceFile.is.a.file" file="${sourceFile}" type="file"/>
<available property="sourceFile.is.a.dir" file="${sourceFile}" type="dir"/>
<target name="process" depends="process-file,process-dir"/>
<target name="process-dir" if="sourceFile.is.a.dir">
<echo message="${sourceFile} is a dir"/>
</target>
<target name="process-file" if="sourceFile.is.a.file">
<echo message="${sourceFile} is a file"/>
</target>
</project>

Related

ant: condition command does not find pattern when pattern is a file path

I am using the following code with the idea of finding a file in a directory that is also part of a list in a file:
<loadfile property="ReportFileContent" srcFile="${ReportFile}"/>
<for param="file">
<path>
<fileset dir="${MainDir}" includes="**/**"/>
</path>
<sequential>
<basename file="#{file}" property="#{file}" />
<condition property="found-file${index2}">
<matches pattern="#{file}" string="${ReportFileContent}"/>
</condition>
<if>
<isset property="found-file${index2}"/>
<then>
<echo message=" Found file #{file}" level="warning" />
</then>
<else>
<echo message="Not Found file #{file}" level="warning" />
</else>
</if>
<math result="index2" operand1="${index2}" operation="+" operand2="1" datatype="int" />
</sequential>
</for>
The command is not working though as it is not finding the file that is available in ${ReportFileContent}.
The content of the ReportFileContent property is the following:
c:\___tools\test\file1.txt;2
c:\___tools\test\file2.txt;2
c:\___tools\test\file3.txt;2
Any idea why the condition is not working correctly?
Thanks
Tony

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>

copy doesn't support the nested "if" element in Ant-contrib Nested Loop

I need to copy all dml.sql files to inside DB2_List.txt file if DML.sql file is present. But after executing this file i'm getting error like this:
copy doesn't support the nested "if" element.
Please let me know if you have any better idea about the nested loop in Ant.
<available file="DB/DML.sql" property="db.check.present"/>
<copy file="DB/DDL.sql" tofile="DB2/DB2_List.txt" >
<if>
<equals arg1="${db.check.present}" arg2="true"/>
<then>
<filterchain>
<concatfilter append="DB/DML.sql" />
<tokenfilter delimoutput="${line.separator}" />
</filterchain>
</then>
</if>
</copy>
It is possible to accomplish what you are after, you just have to approach it quite differently in Ant. Just note that you will need to utilize separate targets.
<target name="db.check">
<available file="DB/DML.sql" property="db.check.present"/>
</target>
<target name="db.copy" depends="db.check" if="db.check.present">
<copy file="DB/DDL.sql" tofile="DB2/DB2_List.txt" >
<filterchain>
<concatfilter append="DB/DML.sql" />
<tokenfilter delimoutput="${line.separator}" />
</filterchain>
</copy>
</target>
Take a look at Ant 1.9.1 which supports special if/unless attributes on tags. This might be possible:
<project name="mysterious.moe" basedir="." default="package"
xmlns:if="ant:if"
xmlns:unless="ant:unless"/>
<target name="db.copy">
<available file="DB/DML.sql" property="db.check.present"/>
<copy file="DB/DDL.sql"
tofile="DB2/DB2_List.txt">
<filterchain if:true="db.ceck.present">
<concatfilter append="DB/DML.sql" />
<tokenfilter delimoutput="${line.separator}" />
</filterchain>
</copy>
<target>
...
</project>
Otherwise, you'll have to use two separate copies. You can't put <if> antcontrib inside tasks. Only around tasks:
<available file="DB/DML.sql" property="db.check.present"/>
<if>
<equals arg1="${db.check.present}" arg2="true"/>
<then>
<copy file="DB/DDL.sql" tofile="DB2/DB2_List.txt" >
<filterchain>
<concatfilter append="DB/DML.sql" />
<tokenfilter delimoutput="${line.separator}" />
</filterchain>
</copy>
</then>
<else>
<copy file="DB/DDL.sql" tofile="DB2/DB2_List.txt" >
</else>
</if>
</copy>

Structure ant projects

I am currently writing an ant project xml file and I am looking for some hints and tips to improve the structure and readability of the project.
<target name="eatnutsOnClient" >
<monkey.eatnuts clientName="${clientName}" label="${nutLabel}" />
<if><not> <equals arg1="${returnCode}" arg2="0"/> </not><then>
<echo message="eatnuts-[${nutlabel}]_[${returnCode}]${line.separator}" file="${reachedFile}" append="true" />
</then></if>
</target>
<target name="eatnuts" depends="createClient,eatnutsOnClient,destroyClient"/>
In order to manage the return codes I would like to have the possibility to replace the full if section that I need to replicate over quite some targets by a sort of function which I can call to handle the returncode logic. I guess one option would be to create a target which only contains the if section and add it to the depend list of each task? Are there better ways?
An Ant <macrodef> provides a function-like way to share code:
<project name="ant-macrodef-echo" default="run">
<taskdef resource="net/sf/antcontrib/antlib.xml" />
<macrodef name="echo-macrodef">
<attribute name="returnCode"/>
<sequential>
<if>
<not>
<equals arg1="#{returnCode}" arg2="0"/>
</not>
<then>
<echo message="#{returnCode}" />
</then>
</if>
</sequential>
</macrodef>
<target name="run">
<echo-macrodef returnCode="42"/>
<echo-macrodef returnCode="0"/>
<echo-macrodef returnCode="-9"/>
</target>
</project>
Results:
run:
[echo] 42
[echo] -9

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>

Resources