Combine filesets using Ant

Viewed 13706

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!

3 Answers

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.

Related