34
votes

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.

9
Not really an answer, but wouldn't it be sufficient to add the valid directories as includes instead of excluding the incomplete?Peter Lang
using 'includes' does not solve the use case, since the goal is to not modify the build.xml as locales are added and completed.Chadwick
You may want to keep the positive list of includes not in build.xml (we're not supposed to change that, which makes sense), but in a separate file. This file would then be loaded via <fileset dir="proj/locales" includesfile="proj/locales/completed-locales.txt"/> The file "completed-locales.txt" would list just the completed locales, one on each line: de-DE en-USmgaert

9 Answers

65
votes

The following approach works for me:

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

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

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

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.

6
votes

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}.

2
votes

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
barxyzzytargetdir
0
votes

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.

0
votes

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.

0
votes

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.

0
votes

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>