How to exclude a directory from ant fileset, based on directories contents
Asked Answered
F

9

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.

Foch answered 9/2, 2010 at 22:19 Comment(3)
Not really an answer, but wouldn't it be sufficient to add the valid directories as includes instead of excluding the incomplete?Krieger
using 'includes' does not solve the use case, since the goal is to not modify the build.xml as locales are added and completed.Foch
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-USHara
S
70

The following approach works for me:

<exclude name="**/dir_name_to_exclude/**" />
Synaeresis answered 9/11, 2010 at 9:1 Comment(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.Foch
There is no such possibility at this moment. So, all the answers in this topic just recommends some approach.Synaeresis
@Synaeresis Thanks, I was looking for first part of this question and your answer gave it to me.Lu
Same here. I just needed to exclude a single directory. Thanks.Utimer
does this mean that it will exculde any subdirectories with the name 'dir_name_to_exclude'Arella
V
22

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

<exclude name="WEB-INF/" />
Vichy answered 17/11, 2010 at 17:1 Comment(3)
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.Foch
"Wonderful" to see that the clearest & simplest & best answer got the fewest vote...Visby
@Peter ... Well maybe what you see as clearest and simplest is not what others see as well? Thanks for downvoting :-(Hara
L
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.

Livonia answered 11/2, 2010 at 3:6 Comment(3)
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?Foch
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.Livonia
I just realized about ant selects. These can be used in filesets. Check it out ant.apache.org/manual/CoreTypes/selectors.htmlLivonia
H
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}.

Hara answered 22/12, 2011 at 23:30 Comment(0)
M
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)
Malkamalkah answered 5/1, 2016 at 16:25 Comment(0)
J
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.

Jase answered 29/10, 2010 at 15:24 Comment(3)
This would be exactly something I would need but, for the life of me, I can't get it to work... :/Scintillant
The above will not exclude any directories. It will only exclude those files matching that pattern, in any subdirectory under maindir.Shira
@Shira - How to exclude all sub directories irrespectively ?Sayer
R
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.

Reaper answered 3/6, 2011 at 23:35 Comment(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.Foch
T
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.

Tide answered 26/8, 2015 at 7:19 Comment(0)
L
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>

Liger answered 29/3, 2017 at 15:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.