You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Kurt Huwig <ku...@iku-netz.de> on 2001/07/16 22:57:40 UTC

Ant2 suggestions

Hello!
 
I just want to give comments about Ant and my suggestions about the upcoming
Ant2. To give some background about me, I am a Java programmer since early
1997 and wrote several commercial applications of >600k code each. I have quite
some experience with 'make' and are using 'ant' for several weeks now.
 
Some general thoughts first; you can skip these and start below where the
underlined headings are.
 
Both make and ant serve to ease the job of creating files out of other files.
You have for example source code and want a jar file of compiled code out of
it.
 
'make' uses a bottom-up approach. You give several rules that tell make how to
generate files out of other files, e.g.
 
  %.class: %.java
    $(JAVAC) $(JAVAFLAGS) $*.java
 
this says "if you want a .class-file, you need a .java-file. Then you apply
this command to it". The same happens with jar-files:
 
  myapp.jar: A.class B.class C.class
    jar cvf myapp.jar A.class B.class C.class
 
When you run make, you tell it what you want and make checks the rules how to
reach the goal. I think this is the way Prolog works. You give it a set of
rules and then ask it to create something based on this rule, but I can be
completely wrong, as I don't know any Prolog :-)
 
With ant, you have a more top-down and programmatic approach. You state
exactly the steps to reach the goal. You can do the same thing with make, by
just using non-file targets like this
 
  <target name="a" depends="b">
    // do a
  </target>
 
  <target name="b"/>
    // do b
  </target>
 
is with make like
 
  a: b
    // do a
 
  b:
    // do b
 
What ant lacks compared to make is the dependency based on files, but later
more on this.
 
So, comparing just the dependencies, make is more powerful than ant, but this
is not all ;-)
 
What I like most of ant are these directory tasks. Ant is MUCH faster than
make when it comes to compiling sourcecode, because it compiles all files at
once and knows how to handle directory-trees.
make was written for C programs and deals very badly with directories. Most of
the time, each directory needs its own makefile. As Java uses directories more
frequently than C, this is one of the main drawbacks of make when writing Java
applications.
 
You are still reading? Ok, here are my suggestions for Ant2. I am a friend of
KISS (keep it simple stupid). I like to reduce problems to the very necessary,
because I don't want to learn much. Everything should be as intuitively as
possible.
 
1. filesets
------------
Ant deals with file conversion. You have input files and outputfiles and tasks
what to do with them. Right now, both writing build.xml files and tasks
itselves it more complicated than necessary.
 
Each task can have input-files, output-files. Some of the build-in tasks just
need one of them, like 'mkdir' or 'delete'. Nethertheless, the syntax should
be similar, as it is obvious that 'delete' does not create files.
 
A possibility would be
 
  <mytask in="...." out="..."/>
 
(this could also be 'from' and 'to') or
 
  <mytask>
    <fileset type="in">
      ...
    </fileset>
    <fileset type="out">
      ...
    </fileset>
  </mytask>
 
Right now, the semantics using several filesets is confusing. If you have
(version 1)

  <mytask>
    <fileset>
      <include name="b"/>
      <include name="a"/>
    </fileset>
  </mytask>
 
then both 'a' and 'b' are sorted and given to the task as one fileset, thats
ok. But if you have (version 2)
 
  <mytask>
    <fileset>
      <include name="b"/>
    </fileset>
    <fileset>
      <include name="a"/>
    </fileset>
  </mytask>
 
then 'a' and 'b' are not sorted and given to the task in two separate calls as
two separate filesets. This is the same as (version 3)
 
  <mytask>
    <fileset>
      <include name="b"/>
    </fileset>
  </mytask>
  <mytask>
    <fileset>
      <include name="a"/>
    </fileset>
  </mytask>
 
and should not be like this, as I can write it like this if I want it. My
suggestion is:
 
version 1: all files are sorted
version 2: files are sorted within the filesets, but not sorted across them and
  given to the task as one large fileset
version 3: several filesets, several calls to the task
 
Additionally an option 'parallel="false"' that switches to 'one file at a time'
mode.
 
2. mappers
-----------
Mappers allow ant to do 'shortcuts' by not applying tasks if the outfiles are
newer then the infiles. Right now, the usage of mappers is very limited. You
cannot give them to all tasks and together with the strange behaviour of version
2, you cannot use it to 'cat' (UNIX cat) several files together if you need a
certain order. If you have
 
  <cat target="targetfile">
    <fileset>
      <include name="b"/>
    </fileset>
    <fileset>
      <include name="a"/>
    </fileset>
    <mapper type="merge" to="targetfile"/>
  </cat>
 
