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

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

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

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>

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>

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