Read the each file name and check for the string using ant - 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>

Related

apache Ant basename issue with empty input strings

I have the below ant code which gives basename (for ex: abc_01142018.txt) of the file from location input.dir. When the file is available, it works as expected.But when there are no files in input.dir it is picking up a value which I am not passing. I am expecting it to be empty value.
I read about basename and its not mentioned anywhere about how basename works when the input parameter is empty.
<path id="ref-id">
<fileset dir="${input.dir}">
<include name="abc*.txt"/>
</fileset>
</path>
<property name="input.files" refid="ref-id"/>
<basename property="input.file" file="${input.files}" />
There's no need to use Ant's path type or basename task if all you want is a list of file names without parent directories. The fileset type already does this, so just reference its ID instead.
Example:
<target name="test">
<touch file="exists1.txt" />
<touch file="exists2.txt" />
<fileset dir="." id="exists">
<include name="exists*.txt" />
</fileset>
<fileset dir="." id="doesnotexist">
<include name="doesnotexist*.txt" />
</fileset>
<property name="exists" refid="exists" />
<property name="doesnotexist" refid="doesnotexist" />
<echo message="${exists}" />
<echo message="${doesnotexist}" />
</target>

how to use<MacroDef> for recourcecount of all file in folder with different extension

While going through the scenario what i got is that folder collection of different extension file i have use resource count for all extension if i have 3 different extension file than try to get resource count of all file differ with extension
Eg:
<resourcecount property="firstfile">
<fileset dir="${basedir}">
<include name="*.xml" />
</fileset>
</resourcecount>
<echo message="There are ${firstfile} xml in This Folder ${basedir}" />
<resourcecount property="SecondFile">
<fileset dir="${basedir}">
<include name="*.jar" />
</fileset>
</resourcecount>
<echo message="There are ${SecondFile} xml in This Folder ${basedir}" />
How can i use the macrodef for this condition which help in count all file with it
You can do this in many ways, including using plugins, such as ant-contrib, or using ant language extensions. But all of them are overkill compared to this simple build script:
<target name="count">
<countresources type="xml" />
<countresources type="java" />
<countresources type="cpp" />
</target>
<macrodef name="countresources">
<attribute name="type" />
<sequential>
<resourcecount property="#{type}.count">
<fileset dir="${basedir}">
<include name="*.#{type}" />
</fileset>
</resourcecount>
<echo message="There are ${#{type}.count} #{type} files in folder ${basedir}" />
</sequential>
</macrodef>
Hope this helps.

Generating MD5 for files in an ant-contrib for loop in ANT

I am selecting set of files using file set and then using them to generate the checksum of all the files in the selected fileset
here is my script
<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="MyTask1" basedir="." default="jar">
<property name="cms.dir" value="D:\Test" />
<property name="comma" value="," />
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<target name="A">
<fileset id="src.files" dir="${cms.dir}" casesensitive="yes">
<include name="**/*.uim"/>
<include name="**/*.properties"/>
<include name="**/*.txt"/>
</fileset>
<pathconvert pathsep="${line.separator}" property="sounds" refid="src.files">
<!-- To get the names of the files only then use mapper-->
<!-- <mapper type="flatten" />-->
</pathconvert>
<delete file="sounds.txt"/>
<for list="${sounds}" delimiter="${line.separator}" param="mod">
<sequential>
<checksum file="#{mod}" property="MD5_Value"/>
<echo file="sounds.txt" append="true">#{mod}${comma}${MD5_Value}${line.separator}</echo>
</sequential>
</for>
<!--<checksum file="Test.txt" property="foobarMD5"/>-->
<!--<echo file="sounds.txt">${foobarMD5}</echo>-->
</target>
</project>
However its failing and its generating duplicate MD5 value here is my output
D:\Test\Test1.txt,6d326741a99efbcda928e5096b43cb9a
D:\Test\Test2.txt,6d326741a99efbcda928e5096b43cb9a
Any help ...
The checksum task can process filesets...
<checksum>
<fileset dir=".">
<include name="foo*"/>
</fileset>
</checksum>
Lot simpler than using the for task, which is not part of standard ANT.

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.

Ant concat fileset separator

When using concat with fileset in Ant, how do I make an action happen for each element in the fileset. Such as, adding a string:
<fileset dir="${project.path.scripts-library}"
excludes="!*.js, **/*.bak, **/dev.*"
>
<type type="file" />
<include name="**/0*.js" />
<include name="**/1*.js" />
<string>test</string>
</fileset>
Or echoing the current file name for each file in the fileset (and, how do I GET the file name for the current file???):
<fileset dir="${project.path.scripts-library}"
excludes="!*.js, **/*.bak, **/dev.*"
>
<echo file="${app.path.file}"
append="true"
message=",${the.file.name}" />
<type type="file" />
<include name="**/0*.js" />
<include name="**/1*.js" />
</fileset>
I think there is no such thing in default ant. The closest one is <apply>, but it's system specific:
<apply executable="echo"> <!-- run this command with each file name -->
<fileset dir="/tmp" includes="**/*.*"/>
</apply>
Also you can install ant-contrib to enable <for> task:
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
<for param="file">
<path>
<fileset dir="/tmp" includes="**/*.*"/>
</path>
<sequential> <!-- run any task here -->
<echo>file [#{file}]</echo>
</sequential>
</for>

Resources