then the mapper will prohibit the cat of 'a', because the targetfile exists and
is newer as 'a' :-(
 
My suggestion is, that a mapper is possible for every task and that it is
evaluated only once. You can specify input-files and a mapper and maybe
outputfiles and a mapper, but it should not be allowed to specify all three,
input-, output-files and mapper.
 
The mapper will create the corresponding filesets and will be used to check if
the task needs to be run or is up to date. The task itself gets the in/outfiles
as if they were given and also access to the mapper.
 
3. fileset-code for tasks
--------------------------
When writing a task, accessing the filesets and mapper is rather complicated.
Code like
 
  fs.getDirectoryScanner( project )
 
where 'project' is inherited from a super class is not very object oriented.
Also, the files should be accessible as an 'Iterator' over 'File'. As there is
only one fileset, the Iterator itself should be sufficient. There is only one
mapper, so Code can be like this:
 
public class MyTask extends Task {
  public void execute() throws BuildException {
    for( Iterator i = getInputFiles(); i.hasNext(); ) {
      File
        fileInput  = (File) i.next(),
        fileOutput = mapToOuput( fileInput );
 
      System.out.println( fileInput.toString() + "->" fileOutput.toString() );
    }
  }
}

The mapper will create the corresponding filesets and will be used to check if
the task needs to be run or is up to date. The task itself gets the in/outfiles
as if they were given and also access to the mapper.
 
3. fileset-code for tasks
--------------------------
When writing a task, accessing the filesets and mapper is rather complicated.
Code like
 
  fs.getDirectoryScanner( project )
 
where 'project' is inherited from a super class is not very object oriented.
Also, the files should be accessible as an 'Iterator' over 'File'. As there is
only one fileset, the Iterator itself should be sufficient. There is only one
mapper, so Code can be like this:
 
public class MyTask extends Task {
  public void execute() throws BuildException {
    for( Iterator i = getInputFiles(); i.hasNext(); ) {
      File
        fileInput  = (File) i.next(),
        fileOutput = mapToOuput( fileInput );
 
      System.out.println( fileInput.toString() + "->" fileOutput.toString() );
    }
  }
}
 
I didn't dig into the 'XXXScanner', but this should be possible and fascilate
writing tasks a lot. Note that 'File' can be a plain file or a directory and
that it does not need to exist.
 
4. shortcuts for targets
-------------------------
Sometimes it is quite hard to convince Ant that a target does not need to be
rebuilt. What about a mapper for the target itself, just state what files this
target needs and what file(s) it creates.
 
The code for checking the mappers does exist and adding a mapper to a target
gives no conflicts.
 
 
So, thank you for reading this. I would like to get some response from you, whatyou think
about this. I don't want to start implemeting something unless someonesays that it is
worth it.
 
Greetings,
 
Kurt
-- 
-------------------------------------------------------------
Impossible doesn't exist!             Unmöglich gibt's nicht!
Difficult exists.                           Schwierig gibt's.

Re: Ant2 suggestions

Posted by Peter Donald <do...@apache.org>.
On Tue, 17 Jul 2001 17:24, Kurt Huwig wrote:
> Then you must have been better than me ;-) I do also have projects with
> only one Makefile, but this makes concurrent development a pain in the ass,
> as every developer needs to modify the makefile when adding files to the
> project. With Ant, you just rebuild a directory which is much easier.

Thats also possible with GNUMake aswell ;) It is just that only a few people 
handwrite build files and thus you end up with monstrous generated 
makefiles.

> That's correct. But you can use the same code for all tasks, so that you
> don't need these 'createFileset'-methods replicated in each task. But you
> can handle this very easy by using task-specific properties that tell Ant
> the name of the parameters for these, maybe like this
>
>   public class MyTask extends Task {
>     public MyTask() {
>       setInFileName( "source" );
>       setOutFileName( "target" );
>     }
>   }

Something similar to that will be possible in Ant2. However it will probably 
be implemented slightly differently.
> > > Code like
> > >
> > >   fs.getDirectoryScanner( project )
> > >
> > > where 'project' is inherited from a super class is not very object
> >
> > oriented.
> > What exactly is not 'object oriented' about this construct? The fact that
> > a task inherits its project or that the fileset needs the project to
> > setup the scanner?
>
> Inheritance of fields is a Bad Thing (tm) IMHO. 

agreed.

> You can also use the Singleton-pattern to remove the need to refer
> by a field. Hotspot optimizes getter and setter-methods, so you don't even
> have a speed advance if you access the fields directly.

Singleton is one solution but we will be moving away from it. We will provide 
a TaskContext through which you can access resources and probably have an 
AbstractTask that simplifies this by caching TaskContext and having easier 
accessors. Similar to the way Servlet and GenericServlet+HttpServlet work.

> Just imagine having the need to switch to several projects for whatever
> reason. Then you have to change every line of code that refers to
> 'project'. If you use 'getProject()' instead, you just have to change the
> code of this method and that's it. I had the problem of changing a software
> from single document to multi document interface and was glad for using
> access methods.

