ANT: several filesets for the javac task - ant

I have a ANT build file with two different filesets:
<fileset id="fs1"> <include name="source1\**" /> </fileset>
<fileset id="fs2"> <include name="source2\**" /> </fileset>
and want to use both of them in the same javac task.
Of course, I could write
<javac ...>
<include name="source1\**" />
<include name="source2\**" />
</javac>
but I want the selection of the files occurs outside, because my javac-task will be called several times with different parameters.
A solution would be to copy all the files in a temp directory and call javac on it. But you will admit it is not very satisfying...
More over: is there a solution to concatenate two filesets in a single one?

I've found a solution, using patternset.
<patternset id="ps1"> <include name="source1\**" /> </patternset>
<patternset id="ps2"> <include name="source2\**" /> </patternset>
<javac ...>
<patternset>
<patternset refid="ps1" />
<patternset refid="ps2" />
</patternset>
</javac>

Related

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.

how to reuse the definition of a number of filesets?

I have a number of tasks in my build.xml that all utilize the same set of filesets. E.g. something like the following (I've retain the actual names of the tasks - related to the cobertura coverage tool - but the nature of the enveloping task is immaterial to this question).
<target name="coverage-report">
<cobertura:cobertura-report destdir="${coverage.xml.dir}" format="xml">
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
<fileset dir="${componentFoo.dir}/src">
<include name="**/*.java" />
</fileset>
</cobertura:cobertura-report>
</target>
<target name="summary-coverage-report">
<cobertura:cobertura-report destdir="${coverage.summaryxml.dir}" format="summaryXml">
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
<fileset dir="${componentFoo.dir}/src">
<include name="**/*.java" />
</fileset>
</cobertura:cobertura-report>
</target>
<target name="alternate-coverage-report">
<cobertura:cobertura-report destdir="${coverage.html.dir}">
<fileset dir="${src.dir}">
<include name="**/*.java"/>
</fileset>
<fileset dir="${componentFoo.dir}/src">
<include name="**/*.java" />
</fileset>
</cobertura:cobertura-report>
</target>
What I would like to do is to be able to define once this recurring set of filesets and reuse it. Now, there's a related SO question on how to use the same fileset in multiple places but that's not working here as I have a number of filesets, not just one. I also tried wrapping the filesets inside a macrodef and expanding the macrodef when needed but I get the message that the these tasks "don't support the nested [name of macrodef] element". So I guess macrodefs in Ant can only be used as high-level tasks and cannot be expanded in arbitrary places.
So is there a way to reuse a definition of a number of filesets in Ant?
This would be easy if the cobertura tasks accepted arbitrary resource collections instead of being hard-coded to just fileset - it may be worth submitting a feature request to this end. For example with a copy task:
<resources id="filesets">
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
<fileset dir="${componentFoo.dir}/src">
<include name="**/*.java" />
</fileset>
</resources>
<copy todir="dest">
<resources refid="filesets"/>
</copy>
You can fall back to the purely XML-level and use an entity reference:
<!DOCTYPE project [
<!ENTITY cobFilesets '<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
<fileset dir="${componentFoo.dir}/src">
<include name="**/*.java" />
</fileset>'>
]>
<project ....>
<target name="coverage-report">
<cobertura:cobertura-report destdir="${coverage.xml.dir}" format="xml">
&cobFilesets;
</cobertura:cobertura-report>
</target>
</project>

How to to control the order of merge in Ant file

I have this code which takes all the files in the folder collection and merges them with the covers.js file. The problem is there are 2 files inside of collections that need to be merged below covers.
But possibly I may want to control the order of how the files are being merged from the collection
folder. IS there a dependency attribute I can use.
<target name="merge box">
<echo>${box.file}</echo>
<concat destfile="${box.file}" fixlastline="yes" append="no">
<fileset dir="${js.src.dir}/components/covers/" includes="**/*.js"/>
<fileset dir="${js.src.dir}/collection/" includes="**/*.js" excludes="base.js"/>
</concat>
</target>
Update
I also tried this but still doesn't work.
<fileset dir="${js.src.dir}/collection" >
<includesfile name="Templates.js" />
<includesfile name="popup.js" />
<includesfile name="popup-extend.js" />
</fileset>
Latest Update
Tried this and it works but it doesn't hold the order of the include files.
<target name="merge box">
<echo>${box.file}</echo>
<concat destfile="${box.file}" fixlastline="yes" append="no">
<fileset dir="${js.src.dir}/components/covers/" includes="**/*.js"/>
<fileset dir="${js.src.dir}/collection" >
<include name="Templates.js" />
<include name="popup.js" />
<include name="popup-extend.js" />
</fileset>
</concat>
</target>
popup-extend is meant to be merged below the popup code but its not doing that matter what order I put them in it will always put it in this order.
Templates
popup
popup-extend
The order I'm trying to get it in is
Templates
popup-extend
popup
Try this:
<target name="merge box">
<echo>${box.file}</echo>
<concat destfile="${box.file}" fixlastline="yes" append="no">
<fileset dir="${js.src.dir}/components/covers/" includes="**/*.js"/>
<fileset file="${js.src.dir}/collection/Templates.js" />
<fileset file="${js.src.dir}/collection/popup.js" />
<fileset file="${js.src.dir}/collection/popup-extend.js" />
</concat>
</target>
Or look here: How to preserve file order in Ant concat?

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 can I print a fileset to a file, one file name per line?

I have a populated fileset and I need to print the matching filenames into a text file.
I tried this:
<fileset id="myfileset" dir="../sounds">
<include name="*.wav" />
<include name="*.ogg" />
</fileset>
<property name="sounds" refid="myfileset" />
<echo file="sounds.txt">${sounds}</echo>
which prints all the files on a single line, separated by semicolons. I need to have one file per line. How can I do this without resorting to calling OS commands or writing Java code?
UPDATE:
Ah, should have been more specific - the list must not contain directories. I'm marking ChssPly76's as the accepted answer anyway, since the pathconvert command was exactly what I was missing. To strip the directories and list only the filenames, I used the "flatten" mapper.
Here is the script that I ended up with:
<fileset id="sounds_fileset" dir="../sound">
<include name="*.wav" />
<include name="*.ogg" />
</fileset>
<pathconvert pathsep="
" property="sounds" refid="sounds_fileset">
<mapper type="flatten" />
</pathconvert>
<echo file="sounds.txt">${sounds}</echo>
Use the PathConvert task:
<fileset id="myfileset" dir="../sounds">
<include name="*.wav" />
<include name="*.ogg" />
</fileset>
<pathconvert pathsep="${line.separator}" property="sounds" refid="myfileset">
<!-- Add this if you want the path stripped -->
<mapper>
<flattenmapper />
</mapper>
</pathconvert>
<echo file="sounds.txt">${sounds}</echo>
Since Ant 1.6 you can use toString:
<echo file="sounds.txt">${toString:myfileset}</echo>

Resources