Ant concat task complain on missing files - ant

<concat destfile="dist/external.js">
<fileset dir=".">
<include name="a.js" />
<include name="b.js" />
</fileset>
</concat>
This won't fail if a or b is missing. I've tried setting optional="false" or asis="true" and it always complains that those attributes don't exist.

If you just want to see a warning from the 'concat' task when a file is missing, you can use afilelistresource collection in place of the 'fileset':
<concat destfile="dist/external.js">
<filelist dir=".">
<file name="a.js" />
<file name="b.js" />
</filelist>
</concat>
Whenb.jsdoesn't exist, that gives the message:
[concat] /Path/.../b.js does not exist.
But proceeds anyway, which is probably not what you want.
One method of checking for the presence of all the files in a resource collection is as follows. Note that you need to add the "antlib:org.apache.tools.ant.types.resources.selectors" namespace to the project to use the resource selectors shown below. (This won't work for Ant versions older than 1.7.0.) Use the Ant fail task to check that no resources are missing.
<project name="stack_overflow"
xmlns:rsel="antlib:org.apache.tools.ant.types.resources.selectors">
<filelist id="my.js.files" dir=".">
<file name="a.js" />
<file name="b.js" />
</filelist>
<restrict id="missing.js.files">
<filelist refid="my.js.files"/>
<rsel:not>
<rsel:exists/>
</rsel:not>
</restrict>
<property name="missing.files" refid="missing.js.files" />
<fail message="These files are missing: ${missing.files}">
<condition>
<length string="${missing.files}" when="greater" length="0" />
</condition>
</fail>
<concat destfile="dist/external.js">
<filelist refid="my.js.files" />
</concat>
</project>
When run, as before withb.jsmissing, this fails the build before the 'concat' task with:
BUILD FAILED
/Path/.../build.xml:17: These files are missing: /Path/.../b.js

Related

Read the each file name and check for the string using ant

I have particular requirement. I have multiple reports file in particlar directly. Currently I build up ant script reading all files and checking for the particular string using the below code.
<target name="GenerateReports" >
<property name="search.string" value="Internal Error" />
<fileset id="existing" dir="${report.dir}">
<patternset id="files">
<include name="*.txt" />
</patternset>
</fileset>
<fileset id="matches" dir="${report.dir}">
<patternset refid="files" />
<contains text="${search.string}" />
</fileset>
<fail message="Found '${search.string}' in one or more test cases results in '${report.dir}' One or more test cases are failed">
<condition>
<resourcecount when="greater" count="0" refid="matches" />
</condition>
</fail>
</target>
But i want to read each file and give the name of the file where the error exists in my report file.
How to read the each file name and read the content also.
<foreach target="-List-File-Names" param="foreach.file" inheritall="true">
<path>
<fileset dir="${report.dir}" includes="*.txt">
<contains text="${search.string}" />
</fileset>
</path>
</foreach>
<target name="-List-File-Names">
<dirname property="file.dir" file="${foreach.file}"/>
<!-- dirname now holds the file -->
</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.

Combine filesets using Ant

I have 2 different filesets defined in Ant as follows:
<fileset id="fileset1" dir="${classes.dir}">
</fileset>
<zipfileset id="fileset2" src="myArchive.zip" includes="**/*.class">
</zipfileset>
I want to create a third fileset which is the union of both the above filesets
<fileset id="merged">
</fileset>
Can someone tell me how to do this ? Is it even possible to do something like that ?
Thanks in advance!
One way to do this is with Ant resource collections, in particular a union.
<fileset id="fileset1" dir="${classes.dir}" />
<zipfileset id="fileset2" src="myArchive.zip" includes="**/*.class" />
<union id="onion">
<resources refid="fileset1" />
<resources refid="fileset2" />
</union>
Then you can refer to the 'onion' anywhere you might use a fileset, e.g.
<copy todir="dest">
<resources refid="onion" />
</copy>
I recommend using generic resources elements rather than filesets for maximum flexibility.
Try this: I think it should work, since <fileset> is an implicit <patternset>.
<fileset id="fileset1" dir="${classes.dir}">
</fileset>
<zipfileset id="fileset2" src="myArchive.zip" includes="**/*.class">
</zipfileset>
EDIT: odd. This perhaps?
<patternset id="merged">
<patternset refid="fileset1" />
<patternset refid="fileset2" />
</patternset>
problem with fileset is, that it requires a directory as a base upon it applies the patternset. Which means you have to find a common base directory that is shared by all filesets.
A <pathconvert> Task can take filesets via refid. You can put several filesets (e.g. from various build targets to assemble a compound set in a root/main target for a modular build environment):
<project name="root" basedir="." xmlns:if="ant:if" xmlns:unless="ant:unless">
<!--
it's important to take the xmlns:features in your project head
otherwhise this code won't work
-->
<target name="init">
<!-- set some common prerequisites -->
<property name="prerequisite.property.xyz" value="xyz" />
</target>
<target name="targetA" depends="init">
<fileset dir="${common.basedir}${file.separator}${targetA.subdir}" id="targetA.fileset">
<include name="**/*.html" />
</fileset>
<property name="targetA.fileset.exists" value="true" />
</target>
<target name="targetB" depends="init">
<fileset dir="${common.basedir}${file.separator}${targetB.subdir}" id="targetB.fileset">
<include name="**/*.java" />
</fileset>
<property name="targetB.fileset.exists" value="true" />
</target>
<target name="targetC" depends="init">
<fileset dir="${common.basedir}${file.separator}${targetC.subdir}" id="targetC.fileset">
<include name="**/*.class" />
</fileset>
<property name="targetC.fileset.exists" value="true" />
</target>
<target name="root" depends="init">
<pathconvert property="all.files.as.commaseparated.path" pathsep="," dirsep="/">
<fileset refid="targetA.fileset" if:true="${targetA.fileset.exists}" />
<fileset refid="targetB.fileset" if:true="${targetB.fileset.exists}" />
<fileset refid="targetC.fileset" if:true="${targetC.fileset.exists}" />
<map from="${common.basedir}/" to="" />
</pathconvert>
<!-- assemble new fileset from paths as comma separated property string -->
<fileset id="new.refid" dir="${common.basedir}" includes="${all.files.as.commaseparated.path}" />
</target>
</project>
This can be called via command line like:
ant targetA targetB targetC root
or
ant targetA root
Be aware that root is always the last target being called.

How to preserve file order in Ant concat?

How to preserve file order in Ant concat?
Simple concat with fileset & includesfile produces rather "random" order, as order is not guaranteed:
<concat destfile="C:/targetdir/concatenated.file">
<fileset dir="C:/sourcedir/">
<includesfile name="C:/targetdir/includes.file" />
</fileset>
</concat>
What I need is concatenation in specific order that the files are listed in the includes file.
So far I've found resourcelist, which should preserve order, but I can't seem to be able to produce any concatenated file with it. :/
<concat destfile="C:/targetdir/concatenated.file">
<resourcelist>
<file file="C:/targetdir/includes.file"/>
<filterchain>
<striplinecomments>
<comment value="#"/>
</striplinecomments>
<prefixlines prefix="C:/sourcedir/"/>
</filterchain>
</resourcelist>
</concat>
Plus, the resourcelist can't seem to handle rows like
LibraryX/A/Stuff/Morestuff/*
Instead the row just produces a ".../Morestuff/* does not exist." -error
Includes file has list of relative paths:
LibraryX/A/Stuff/FileA.txt
LibraryX/A/Stuff/FileB.txt
LibraryX/A/Stuff/FileC.txt
LibraryX/A/Stuff/FileY.txt
I was able to get a filelist working pretty easily:
<concat destfile="C:/targetdir/concatenated.file">
<filelist dir="C:/sourcedir/">
<file name="i.txt" />
<file name="n.txt" />
<file name="o.txt" />
<file name="r.txt" />
<file name="d.txt" />
<file name="e.txt" />
<file name="r.txt" />
</filelist>
</concat>
Hope that helps!
If you are using Ant 1.7+, you can use the sort command
<concat destfile="C:/targetdir/concatenated.file">
<sort>
<fileset dir="C:/sourcedir/">
<include name="C:/targetdir/*.file" />
</fileset>
</sort>
</concat>
You can find the documentation of sort here
[On Ant 1.8.2+] You can also pass the fileset via a sort, and sort on filename, like below:
<concat destfile="./${dir.publish}/${dir.js}/b.main-${build.number}.debug.js">
<sort xmlns:rcmp="antlib:org.apache.tools.ant.types.resources.comparators">
<fileset dir="./${dir.publish}/">
<include name="**/${dir.js.main}/**/*.js"/>
<exclude name="**/${dir.js.main}/**/*.min.js"/>
</fileset>
<rcmp:name />
</sort>
</concat>
Couple of things to watch out for:
Directories are sorted before files
Capitals come before lowercase
UPDATE: Another alternative if you need to manually specify order:
<!-- create a ordered list of all the build files so that CIAPI & CIAPI.widget are built first
(can't find a smarter way to do this, since ant filesets are unordered) -->
<fileset id="a" dir="."><include name="CIAPI/build.project.xml"/></fileset>
<fileset id="b" dir="."><include name="CIAPI.widget/build.project.xml"/></fileset>
<fileset id="c" dir=".">
<include name="**/build.project.xml"/>
<exclude name="CIAPI/build.project.xml" />
<exclude name="CIAPI.widget/build.project.xml" />
</fileset>
<union id="all_build_files">
<fileset refid="a"/>
<fileset refid="b"/>
<fileset refid="c"/>
</union>
Ugly, but, erm, this is ant?
try this, put in alphabetical order
<project name="concatPath" default="full">
<target name="full">
<fileset id="fs" dir="./files" />
<pathconvert refid="fs" property="concatList" pathsep=";" targetos="unix"/>
<echo>${concatList}</echo>
</target>
</project>
this can be used with hierarchical structure of directories, and the order will be the exposed by David.
Remember that XML is not order-dependent, by definition.
To concatenate files in a sorted order, consider using <replace> instead.
Create an order file that defines the order. Then, in your build file:
Copy the order file to the destination file with <copy>
Concatenate your files together into a temporary file with <concat>
Load the files into properties with <loadfile>
Insert the text from those files into the destination file with <replace>
Example order file order_file.txt:
FILE_A_HERE
CONCAT_FILES_HERE
Example ant build file build.xml:
<copy file="order_file.txt" tofile="destination.txt" overwrite="yes">
<concat destfile="tempfile.txt">
<fileset dir="includes/">
<include name="*.txt">
<exclude name="fileA.txt">
</fileset>
</concat>
<loadfile property="fileA" srcFile="includes/fileA.txt" />
<loadfile property="concatFile" srcFile="tempfile.txt" />
<replace file="destination.txt" token="FILE_A_HERE" value="fileA" />
<replace file="destination.txt" token="CONCAT_FILES_HERE" value="concatFile" />

How to fail Ant build if errors are detected in either of two files?

I am using Ant to do a database build by basically using the exec task to run some SQL scripts.
However, there might be errors generated during the script execution (e.g. could not properly drop a connected user, etc) so I check for this by looking through two output log files.
Here's a snippet of the relevant target:
<target name="build">
<echo message="Add foo bar baz"/>
<exec executable="${db.sqlplus}">
</exec>
<echo message="Load x y z"/>
<exec executable="${db.sqlplus}" dir="foobar">
</exec>
<!--Check the log files here-->
<antcall target="check-log-file">
<param name="file.to.check" value="${output.log.1}"/>
</antcall>
<antcall target="check-log-file">
<param name="file.to.check" value="${output.log.2}"/>
</antcall>
<antcall target="fail-if-error"/>
</target>
<!--=============================================================================
Check the file named in the property file.to.check to see if there are errors.
The way this works is to find all lines containing the text "ERROR" and put
them into a separate file. Then it checks to see if this file has non-zero
length. If so, then there are errors, and it sets the property errors.found.
Then it calls the send-email target, which doesn't execute if the
errors.found property isn't set.
-->
<target name="check-log-file"
description="Checks the file (specified in ${file.to.check}) for errors">
<property name="file.errorcount" value="${file.to.check}.errorcount"
description="The file to hold the error lines"/>
<copy file="${file.to.check}" tofile="${file.errorcount}">
<filterchain>
<linecontains>
<contains value="ERROR"/>
</linecontains>
</filterchain>
</copy>
<condition property="errors.found" value="true">
<length file="${file.errorcount}" when="gt" length="0"/>
</condition>
<antcall target="check-log-file-send-email"/>
</target>
<!--=========================================================================
If there are any errors, send an email to let someone know
-->
<target name="check-log-file-send-email" if="errors.found"
description="Sends an email out if error detected">
<resourcecount property="error.count">
<tokens><!-- default tokenizer is a line tokenizer -->
<file file="${file.to.check}.errorcount"/>
</tokens>
</resourcecount>
<echo
message="Database build (${e1.codeline} - ${error.count} errors found..."/>
<antcall target="mail">
<param name="from-address" value="build"/>
<param name="to-list" value="myemail"/>
<param name="subject"
value="Automated database build error report for ${db.host}"/>
<param name="message"
value="See attached log file, ${error.count} error(s)found..."/>
<param name="attach" value="${file.to.check}"/>
</antcall>
</target>
<!--==========================================================================
Fails the database build if errors were detected.
-->
<target name="fail-if-error" if="errors.found">
<echo message="Errors found - setting database fail flag..."/>
<fail message="Errors detected during ${codeline} database build. Check logs."/>
</target>
When there are errors the build does not fail.
I think it's because the antcall task to check the logs does not return the property error.
Found back to the build target, so when fail-if-error is called, that property is unset.
Is that right?
Is there a way to set it up to fail properly?
The antcall will set the property in the scope of its execution, so when you get to your check it is not set. Instead try using a macrodef, this will run in the current scope and set the errors-found property in that scope so the later check can read it. You'd define the macrodef something like this:
<macrodef name="check-log-file">
<attribute name="fileToCheck"/>
<!--note attributes are referenced with an "#" rather than a "$" -->
<property name="file.errorcount" value="#{fileToCheck}.errorcount"/>
<copy file="#{fileToCheck}" tofile="${file.errorcount}">
...
</macrodef>
and call it like this:
<check-log-file fileToCheck="${output.log.1}"/>
<check-log-file fileToCheck="${output.log.1}"/>
Thanks to Rich Seller, who provided the idea of using a macrodef. The macrodef needed a little cleanup (property not allowed inside a macrodef, tasks need to be wrapped in a sequential tag) so I'm providing it here in full:
<macrodef name="check-log-file">
<attribute name="file.to.check"/>
<attribute name="file.errorcount" default="#{file.to.check}.errorcount" description="The file to hold the error lines"/>
<sequential>
<copy file="#{file.to.check}" tofile="#{file.errorcount}">
<filterchain>
<linecontains>
<contains value="ERROR"/>
</linecontains>
</filterchain>
</copy>
<condition property="errors.found" value="true">
<length file="#{file.errorcount}" when="gt" length="0"/>
</condition>
<antcall target="check-log-file-send-email">
<param name="file.to.check" value="#{file.to.check}"/>
</antcall>
</sequential>
</macrodef>
General log file checking with Errors and Warnings
Here is a general macrodef that can be used to scan files for issues. As long as you can write a regexp for the issue, it can check for it...
It can fail or not if the issue is found.
It summarises the issues found, writing them to the Ant output.
The files to scan can be indicated with wildcards.
Here are example calls to check log files for Oracle errors:
Fail on "SP2-" errors
Warn on "ORA-" errors
Warn on "ERROR:" text.
<check_for_errors file.to.check.dir="${buildlogs}" file.to.check.include="*.log" error.pattern="SP2-" />
<check_for_errors file.to.check.dir="${buildlogs}" file.to.check.include="*.log" error.pattern="ORA-" error.action="warn" />
<check_for_errors file.to.check.dir="${buildlogs}" file.to.check.include="*.log" error.pattern="ERROR:" error.action="warn" />
Here are example calls to check for unreplaced tokens in generated sql files, before execution:
<check_for_errors file.to.check.dir="${distdir}" file.to.check.include="**/\*.sql"
error.name="Token" error.pattern="^(?!--).+#[^# ]+#" error.display.find=".*(#[^# ]+#).*" error.display.show=" Token = '\1'"/>
<check_for_errors file.to.check.dir="${distdir}" file.to.check.include="**/*.sql"
error.name="Token" error.pattern="^(?!--).+#\$\{[^ }]+\}" error.display.find=".*(\$\{[^ }]+\}).*" error.display.show=" Token = '\1'"/>
Here is the macrodef:
<macrodef name="check_for_errors">
<attribute name="file.to.check.dir" default="." />
<attribute name="file.to.check.include" default="*.log" />
<attribute name="file.to.check.exclude" default="" />
<attribute name="error.pattern" default="ERROR" />
<attribute name="error.name" default="ERROR" />
<attribute name="error.action" default="fail" />
<attribute name="error.display.find" default="(.+)" />
<attribute name="error.display.show" default=" \1" />
<sequential>
<echo message="Excluding file ${buildlogfile}" level="debug" />
<for param="file.to.check.name">
<fileset dir="#{file.to.check.dir}">
<include name="#{file.to.check.include}"/>
<exclude name="#{file.to.check.exclude}"/>
<exclude name="${buildlogfile}"/>
<containsregexp expression="#{error.pattern}"/>
</fileset>
<sequential>
<echo message="ERROR: #{error.name} found in file '#{file.to.check.name}' :" level="warn" />
<concat>
<fileset file="#{file.to.check.name}" />
<filterchain>
<linecontainsregexp>
<regexp pattern="#{error.pattern}" />
</linecontainsregexp>
<replaceregex pattern="#{error.display.find}" replace="#{error.display.show}" />
</filterchain>
</concat>
<property name="error.check.foundvalues" value="true" />
</sequential>
</for>
<condition property="error.check.fail">
<and>
<matches string="#{error.action}" pattern="fail" />
<isset property="error.check.foundvalues" />
</and>
</condition>
<fail message="ERROR: Fix the above errors and try again. Exiting..." if="error.check.fail"/>
</sequential>
</macrodef>

Resources