Alternatively you could just design the software so that it doesn't need and 
can never get access to project. Makes it much easier to have multi-project, 
no project (ie for script writing) or anyother combination ;) I am fairly 
certain thats the strategy we will end up using.

Cheers,

Pete

*-----------------------------------------------------*
| "Faced with the choice between changing one's mind, |
| and proving that there is no need to do so - almost |
| everyone gets busy on the proof."                   |
|              - John Kenneth Galbraith               |
*-----------------------------------------------------*

Re: Ant2 suggestions

Posted by Kurt Huwig <ku...@iku-netz.de>.
Maurice le Rutte wrote:
> > Inheritance of fields is a Bad Thing (tm) IMHO.
> 
> I've always thought that inheritance of fields was one of the core things of
> OO...

Certainly, OO means inheritance of fields and methods, but some things are
not recommended. 'Best practice' as recommended by a lot of people in the
software design field

public:
 - methods that are part of the public API; as few as possible
 - fields in value objects only (classes that just hold several values and
have no methods)
 - classes

protected:
 - other methods

"package":
 - evil, just use it for examples

private:
 - fields; supply public set/get methods
 - don't use it for methods as these methods cannot be overwritten or used
in subclasses

If you use a tool like Together(tm), there are several wizards that check
code style and complain if you break these rules. There are some other
tools, that can do this stuff, but I don't remember the names. It was
something like 'JMetric' or so.

The philosophy behind this is to keep the classes as much separated from
each other as possible. Some say, you should use a lot of interfaces and
only these form the public api, but I think this is a bit extreme.

As soon as you hand over references from one class to another, e.g.

	o.doSomething( this );

you create dependencies between these two classes. If you change something
in this class, you also have at least to check the other class if you broke
something.

Kurt
-- 
---------------------------------------------------------------
If DOS means "Denial Of Service" what means MS-DOS?
                            And why should I tell it to "win"?

Re: Ant2 suggestions

Posted by Kurt Huwig <ku...@iku-netz.de>.
Conor MacNeill wrote:
> From: "Maurice le Rutte" <mp...@oce.nl>
> > From: "Kurt Huwig" <ku...@iku-netz.de>
> >
> > > Inheritance of fields is a Bad Thing (tm) IMHO.
> >
> > I've always thought that inheritance of fields was one of the core things
> of
> > OO...
> 
> Well, allowing protected access does break the super class' encapsulation,
> allowing the subclass to violate the class invariant of the super class.
> So, in general, it is a bad thing. Providing accessors is not much better,
> though, unless you can restrict what the caller can do to the object (eg,
> const in C++). In the case of Ant tasks, the project field is not really
> part of the task's invariant, so protected access is not generally harmful.

Accessors allow you to change the internal data representation without
changes to the outer world. If you have to change from one project to
several projects or divide the 'Project' class into several classes, you
just change the 'getProject()' into a fascade and are done. With protected
inheritance, things become evil.

You are right that Java lacks the things you can do in C++ with 'const'. You
can work around it by using an interface containing only getter methods, but
it is not as easy as the C++ approach. On the other hand, you if you want to
make it right, you have to check every access at runtime.

Kurt
-- 
---------------------------------------------------------------
If DOS means "Denial Of Service" what means MS-DOS?
                            And why should I tell it to "win"?

Re: Ant2 suggestions

Posted by Conor MacNeill <co...@cortexebusiness.com.au>.
From: "Maurice le Rutte" <mp...@oce.nl>
>
> ----- Original Message -----
> From: "Kurt Huwig" <ku...@iku-netz.de>
>
> > Inheritance of fields is a Bad Thing (tm) IMHO.
>
> I've always thought that inheritance of fields was one of the core things
of
> OO...
>

Well, allowing protected access does break the super class' encapsulation,
allowing the subclass to violate the class invariant of the super class.
So, in general, it is a bad thing. Providing accessors is not much better,
though, unless you can restrict what the caller can do to the object (eg,
const in C++). In the case of Ant tasks, the project field is not really
part of the task's invariant, so protected access is not generally harmful.

Conor



Re: Ant2 suggestions

Posted by Maurice le Rutte <mp...@oce.nl>.
----- Original Message -----
From: "Kurt Huwig" <ku...@iku-netz.de>

> Inheritance of fields is a Bad Thing (tm) IMHO.

I've always thought that inheritance of fields was one of the core things of
OO...

Maurice.



Re: Ant2 suggestions

Posted by Kurt Huwig <ku...@iku-netz.de>.
Maurice le Rutte wrote:
> > [...]
> > So, comparing just the dependencies, make is more powerful than ant, but
> this
> > is not all ;-)
> I've never hacked much makefiles myself as NeXT's ProjectBuilder was better
> at this than me,but I can't see why make would be more powerful than Ant
> just because the rules are specified differently. I really like the fact
> that I tell Ant 'I want this. To get this do foo, bar and baz. To get foo
> do...' . Can you explain what nifty feature I should be missing in Ant that
> makes my life misarable?

