ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dominique Devienne <>
Subject RE: NOT A SOLUTION: Modifying a DirSet (or any AbstractFileSet) f rom within a <script>
Date Tue, 16 Sep 2003 14:22:26 GMT
> From: Stefan Bodewig []
> > From: Ken Gentle []
> > Part of the problem is that AbstractFileSet creates a new
> > DirectoryScanner on each call to "getDirectoryScanner"
> This is so that it can pick up changes that have happened between
> invocations.  Part of fileset's contract is that the files it returns
> actually exist.
> The silly example
> <delete ...>
>   <fileset id="foo" .../>
> </delete>
> <copy ...>
>   <fileset refid="foo"/>
> </copy>
> would certainly violate that contract if the second fileset didn't
> rescan the directory.  OK, it would be enough to rescan instead of
> creating a new DirectoryScanner instance.

Exactly. But the real problem is more that getDirectoryScanner() doesn't
allow to use a custom DirectoryScanner (or FileScanner) easily.

Furthermore, the break between getDS and setupDS is broken by the
setFollowSymlinks() call, which should be in setupDS, but I suspect is not
because it's an afterthought of FileScanner. This means one cannot rely on
setDS to do everything, and since there's no getter on that attribute, I
must also intercept it's setter to get its state!

To have AbstractFileSet use a derived DirectoryScanner, I was thus forced to
duplicate Ant code from getDirectoryScanner(), which is not good (and
setFollowSymlinks, as explained above...)

> > Looking at the Ant sources, one can kind of see how things got this
> > way, through adding features and behavior to DirectoryScanner.  But
> > it sure makes any low-impact enhancement a real pain.
> I agree.

Specifically, the enhancement that I was able to HACK up was the ability to
have what I call FileTransformer's applied on the set of files or
directories normally returned by DirectoryScanner.

     * A filter that transform a set of relative filenames into another
     * set which does not need to be of the same size, but must be rooted
     * into the same basedir, and correspond to existing files on disk.
    public interface FileTransformer {

         * Transforms a set of filenames, into another.
         * @param  basedir the directory all relatives filenames are rooted
         * @param  filenames the relative filenames to transform.
         * @return the filtered relative filenames.
        String[] transform(File basedir, String[] filenames);


These act a bit like GlobalFileSelector (which I've talked about before),
which can take a look at all the files normally selected at once, and do
further processing impossible by looking at each file individually/in
isolation. But with the added flexibility to be able to redefine completely
the files returned, even in term of the number of files returned. For
example, to get the 10 most recent files, do:

      <fileset id="FILES-sorted"
               includes="etc/*, bin/*" />
      <sorter type="last-modified" />
      <filter type="head" />

(The above runs with Ant 1.5.3, it's not vapor-ant)

I didn't code it up, but <mapper>s could also be added. I believe that's
what Alexei wanted??? I'm not sure for the use case though.

The only constraint I put (by contract only) in the FileTransformer is that
the list (since it can be ordered!) of files returned:
* must be rooted in the same basedir of the original <fileset>/<dirset>, and
* must correspond to actual files in that basedir.

This should make the transformations transparent to any user of the
FileSet/DirSet, thru the DirectoryScanner.

Anyways, my hack to find a solution to Ken's problem is ugly (had to derive
FileSet/DirSet/DirectoryScanner!), but it does show that it's easy to code
up something like it, especially if one's willing to modify Ant's code
directly, unlike me.

Whether it's desirable (I think so to some extend) or will be done is
another story ;-) --DD

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message