[ant] How to exclude a directory from ant fileset, based on directories contents

How can I create an ant fileset which excludes certain directories based on the contents of the directory?

I use ant to create a distribution jar which has each localization in separate directories, some of which are incomplete and should not be released.

I would like to add something to the directory (for example a file named incomplete.flag) so that ant excludes the directory. Then I can delete the file when translation is complete, and include it in the build without modifying build.xml.

Given this directory structure:

proj
+ locale
  + de-DE
  + en-US
  + fr-FR

This fileset excludes all incompelte.flag files, but how can I exclude the entire directories that contain them?

  <fileset dir="${basedir}">
    <include name="locale/"/>
    <exclude name="locale/*/incomplete.flag">
  </fileset>

I can write an ant task if need be, but I'm hoping the fileset can handle this use case.

This question is related to ant fileset

The answer is


This is possible by using "**" pattern as following.

<exclude name="maindir/**/incomplete.flag"/>

the above 'exclude' will exclude all directories completely which contains incomplete.flag file.


it works for me with a jar target:

<jar jarfile="${server.jar}" basedir="${classes.dir}" excludes="**/client/">
  <manifest>
    <attribute name="Main-Class" value="${mainServer.class}" />
  </manifest>
</jar>

this code include all files in "classes.dir" but exclude the directory "client" from the jar.


I think one way is first to check whether your file exists and if it exists to exclude the folder from copy:

<target name="excludeLocales">

    <property name="de-DE.file" value="${basedir}/locale/de-DE/incompelte.flag"/>
    <available property="de-DE.file.exists" file="${de-DE.file}" />

    <copy todir="C:/temp/">
        <fileset dir="${basedir}/locale">
            <exclude name="de-DE/**" if="${de-DE.file.exists}"/>
            <include name="xy/**"/>
        </fileset>
    </copy>
</target>

This should work also for the other languages.


The following approach works for me:

<exclude name="**/dir_name_to_exclude/**" />

Here's an alternative, instead of adding an incomplete.flag file to every dir you want to exclude, generate a file that contains a listing of all the directories you want to exclude and then use the excludesfile attribute. Something like this:

<fileset dir="${basedir}" excludesfile="FileWithExcludedDirs.properties">
  <include name="locale/"/>
  <exclude name="locale/*/incomplete.flag">
</fileset>

Hope it helps.


There is actually an example for this type of issue in the Ant documentation. It makes use of Selectors (mentioned above) and mappers. See last example in http://ant.apache.org/manual/Types/dirset.html :

<dirset id="dirset" dir="${workingdir}">
   <present targetdir="${workingdir}">
        <mapper type="glob" from="*" to="*/${markerfile}" />
   </present>
</dirset>

Selects all directories somewhere under ${workingdir} which contain a ${markerfile}.


Answer provided by user mgaert works for me. I think it should be marked as the right answer.

It works also with complex selectors like in this example:

<!-- 
    selects only direct subdirectories of ${targetdir} if they have a
    sub-subdirectory named either sub1 or sub2
-->
<dirset dir="${targetdir}" >
    <and>
        <depth max="0"/>
        <or>
            <present targetdir="${targetdir}">
                <globmapper from="*" to="*/sub1" />
            </present>
            <present targetdir="${targetdir}">
                <globmapper from="*" to="*/sub2" />
            </present>
        </or>
    </and>
</dirset>

Thus, having a directory structure like this:

targetdir
+-- bar
¦   +-- sub3
+-- baz
¦   +-- sub1
+-- foo
¦   +-- sub2
+-- phoo
¦   +-- sub1
¦   +-- sub2
+-- qux
    +-- xyzzy
        +-- sub1

the above dirset would contain only

baz foo phoo
(bar doesn't match because of sub3 while xyzzy doesn't match because it's not a direct subdirectory of targetdir)


You need to add a '/' after the dir name

<exclude name="WEB-INF/" />

works for me:

<target name="build2-jar" depends="compile" >
   <jar destfile="./myJjar.jar">
        <fileset dir="./WebContent/WEB-INF/lib" includes="hibernate*.jar,mysql*.jar" />
        <fileset dir="./WebContent/WEB-INF/classes" excludes="**/controlador/*.class,**/form/*.class,**/orm/*.class,**/reporting/*.class,**/org/w3/xmldsig/*.class"/>
   </jar>