I just meant that make can do what Ant does but not the other way round as
long as you look at dependencies only. I didn't say that this is a feature
you really need in everyday work. In fact, dependencies are less important
with current machines that rebuild even large projects in just a few
seconds. Back in 1993, our C project at university needed about 45 minutes
to rebuild, so this was quite important. Ant is much faster than make when
it comes to Java applications, so that's why I switched to Ant.

> > [..]
> > make was written for C programs and deals very badly with directories.
> Most of
> > the time, each directory needs its own makefile.
> I must have been abusing make, we had only one makefile per project and
> we've always used sub-directories quite a lot.

Then you must have been better than me ;-) I do also have projects with only
one Makefile, but this makes concurrent development a pain in the ass, as
every developer needs to modify the makefile when adding files to the
project. With Ant, you just rebuild a directory which is much easier.
 
> > I like to reduce problems to the very necessary,
> > because I don't want to learn much. Everything should be as intuitively as
> > possible.
> Laziness is a virtue when programming. However, what is intuitive differs
> per person and is largely based on past experiences. The biggest mistake is
> to use yourself as the center of universe.

I am not the center of the universe, as this is Germany ;-) Just kidding. I
don't know if it is easier to judge if something is easy to understand for
someone else than it is to judge for me. I just can see what looks easy for
me and ask others to comment about this.
 
> > 1. filesets
> > ------------
> > Ant deals with file conversion. You have input files and outputfiles and
> tasks
> > what to do with them. Right now, both writing build.xml files and tasks
> > itselves it more complicated than necessary.
> 
> > Each task can have input-files, output-files. Some of the build-in tasks
> just
> > need one of them, like 'mkdir' or 'delete'. Nethertheless, the syntax
> should
> > be similar, as it is obvious that 'delete' does not create files.
> >
> > A possibility would be>
> >   <mytask in="...." out="..."/>
> > (this could also be 'from' and 'to') or
> Arguments names should be descriptive of what they are used for. If two
> tasks can share the same name, great, but don't enforce names. The names
> you've suggested seem a bit too general for me.

That's correct. But you can use the same code for all tasks, so that you
don't need these 'createFileset'-methods replicated in each task. But you
can handle this very easy by using task-specific properties that tell Ant
the name of the parameters for these, maybe like this

  public class MyTask extends Task {
    public MyTask() {
      setInFileName( "source" );
      setOutFileName( "target" );
    }
  }

> > Right now, the semantics using several filesets is confusing. If you have
> > (version 1)
> >
> > [...]
> > then both 'a' and 'b' are sorted and given to the task as one fileset,
> thats
> > ok. But if you have (version 2)
> > [...]
> > then 'a' and 'b' are not sorted and given to the task in two separate
> calls as
> > two separate filesets. This is the same as (version 3)
> > [...]
> > and should not be like this, as I can write it like this if I want it. My
> > suggestion is:
> >
> > version 1: all files are sorted
> > version 2: files are sorted within the filesets, but not sorted across
> them and
> >   given to the task as one large fileset
> > version 3: several filesets, several calls to the task
> >
> Could you explain what trouble it causes? Don't fix what isn't broken.

The problems where stated below this one with the 'cat' task. I have several
files that need to be put together in a certain order. First one file, then
a bunch of files in another directory and then another file in the same
directory as the first one. I want to use a mapper, so that this file is
only being rebuilt if necessary. If I write all the files in one fileset,
they are being sorted and I get the second file directly after the first
file an especially before the bunch of files. If I use several filesets,
each fileset is a separate call to the task and a separate check with the
mapper, so Ant just adds the first file and then says that the target-file
is up-to-date as it is newer than any of the other files.

I could not figure out how to handle this problem, as I don't know how to
tell Ant file dependencies and so I just removed the mapper in my task and
rebuild the file on each compilation to be on the safe side.
 
> > Additionally an option 'parallel="false"' that switches to 'one file at a
> time'
> > mode.
> Task specific, imho.

Certainly, but if you can use it for every task, it is consistent. It might
even be resonable for the 'javac'-task, if you are low on memory.
 
> > [...]
> > 3. fileset-code for tasks
> > --------------------------
> > When writing a task, accessing the filesets and mapper is rather
> complicated.
> > Code like
> >
> >   fs.getDirectoryScanner( project )
> >
> > where 'project' is inherited from a super class is not very object
> oriented.
> What exactly is not 'object oriented' about this construct? The fact that a
> task inherits its project or that the fileset needs the project to setup the
> scanner?

