36

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.

Chadwick
  • 12,555
  • 7
  • 49
  • 66
  • Not really an answer, but wouldn't it be sufficient to add the valid directories as `includes` instead of `excluding` the incomplete? – Peter Lang Feb 09 '10 at 22:31
  • 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 Feb 11 '10 at 14:11
  • 1
    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 The file "completed-locales.txt" would list just the completed locales, one on each line: de-DE en-US – mgaert Dec 21 '11 at 07:58

9 Answers9

69

The following approach works for me:

<exclude name="**/dir_name_to_exclude/**" />
Sasha
  • 1,958
  • 1
  • 19
  • 33
  • 11
    Exclusion by directory name, as shown in this answer, is trivial and does not address the question. Please read carefully, the subdirs to be excluded should be only those which contain a file of a specific name. – Chadwick Jun 06 '11 at 08:45
  • 1
    There is no such possibility at this moment. So, all the answers in this topic just recommends some approach. – Sasha Jun 08 '11 at 11:32
  • @Sasha Thanks, I was looking for first part of this question and your answer gave it to me. – randomUser56789 Aug 06 '12 at 11:16
  • Same here. I just needed to exclude a single directory. Thanks. – yellavon Jan 29 '13 at 19:37
  • 1
    does this mean that it will exculde any subdirectories with the name 'dir_name_to_exclude' – frewper Mar 11 '13 at 06:17
21

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

<exclude name="WEB-INF/" />
  • 5
    Exclusion by directory name, as shown in this answer, is trivial and does not address the question. Please read carefully, the subdirs to be excluded should be only those which contain a file of a specific name. – Chadwick Jun 06 '11 at 08:43
  • 1
    "Wonderful" to see that the clearest & simplest & best answer got the fewest vote... – peterh Sep 04 '14 at 14:17
  • @Peter ... Well maybe what __you__ see as clearest and simplest is not what others see as well? Thanks for downvoting :-( – mgaert Sep 04 '14 at 16:03
8

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.

Alonso
  • 1,069
  • 5
  • 12
  • 22
  • This crossed my mind, but I couldn't think of a way to create that excludesfile - any suggestions? I suspect that the same mechanism could just be used to create a fileset. Thoughts? – Chadwick Feb 11 '10 at 14:17
  • I see the problem. I think it depends on the criteria to include or exclude the files. I think you might be able to write a little script to generate the file, but you'll have to go outside ant. – Alonso Feb 11 '10 at 15:21
  • I just realized about ant selects. These can be used in filesets. Check it out http://ant.apache.org/manual/CoreTypes/selectors.html – Alonso Feb 11 '10 at 15:25
6

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

peterh
  • 11,875
  • 18
  • 85
  • 108
mgaert
  • 2,338
  • 21
  • 27
2

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)
Community
  • 1
  • 1
dinwath
  • 41
  • 3
0

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.

Uncle_Sam
  • 1
  • 2
0

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.

Chadwick
  • 12,555
  • 7
  • 49
  • 66
lakhdeep
  • 17
  • 2
  • This would be exactly something I would need but, for the life of me, I can't get it to work... :/ – crappish Sep 16 '11 at 14:12
  • 3
    The above will not exclude any directories. It will only exclude those files matching that pattern, in any subdirectory under maindir. – Eddie Nov 27 '12 at 20:54
  • @Eddie - How to exclude all sub directories irrespectively ? – useranon Nov 17 '16 at 10:49
0

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>

RaZieRSarE
  • 89
  • 4
0

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.

johndoe
  • 27
  • 1
    Exclusion by directory name, as shown in this answer, is trivial and does not address the question. Please read carefully, the subdirs to be excluded should be only those which contain a file of a specific name. – Chadwick Jun 06 '11 at 08:43