ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nicola Ken Barozzi <>
Subject Re: override
Date Thu, 07 Aug 2003 14:45:33 GMT

Sorry if the mail becomes long, I have difficulty in deciding what to 
snip ;-)

Costin Manolache wrote, On 07/08/2003 15.56:

> Nicola Ken Barozzi wrote:
>>>Thanks for the overview, Nicola !
>>>>Just to get you up to speed, the current issue is about multiple
>>>>inheritance, and how the current system allows cross-import (unwanted?)
>>>>side-effects, as Conor has brilliantly shown.
>>>What I'm not sure I understand is what import has to do with multiple
>>>inheritance :-)
>>Because we can import two targets with the same name from different
>>files. Making them work together is conceptually similar.
> You could try to import 2 classes with the same name in java.
> It's a syntax error - and if it happen, you must use qualified names.
> Yes, most build files have a target named "build" - but I don't know why
> would you think about inheritance and OO instead of just qualified names.
> I don't know _any_ programming language where import is used for
> inheritance.

Well, I pointed out xslt, what about that? ;-)

As has been pointed out in these threads, Ant is a different beast, and 
should be treated differenty.

>>>What's the syntax for the
>>>prefixed targets/properties ?
>>  prefix="a"
>>  name="b"
>>  result="ab"
> Hmm. Some delimiter would be good to have. 
>  a.b, a-b, a::b, etc.
> It would make things easier to read and understand.

not : , as it mixes with namespaces
not :: , too cluttery
not - , used in many xml langiages in compound names
. could be ok

> It would also be nice to default to the project name
> ( and require it to be unique, or use the explicit prefix
> only if 2 build files have the same name ).

OOTOMH could be a nice thing.

>>>>- add <include/> task, like entity includes
>>>>- add <override-target/> task to override targets
>>>Is this "override-target" a substitute for <extends> and OO use of
>>>ant ( i.e. a buildfile == class, target==method ) ?
>>In a sense yes, but not quite. Import does not fully encapsulate the
>>calling buildfile. @see XSLT include and import for a more similar
>>>If so, wouldn't be more intuitive to just use the real concept - i.e.
>>>extends and inheritance ?
>>>I know python has a very nice namespacing mechanism where you can replace
>>>or add methods dynamically to an object, but I don't know if this is
>>>desirable for ant.
>>KISS. Personally I don't need that (yet) I guess.
> Well, KISS is my concern as well, for <import> ( which at least in my mind
> is _very_ different from "extend" ).

It is, I agree.

> I preffer to use import to just import
> entire files, instead of some attributes and sophisticated rules to
> determine what target is visible and what target is overriden.

Then call it <include>, it's already proposed.

> And if people need an OO feature for ant - that's fine, they can add special
> tasks ( <exted>, <override>, etc ).

Hey, that's what we are talking about! IOW, what should Ant give me to 
get the features I want?

<include> ok, already decided
<override> ok, already decided
<import> ?

>>>>Threads about import (in order):
>>>>   1 - ImportTask ant 1.6
>>>>   2 - ant 1.5.4 : Import
>>>>   3 - override
>>>>>From thread 2 I wrote:
>>>>multi-import(import a,b)
>>>>  target test depends=a.test, b.test
>>>>  target critical
>>>>  target test depends=critical
>>>>  target critical
>>>>  target test depends=critical
>>>>Here "critical" means a.critical to a and b.critical to b, but since
>>>>they reference a generic "critical", they get the only one that remains
>>>>after being redefined. The problem is that I did not redefine it in the
>>>>main buildfile!
>>>Can this be resolved by making all targets qualified after the build file
>>>is read ?
>>This is what Conor seems to propose IIUC, and what others are not keen
>>on, and instead talk more about the xslt-type import.
> Well, Conor has one more vote then :-)
> XSLT is not the easiest XML format ( I don't know many people to 
> consider writting an XSTL is easier than writting an ant build file :-)
> And the fundamental problem ( IMO ) is using the wrong concept.
> We are talking about OO concepts and inheritance - in <import> context. 

Well, we are not. We are referencing those concepts, but it's not the 
same thing.

> If we have so much trouble understanding how <import> would be used 
> for inheritance, what about all the users who may be java programmers 
> ( where import has a very intuitive meaning, and so does extends ).

If it's just a naming issue, let's call it XYZ, I honestly don't care.

Just to be clear: current import is *not* <projectref>. It is not meant 
to encapsulate another buildfile, and the basedir resolving and the 
non-namespacing of properties is very clear about this.

>>Just remember that we are not talking about renaming properties, or
>>resolving basedirs, so it's not full encapsulation, but just
> Well, we seem to be talking about which target will be visible - with
> private/public and all this. 
> Very far from java import - where all you can talk about is qualified names
> if you have 2 classes with the same name.

Because Java does not have multiple inheritance, and even more does not 
have automatic multiple inheritance. I agree that this is a different 

>>I have not yet made up my mind, but it seems that ATM there is a reason
>>favor some kind of "namespacing" because I see more harm than good in
>>side-effects that come out of not doing it. How this can still solve my
>>usecase is yet to be seen.
> Maybe import shouldn't solve all use cases - just have a different task 
> that solves overriding/replacing some targets.

Ok, so you haven't read all the thread ;-)

Maybe it's better if you take a bit of time to reread the thread, as we 
are repeating stuff here.

>>>When you look at a build.xml, all targets that don't have prefix are
>>>resolved to the current build file - it's pretty easy to understand.
>>>That mean you won't be able to use import for crazy overrding of
>>>some targets from one file with targets from other file - but if there is
>>>a real need for that i have no problem with a python-like mechanism where
>>>you can add/replace methods in an object at runtime. As long as it's
>>>not disguised as <import> :-)
>>Well, IMHO I personally don't see a real, strong, compelling reason to
>>have targets have crosstalk between themselves, but I do have an equally
>>strong need to import dependencies.
> With qualified names, you can have both. 