Inheritance of fields is a Bad Thing (tm) IMHO. The same for the fileset's
need of the project. The fileset is created by Ant, so it should know the
project. You can also use the Singleton-pattern to remove the need to refer
by a field. Hotspot optimizes getter and setter-methods, so you don't even
have a speed advance if you access the fields directly.

Just imagine having the need to switch to several projects for whatever
reason. Then you have to change every line of code that refers to 'project'.
If you use 'getProject()' instead, you just have to change the code of this
method and that's it. I had the problem of changing a software from single
document to multi document interface and was glad for using access methods.

> > Also, the files should be accessible as an 'Iterator' over 'File'.
> I tend to agree on this one. I think all objects that have a containment
> relationship with other objects should have an iterator. Unfortunately even
> Sun doesn't do this. Look for example at the Servlet API and in 1.4 the
> NetworkInterface  class...

This is not a reason for me to do the same mistake...
 
> > As there is only one fileset, the Iterator itself should be sufficient.
> Don't agree here. Use a collection. Collections can return iterators.
> Doesn't complicate things and doesn't force you into a specific way.

Ok, you are completely correct. I just didn't think about this enought.
 
> [...]
> 
> Maurice.

Thanks for you feedback,

Kurt
-- 
-----------------------------------------------------------
Dave. Stop. Stop, Dave. Will you stop, Dave? I'm afraid.
I'm afraid, Dave. Dave, my mind is going. I can feel it...

Re: Ant2 suggestions

Posted by Maurice le Rutte <mp...@oce.nl>.
----- Original Message -----
From: "Kurt Huwig" <ku...@iku-netz.de>
To: <an...@jakarta.apache.org>
Sent: Monday, July 16, 2001 10:57 PM
Subject: Ant2 suggestions

> [...]
> So, comparing just the dependencies, make is more powerful than ant, but
this
> is not all ;-)
I've never hacked much makefiles myself as NeXT's ProjectBuilder was better
at this than me,but I can't see why make would be more powerful than Ant
just because the rules are specified differently. I really like the fact
that I tell Ant 'I want this. To get this do foo, bar and baz. To get foo
do...' . Can you explain what nifty feature I should be missing in Ant that
makes my life misarable?

> [..]
> make was written for C programs and deals very badly with directories.
Most of
> the time, each directory needs its own makefile.
I must have been abusing make, we had only one makefile per project and
we've always used sub-directories quite a lot.

> I like to reduce problems to the very necessary,
> because I don't want to learn much. Everything should be as intuitively as
> possible.
Laziness is a virtue when programming. However, what is intuitive differs
per person and is largely based on past experiences. The biggest mistake is
to use yourself as the center of universe.

> 1. filesets
> ------------
> Ant deals with file conversion. You have input files and outputfiles and
tasks
> what to do with them. Right now, both writing build.xml files and tasks
> itselves it more complicated than necessary.

> Each task can have input-files, output-files. Some of the build-in tasks
just
> need one of them, like 'mkdir' or 'delete'. Nethertheless, the syntax
should
> be similar, as it is obvious that 'delete' does not create files.
>
> A possibility would be>
>   <mytask in="...." out="..."/>
> (this could also be 'from' and 'to') or
Arguments names should be descriptive of what they are used for. If two
tasks can share the same name, great, but don't enforce names. The names
you've suggested seem a bit too general for me.


> Right now, the semantics using several filesets is confusing. If you have
> (version 1)
>
> [...]
> then both 'a' and 'b' are sorted and given to the task as one fileset,
thats
> ok. But if you have (version 2)
> [...]
> then 'a' and 'b' are not sorted and given to the task in two separate
calls as
> two separate filesets. This is the same as (version 3)
> [...]
> and should not be like this, as I can write it like this if I want it. My
> suggestion is:
>
> version 1: all files are sorted
> version 2: files are sorted within the filesets, but not sorted across
them and
>   given to the task as one large fileset
> version 3: several filesets, several calls to the task
>
Could you explain what trouble it causes? Don't fix what isn't broken.

> Additionally an option 'parallel="false"' that switches to 'one file at a
time'
> mode.
Task specific, imho.

> [...]
> 3. fileset-code for tasks
> --------------------------
> When writing a task, accessing the filesets and mapper is rather
complicated.
> Code like
>
>   fs.getDirectoryScanner( project )
>
> where 'project' is inherited from a super class is not very object
oriented.
What exactly is not 'object oriented' about this construct? The fact that a
task inherits its project or that the fileset needs the project to setup the
scanner?

> Also, the files should be accessible as an 'Iterator' over 'File'.
I tend to agree on this one. I think all objects that have a containment
relationship with other objects should have an iterator. Unfortunately even
Sun doesn't do this. Look for example at the Servlet API and in 1.4 the
NetworkInterface  class...

> As there is only one fileset, the Iterator itself should be sufficient.
Don't agree here. Use a collection. Collections can return iterators.
Doesn't complicate things and doesn't force you into a specific way.

