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

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>

Related

using if with resourcecontains in and is not returning true value

I'm reading a file that contains a list of files path.
For each file, I would like to know if it contains a substring.
the answer is always false, although part of it should be true.
Here is my target:
<target name="chek-file">
<loadfile property="file" srcfile="c:\tmp\testing.txt"/>
<for param="line" list="${file}" delimiter="${line.separator}">
<sequential>
<echo>#{line}</echo>
<loadfile property="inner_file" srcfile="#{line}"/>
<if>
<resourcecontains resource="${inner_file}" substring="parent" />
<then>
<echo message="this is a jpa jar"/>
</then>
<else>
<echo message="this is NOT a jpa jar"/>
</else>
</if>
</sequential>
</for>
</target>
the echo is typing "this is NOT a jpa jar" for all jars.
Is 'if' not working with 'resourcecontains'?
OK, found two problems:
1) The second load file is actually not needed here because resourcecontains needs to get the file name and not its value.
2) resourcecontains is inherited from <condition>
so the solution should be:
<target name="chek-file">
<loadfile property="file" srcfile="c:\tmp\testing.txt"/>
<for param="line" list="${file}" delimiter="${line.separator}">
<sequential>
<echo>#{line}</echo>
<condition property="substring_found">
<resourcecontains resource="#{line}" substring="JPA>true" />
</condition>
<echo message="substring_found value: ${substring_found}"/>
<if>
<equals arg1="${substring_found}" arg2="true" />
<then>
<echo message="this is a jpa jar"/>
<get_jar_name_no_version property.to.process="#{line}" output.property="linetobeadd" />
</then>
<else>
<echo message="this is NOT a jpa jar"/>
</else>
</if>
<var name="substring_found" unset="true"/>
</sequential>
</for>
</target>

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- How can i compare the list of strings?

<target name="build">
<for list="${platform}" param="platform" trim="true">
<sequential>
<if>
<equals arg1="${platform}" arg2="${project.SuppoortedPlatforms}" />
<then>
<antcall target="package.${platform}" />
</then>
</if>
</sequential>
</for>
</target>
where i'm getting platfrom values at runtime (eg:windows,ios) and project.SuppoortedPlatforms is declared under build.properties (eg:android,ios). how can i compare the list of strings?
could anyone help me to solve this problem?
Thanks,
sandhiya
You are looping over a comma-separated list of platforms, and for each one you're checking if it is contained in the list of supported platforms in project.SuppoortedPlatforms. This should go like this:
<for list="${platform}" param="platformParam" trim="true">
<sequential>
<if>
<contains string="${project.SuppoortedPlatforms}" substring="#{platformParam}" />
<then>
<antcall target="package.#{platformParam}" />
</then>
</if>
</sequential>
</for>
The parameter in the loop should be accessed with # instead of $. Also it would be better to rename the parameter for readability (platformParam instead of platform).
Instead of using contains task, i myself tried with the nested for loop, its cool working fine.
<for list="${platforms}" param="platformparam" trim="true">
<sequential>
<for list="${project.SupportedPlatforms}" param="supplatformparam" trim="true">
<sequential>
<if>
<equals arg1="#{platformparam}" arg2="#{supplatformparam}" />
<then>
<antcall target="package.#{platformParam}" />
</then>
</if>
</sequential>
</for>
</sequential>
</for>

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

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>

Delete files specified via a zipfileset?

I have the following Ant target which extracts contents from a specific .ZIP archive:
<!-- UNPACK-MATH -->
<target name="unpack-math" depends="init-contrib">
<!-- NOTE: the 'unzip' task doesn't fail when it cannot extract over read-only files; however, 'copy' with a 'zipfileset' does. -->
<first id="math.archive">
<fileset dir="${builddir}" includes="MATH_MF*.zip" />
</first>
<if>
<length string="${toString:math.archive}" when="greater" length="0" />
<then>
<copy todir="${basedir}">
<zipfileset src="${toString:math.archive}" />
</copy>
</then>
<else>
<echo message="No math to unpack." />
</else>
</if>
</target>
What I'd like to do now is "clean up" the files that were extracted. However, the following does not work:
<!-- CLEAN-MATH -->
<target name="clean-math" depends="init-contrib">
<first id="math.archive">
<fileset dir="${builddir}" includes="MATH_MF*.zip" />
</first>
<if>
<length string="${toString:math.archive}" when="greater" length="0" />
<then>
<delete>
<zipfileset src="${toString:math.archive}" />
</delete>
</then>
<else>
<echo message="No math to clean." />
</else>
</if>
</target>
I get the following stack trace:
BUILD FAILED
D:\Development\MForce\Games\gamebuild.xml:214: java.lang.ClassCastException: class org.apache.tools.ant.types.resources.ZipResource doesn't provide files
at org.apache.tools.ant.types.resources.comparators.FileSystem.resourceCompare(FileSystem.java:43)
...
Any ideas?
This solution appears to work, but requires unpacking the .ZIP archive (which lists the files you'd like to delete as some other root) first, which I'd prefer to avoid:
<!-- CLEAN-MATH -->
<target name="clean-math" depends="init-contrib">
<first id="math.archive">
<fileset dir="${builddir}" includes="MATH_MF*.zip" />
</first>
<if>
<length string="${toString:math.archive}" when="greater" length="0" />
<then>
<unzip dest="${builddir}/tmp" src="${toString:math.archive}"/>
<delete>
<fileset dir="${basedir}" includes="**/*">
<present present="both" targetdir="${builddir}/tmp"/>
</fileset>
</delete>
<delete dir="${builddir}/tmp"/>
</then>
<else>
<echo message="No math to clean." />
</else>
</if>
</target>

Resources