>>As I have outlined before, imagine I import a file that has a compile
>>and test targets.
>>  target compile
>>  target test depends=compile
>>I want to be able to do "ant compile" and have it compile. Thus the
>>compile target should not be renamed.
> If this is the only "compile" target in all the imported files, then 
> you should be able to say "ant compile".
> If you import 2 files, each having a "compile" target, then you should
> use qualified names. Like in java import. 

Ok, this is clear, you are saying we should not have an automatic 
"winner" in case of multiple colliding import names.

Let's see the rest...

>>Then when I want to insert a pre-condition to the compile target, I want
>>to be able to redefine the compile target.
>>Reusing it in a differently-renamed target is not ok, as when I call
>>"test", it will not have a dependency to the new version of the target.
>>  target compile
>>  target newcompile (call:prestuff, compile, poststuff)
>>  target test depends=compile
> That's a nice use-case - but why do you think this is a use case for
> "import" ? 

Because I called it this way, that's all ;-)

> Just use a <rename-target> target, or some <pre>/<post> or <extend>.

In fact, as I have explained, Conor proposed <override-target>, and I 
like it. But this is only about a a single import, the real issue 
discussed here is the multiple one.

>>If I call newcompile, it works but calling test will not call the new
>>one, thus making it impossible for me to *decorate* the compile target,
>>thus specializing the template.
> Makes sense to me - if import would allow this to happen few people will
> be able to understand a build file. 
> So I consider a good thing that import doesn't allow you to "decorate", 
> but instead you should use a specialized task for this use case.

You mean that a user must do:

  <override-target name="xxx">

  instead of

  <target name="xxx"> (implicit override)?

I'm fine with it, no problem here, again it has been proposed and 
accepted, but not the issue here.

>>The question is: after a multiple import, which compile target becomes
>>the "default" one, ie the one without renaming?
> None, if 2 targets with the same name are found, you must
> use qualified names for both ( when calling from outside - all dependencies
> and calls from inside an imported build.xml file would use the short name ). 

I get your point, same as you described above.
Not sure, but OOTOMH I think it's ok.

>>Second question: how do we deal with the fact that targets that are not
>>even used have crosstalk between themselves?
> I don't think you can have crosstalk if you follow the rule that everything
> is qualified if it has the same name.

Two points here:

  - Crosstalk can happen in form of properties
  - Of course you won't have crosstalk if you use qualified names, this
    is what Conor says

>>And most of all: how to solve the last two points while keeping it
>>possible for me to retain the use-cases?
> By adding specialized tasks for your use case ? 

Let's see:


No problem here, any collision is an error


I am overriding the previous defined target, and can refer only to the 
immediately previous one as original.targetname. Overriding can be done 
multiple times, nesting the calls.


Like include, but gives me the possibility of referring to the imported 
tasks with a fully qualified name in any case. If there is only one 
version of a target, it's also available with the original name.

<Still conused about this [] part> [The "namespace" name has to be 
specified as a prefix by the one that imports the file, else the project 
name is used. Projects that are imported must have a name.]

If a project imports clashing target names, and thus namespacing is 
needed, I can still use <override-target> or <target> to define a target 
with the original name.


Use case:

multi-import(import a,b)
   target test depends=a.test, b.test

   target compile
   target test depends=compile
   target compile
   target test depends=compile

With namespacing I would get:

   target a.compile
   target a.test depends=a.compile
   target b.compile
   target b.test depends=b.compile

Now If I redefine compile

multi-import(import a,b)
   target test depends=a.test, b.test
   target compile depends=a.compile,b.compile

Seems ok to me  :-)

Now for Nick's usecase:

Nick Chalko wrote, On 01/08/2003 9.37:

> I used this "feature" in centipede.
> The release antlib has a target called tag-and-release, but it
> depends on a target called tag However tagis expected to be defined
> in a different antlib. Currently it is defined in cvsbuild, but it is
> open for someone to make a vssbuild antlib.
> So I do think cross talk is a "feature" but a feature that can be
> hard to grok.

   multi-import(import release,cvsbuild)

   release @importable="only"
     target tag-and-release depends=tag

     target tag

Seems that it should work with the above system.


   multi-import(import release,cvsbuild,vssbuild)

Would make it necessary for me to do:

   override-target tag depends=cvsbuild.tag

>>As you see, for this usecase, <include> is not strong enough, as I
>>cannot override, and complete namespacing prevents me from overriding
>>the dependency chain.
> It's like saying <copy> is not strong enough to compile java code :-)

It isn't? ;-P

Anyway, it seems that all this discussion has brought us back to what I 
had proposed after Conor pointing out the issue:

Nicola Ken Barozzi wrote, On 30/07/2003 10.45:
 > OTOMH this could be solved by rewriting all dependencies that are not
 > in the import line.
 >               (1)---a
 >  multi-import (2)---b
 >               (3)---c---d
> So rewriting should block collisions between (1), (2), (3), but
> enable them inside those lines.
> What had been proposed is using "fully qualified" names in targets
> that I do not want to be redefined, which could be ok conceptually,
> but the issue is that the implications of sideways crosstalk between
> import lines are not transparent to the user, and thus should be
> avoided.
> What I need is to be able to import build dependencies along with the
>  targets. Probably the above solution should fix this error and make
> it work, no?

Thanks for taking time to discuss this guys, I appreciate :-)

Nicola Ken Barozzi         
             - verba volant, scripta manent -
    (discussions get forgotten, just code remains)

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

View raw message