[...]

Maurice.



Re: Ant2 suggestions

Posted by Stefan Bodewig <bo...@apache.org>.
On Tue, 17 Jul 2001, Kurt Huwig <ku...@iku-netz.de> wrote:

> Stefan Bodewig wrote:

> I meant that specifying several filesets should preserve the order
> of the filesets,

Oh, Ant does that.  createFileset or addFileset will be called once
for each fileset and they will be called in the same order they appear
in the build file.  It's again up to the task to preserve that order
(most tasks do as they pile them up in a Vector).

>> Collections would make it a no-go for Ant 1.x, and there is no
>> design for Ant2 to work against ATM.
> 
> So I can start with Ant 1.x and supply a patch that uses JDK 1.2/3
> features.

Let me try to rephrase: Ant 1.x will be JDK 1.1 compatible and Ant 2
will be JDK 1.2 compatible.

> Does 1.3 represent a common base? It's been around for a while

Not for everyone - the BSDs don't even have an 1.2 yet, MacOS 9
doesn't, HP/UX 10 will never get one and so on ...

Stefan

Re: Ant2 suggestions

Posted by Kurt Huwig <ku...@iku-netz.de>.
Stefan Bodewig wrote:

[...]

> >> (2) Ant doesn't guarantee any order - even within a single fileset.
> >
> > This should be made clear.
> 
> Yes, thanks, volunteer to update the documentation? 8-)

I meant that specifying several filesets should preserve the order of the
filesets, so you have control over the sequence of files. And this certainly
has to be documented.
 
> > The sequence of the files is very important for this task.
> 
> If it is a custom task, the task could sort the files itself.  The
> order of files in a FileSet is the order in which File.list returns
> them (searching directories recursively as it goes).

That's fine, but when there are several filesets within one task, the order
should be preserved.
 
> > There is better code in the upcoming 1.4 release where the URL is
> > not accessed.
> 
> Slow down a little, Ant 2 is just ready to drop JDK 1.1 compatibility 8-)

I know, there is no 1.4 up to now, but attending JavaOne was very exciting
;-)
 
> > So, I can get the current version out of CVS, implement a
> > Task-Superclass that supports Collections, port some tasks to it and
> > see if it works.
> 
> Collections would make it a no-go for Ant 1.x, and there is no design
> for Ant2 to work against ATM.

So I can start with Ant 1.x and supply a patch that uses JDK 1.2/3 features.
Does 1.3 represent a common base? It's been around for a while and Ant2 will
not be there for quite a while.
 
[...]

Kurt
-- 
------------------------------------------------------------ 
| yes, it runs | Designed for |     Microsoft     | intel  |
| with Netware |  Windows 95  | Windows compliant | inside |
------------------------------------------------------------ 
If you still have problems reading this signature,
                                   get Linux and a FAST cpu!

Re: Ant2 suggestions

Posted by Stefan Bodewig <bo...@apache.org>.
On Tue, 17 Jul 2001, Kurt Huwig <ku...@iku-netz.de> wrote:

> Stefan Bodewig wrote:
>> On Mon, 16 Jul 2001, Kurt Huwig <ku...@iku-netz.de> wrote:
> 
>> > What ant lacks compared to make is the dependency based on files,
>> > but later more on this.
>> 
>> Please take a look at the <apply> task.
> 
> I did, but the <apply> currently only executes other programs. I
> would like to have something like execute this Java-class;

This is the <javaon> the requirements list for Ant2 talks about.

> Also, you cannot <apply> another task, right?

<anton> in same document.

> I merely did mean that the fileset stuff can be moved up into the
> Task-class. If a task doesn't need it, it should be no problem.

I'd prefer to reuse the stuff via delegation - which doesn't mean the
current design couldn't be improved.

>> > 2. mappers
>> > -----------
>> > Mappers allow ant to do 'shortcuts' by not applying tasks if the
>> > outfiles are newer then the infiles.
>> 
>> This is not their primary purpose - they are used to define the
>> target files with respect to the source files in the first place.
> 
> I just noticed that they also serve as file-dependecy. If the mapped
> files are newer, the task is never called and therefore cannot
> decide.

This is not the mapper, but the SourceFileScanner class, which those
tasks that need more control (<copy> in the case of the overwrite
attribute) elect to ignore if needed.

>> (2) Ant doesn't guarantee any order - even within a single fileset.
> 
> This should be made clear.

Yes, thanks, volunteer to update the documentation? 8-)

> The sequence of the files is very important for this task.

If it is a custom task, the task could sort the files itself.  The
order of files in a FileSet is the order in which File.list returns
them (searching directories recursively as it goes).

> There is better code in the upcoming 1.4 release where the URL is
> not accessed.

Slow down a little, Ant 2 is just ready to drop JDK 1.1 compatibility 8-)

