ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Steve Loughran" <>
Subject Re: newbie - if-then-else task?
Date Tue, 04 Dec 2001 20:03:29 GMT

----- Original Message -----
From: "Russ Fink" <>
To: <>
Sent: Tuesday, December 04, 2001 7:19 PM
Subject: Re: newbie - if-then-else task?

> I tried the other way, using depends and targets.  It is REALLY long, not
> succinct, and IMHO can lead to severe maintenance problems in the long
run -
> therefore, I advocate leaving the "available" tag just the way it is.
> To do what I wanted using depends and targets, it roughly works like this
> (without too much correctness on the syntactical details):
> <<< start of code >>>
> // This sets a property, localfile.exists=true, if the file
> // exists locally
> <target name="check.local">
>   <available file="my_local_path/file" property="localfile.exists"/>
> </target>
> // This calls the target that sets localfile.exists, then
> // if localfile.exists is true, it copies the file from the local
> // spot.
> <target name="copy.from.local" depends="check.local"
>        if="localfile.exists">
>   // copy from my_local_path/file to my_destination_dir
> </target>
> // In the event that a local file does not exist, this target
> // goes to a system directory and fetches the file there.
> <target name="copy.from.system" depends="check.local"
>        unless="localfile.exists">
>   // copy from my_system_path/file to my_destination_dir
> </target>
> // We need a dummy target to exercise the depends line and force
> // needed copying to occur.  Try copying from local first, then
> // try copying from the system.
> <target name="copyfile" depends="copy.from.local, copy.from.system"/>

1. given copyfile does date based copying, I am not sure that you need to
jump through these hoops. A <copyfile> on its own *usually* suffices.

2.  you dont need the dummy target to get the dependences, just glue the two
paths together and rely on them being skipped if the conditions are broken.

 <target name="check.local">
   <available file="my_local_path/file" property="localfile.exists"/>

 <target name="copy.from.local" depends="check.local"
   // copy from my_local_path/file to my_destination_dir

 // In the event that a local file does not exist, this target
 // goes to a system directory and fetches the file there.
 <target name="copy-files" depends="copy.from.local"
   // copy from my_system_path/file to my_destination_dir

The other optimisation is just to have a probe target which checks for
everything in one place; files, java classes, remote servers, executables on
the path, etc. The advantage of that strategy is that all your dependencies
are listed in one place, which can help maintainers.

3. But in this case I would use immutability to my own ends, along with the
knowledge that copy doesnt copy onto itself

<property name="destfile" location="my_local_path/file"/>
<available file="${destfile}" property="srcfile"  value=="${destfile}" />

<property name="srcfile" location="my_system_path/file"/>
<copy file="${srcfile}" tofile="${destfile}" />

one target. one test. one action. four lines. Three if you skip the initial
property declaration, but that is bad engineering.

> This I believe is what you mean by the "depends/unless" method.  If so,
> is verbose, and prone to maintenance error.  For instance, I have to
> maintain a copy of the local file in two separate tags.  Also, where do I
> set a property that tells what file I want to copy?  I would have
> potentially hundreds of files I want to copy, and it would be insane to
> hundreds of targets, one per file.  What would I do?  I might end up
> a property, "file.from", and then have to override it when I want to copy
> different file - but that would run against the idea of having set-once
> this what is meant by 'immutable?') properties.

you can use <antcall> to call a target with a different set of properties.
However, I agree that it doesnt scale. In that situation I would probably
modify the <copy> task to have a new 'onlyifdestmissing' tag or equivalent;
eight lines of code, plus 1 minute to rebuild ant.

> Now that I'm standing on a soapbox, I would like to point out that if we
> wish to have a suitable build system replacement for Make, then it should
> support at least a basis vector of functionality from Make, to include
> other things the ability to easily make choices at compile time depending
> environment variables, tag names, and so on.

We have a <condition> tag to do these things, it now does more than make
ever did; such as letting you probe for a TCP port on a remote server being

What is still complex is acting on conditional values; the 'many targets'
solution seems ungainly, but it is a simple model. It may be that a better
conditional execution model can be designed, but it should be through

> Digging in deeper, I strongly suggest supporting in-line Java calls, in
> form of an XML tag, that would be similar to how Make supports "in-line"
> shell script constructs (how Make executes shell code... well, that's all
> does, actually).  This would give some power to the build process, and
> should be fairly easy to implement - just compile all the inline java
> then include these classes in the VM when invoking ant.  This would give
> powerful file copying capabilities, decision making, pattern replacement,
> user-interface prompts (popup dialog boxes), string manipulation, and

That's idea. we could call it, say the <script> task. Oh, wait a minute,
somebody has already written one, it is one of the optional tasks.

There is a underlying issue here, which does often crop up when migrating to
ant from make, and that is you want ant to behave just like make. It doesnt
and it wont. the complexity in make goes into the makefiles, the complexity
in ant goes into the tasks themselves.

> At least leave the <available> tag the way it is.  Thanks for your help,

Too late. It's gone. And for a good reason.

If people can overwrite properties, it becomes impossible to call one build
file from another and give the parent file control over what that child
build does: where it puts files, what its debug flag is, etc. There has been
a consistent rule since ant1.2 that this should be the case, it was only
recently that it became clear that there was an inconsistency, which has
just kept Erik busy all week fixing.


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

View raw message