> So, I can get the current version out of CVS, implement a
> Task-Superclass that supports Collections, port some tasks to it and
> see if it works.

Collections would make it a no-go for Ant 1.x, and there is no design
for Ant2 to work against ATM.

> But this makes no sense if noone agrees on moving the fileset logic
> up.

We already have MatchingTask - actually this is the historic version
of directory based tasks.  <fileset>s have been invented after that,
because they've proven to be more flexible.  A fileset can have only
one "base" directory and there are many situations where a task really
benefits from working on more than just one fileset.

Stefan

Re: Ant2 suggestions

Posted by Kurt Huwig <ku...@iku-netz.de>.
Stefan Bodewig wrote:
> On Mon, 16 Jul 2001, Kurt Huwig <ku...@iku-netz.de> wrote:

[...]

> > What ant lacks compared to make is the dependency based on files,
> > but later more on this.
> 
> Please take a look at the <apply> task.

I did, but the <apply> currently only executes other programs. I would like
to have something like execute this Java-class; this would reduce the need
to write your own tasks a bit. Also, you cannot <apply> another task, right?

> > 1. filesets
> > ------------
> > Ant deals with file conversion.
> 
> Not really - <sql>, <junit>, <mail> do not really work on files at
> all.  If you leave out the <batchtest> element of JUnit there are no
> files involved at all (as far as Ant is concerned) for example.

I merely did mean that the fileset stuff can be moved up into the
Task-class. If a task doesn't need it, it should be no problem.
 
> > if you have (version 2)
> >
> >   <mytask>
> >     <fileset>
> >       <include name="b"/>
> >     </fileset>
> >     <fileset>
> >       <include name="a"/>
> >     </fileset>
> >   </mytask>
> >
> > then 'a' and 'b' are not sorted and given to the task in two
> > separate calls as two separate filesets. This is the same as
> > (version 3)
> >
> >   <mytask>
> >     <fileset>
> >       <include name="b"/>
> >     </fileset>
> >   </mytask>
> >   <mytask>
> >     <fileset>
> >       <include name="a"/>
> >     </fileset>
> >   </mytask>
> 
> No, these are different.  <chmod> in current CVS will create a single
> call to the chmod utility in the first case (your version 2) - it is
> up to the task to decide what it wants to do with several filesets.

Mmh, I just tried ant-1.3. If it is better now, that's fine and exactly what
I need.
 
> > 2. mappers
> > -----------
> > Mappers allow ant to do 'shortcuts' by not applying tasks if the
> > outfiles are newer then the infiles.
> 
> This is not their primary purpose - they are used to define the target
> files with respect to the source files in the first place.

I just noticed that they also serve as file-dependecy. If the mapped files
are newer, the task is never called and therefore cannot decide.
 

[...]

> > together with the strange behaviour of version 2, you cannot use it
> > to 'cat' (UNIX cat) several files together if you need a certain
> > order.
> 
> Two things here:
> 
> (1) you can use it with Unix cat using <execon> and the parallel
> attribute - it will be one call per fileset in Ant 1.3 but really just
> one call in the current CVS version.
> 
> (2) Ant doesn't guarantee any order - even within a single fileset.

This should be made clear. Otherwise it is impossible do with ant what this
code does in make:

        cat ear/ejb/META-INF/jaws.xml.1 > ear/ejb/META-INF/jaws.xml
        cat `find application/ejb -mindepth 2 -name "*-jaws.xml"` \
          >> ear/ejb/META-INF/jaws.xml
        for i in Account Acting Voucher; do \
          cat framework/ejb/$$i-jaws.xml; \
        done >> ear/ejb/META-INF/jaws.xml
        cat ear/ejb/META-INF/jaws.xml.2 >> ear/ejb/META-INF/jaws.xml

The sequence of the files is very important for this task.
 
[...]

> Again, it is up to the task to decide what it wants to do with
> filesets or mappers.  Which built-in task should support mappers in
> what way in your opinion?

I thought the mappers map input files to output files. And as it looks to
me, the task doesn't get called when the output files are newer than the
corresponding input files.
 
> > 3. fileset-code for tasks
> > --------------------------

[...]

> > Also, the files should be accessible as an 'Iterator' over
> > 'File'.
> 
> This has been suggested before - there are times where you want to
> operate on a set at once and times where you want to iterate through
> the set.  I guess we'll end up with an Iterator approach as
> alternative to methods returning the whole set at once.
> 
> I'm not sure about the File though, we have filesets that work on
> remote directories (see <ftp>) or ZipEntries (see <zipfileset> in
> <zip> and friends).  We'll probably end up using a different
> abstraction than File.

You are right. Maybe 'URL' is better, although there are some problems with
it, as the Java API checks if the URL exists. There is better code in the
upcoming 1.4 release where the URL is not accessed.
 
> > The mapper will create the corresponding filesets and will be used
> > to check if the task needs to be run or is up to date.
> 
> I'd prefer to keep this responsibility (does the task need to run)
> inside the task itself, as only the task can now the logic it has to
> follow. See the various overwrite or force attributes in some tasks
> for example.

OK, I will have a look at it before I talk more nonsense ;-)
 
> > 4. shortcuts for targets
> > -------------------------
> > Sometimes it is quite hard to convince Ant that a target does not
> > need to be rebuilt. What about a mapper for the target itself, just
> > state what files this target needs and what file(s) it creates.
> 
> <target>s don't have input or output files for me.  A <target> groups
> tasks and these tasks are supposed to be smart enough to know whether
> they should run.

I just thought of complicated file generation, like EAR files. But that was
just an idea.

So, I can get the current version out of CVS, implement a Task-Superclass
that supports Collections, port some tasks to it and see if it works. But
this makes no sense if noone agrees on moving the fileset logic up.

Kurt
-- 
-------------------------------------------------------------------------
Microsoft wants customized versions of Windows NT for "embedded" systems
such as health and communications equipment.
              This gives the Blue Screen of Death a whole new meaning...

Re: Ant2 suggestions

Posted by Stefan Bodewig <bo...@apache.org>.
On Mon, 16 Jul 2001, Kurt Huwig <ku...@iku-netz.de> wrote:

> Both make and ant serve to ease the job of creating files out of
> other files.

Ant not so much as make, as what would be a PHONY target in make is
nothing special for Ant.  In effect, the whole build process is mostly
about creating files from files, but Ant doesn't really focus on this.

> What ant lacks compared to make is the dependency based on files,
> but later more on this.

Please take a look at the <apply> task.

> 1. filesets
> ------------
> Ant deals with file conversion.

Not really - <sql>, <junit>, <mail> do not really work on files at
all.  If you leave out the <batchtest> element of JUnit there are no
files involved at all (as far as Ant is concerned) for example.

> if you have (version 2)
>  
>   <mytask>
>     <fileset>
>       <include name="b"/>
>     </fileset>
>     <fileset>
>       <include name="a"/>
>     </fileset>
>   </mytask>
>  
> then 'a' and 'b' are not sorted and given to the task in two
> separate calls as two separate filesets. This is the same as
> (version 3)
>  
>   <mytask>
>     <fileset>
>       <include name="b"/>
>     </fileset>
>   </mytask>
>   <mytask>
>     <fileset>
>       <include name="a"/>
>     </fileset>
>   </mytask>

No, these are different.  <chmod> in current CVS will create a single
call to the chmod utility in the first case (your version 2) - it is
up to the task to decide what it wants to do with several filesets.

> 2. mappers
> -----------
> Mappers allow ant to do 'shortcuts' by not applying tasks if the
> outfiles are newer then the infiles.

This is not their primary purpose - they are used to define the target
files with respect to the source files in the first place.

> Right now, the usage of mappers is very limited.

True.

> together with the strange behaviour of version 2, you cannot use it
> to 'cat' (UNIX cat) several files together if you need a certain
> order.

Two things here:

(1) you can use it with Unix cat using <execon> and the parallel
attribute - it will be one call per fileset in Ant 1.3 but really just
one call in the current CVS version.

(2) Ant doesn't guarantee any order - even within a single fileset.

> My suggestion is, that a mapper is possible for every task and that
> it is evaluated only once.

Where they make sense - see <mkdir> or <junit> or ...

Again, it is up to the task to decide what it wants to do with
filesets or mappers.  Which built-in task should support mappers in
what way in your opinion?

> 3. fileset-code for tasks
> --------------------------
> When writing a task, accessing the filesets and mapper is rather
> complicated.

Agreed.

> Also, the files should be accessible as an 'Iterator' over
> 'File'.

This has been suggested before - there are times where you want to
operate on a set at once and times where you want to iterate through
the set.  I guess we'll end up with an Iterator approach as
alternative to methods returning the whole set at once.

I'm not sure about the File though, we have filesets that work on
remote directories (see <ftp>) or ZipEntries (see <zipfileset> in
<zip> and friends).  We'll probably end up using a different
abstraction than File.

> The mapper will create the corresponding filesets and will be used
> to check if the task needs to be run or is up to date.

I'd prefer to keep this responsibility (does the task need to run)
inside the task itself, as only the task can now the logic it has to
follow. See the various overwrite or force attributes in some tasks
for example.

> 4. shortcuts for targets
> -------------------------
> Sometimes it is quite hard to convince Ant that a target does not
> need to be rebuilt. What about a mapper for the target itself, just
> state what files this target needs and what file(s) it creates.

<target>s don't have input or output files for me.  A <target> groups
tasks and these tasks are supposed to be smart enough to know whether
they should run.

Stefan