ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stefan Bodewig <>
Subject Re: Is this a desirable feature?
Date Fri, 25 May 2001 08:55:30 GMT
Bryan Headley <> wrote:

> That would work, but I want all my properties in a single file, so I
> can ensure that they stay in sync together. 

As something like your example is the only use case for recursive
property resolution I've seen so far (and my answer to use property
files instead is always the same as well 8-), I really want to explore
the benefits of both approaches.  

My take so far has been "do we need recursive property resolution? If
so, let's add it." - and yet I've not been convinced.

So let's start out simple.  I have two different build scenarios, DEV
and STABLE with differing property sets.  Let's assume we support
recursive property resolution, then we have two options (passing in
either DEV or STABLE as property TYPE):


<property name="myprop.DEV" value="foo" />
<property name="myprop.STABLE" value="bar" />

<property name="myprop" value="${myprop.${TYPE}}" />


<property file="${TYPE}.properties" />




As I always argue that (b) has advantages over (a) I'll leave the
arguments in favor of (a) to others.  Yours is that you have all
properties in one file and can make sure they stay in sync more
easily. I'm not sure this is true in the light of my default values
argument further down ...


Pros of (b) IMHO:

(1) Easy support of common/default values

If you slightly modify (b) to read

<property file="${TYPE}.properties" />
<property file="" />

you can place default values for all properties into a file of its own
- every property that has not been specified in ${TYPE}.properties
gets its value from the defaults.

To achieve the same in scenario (a) you'd need something like this

<target name="set-myprop-default" unless="myprop.${TYPE}" />
  <property name="myprop" value="default-value" />

<target name="set-myprop-type" if="myprop.${TYPE}" />
  <property name="myprop" value="${myprop.${TYPE}}" />

<target name="set-myprop" 
        depends="set-myprop-default,set-myprop-type" />

for each property (or we'd need to modify antcall to run in the same
execution context as the current project and use template targets
that would be called for each property).

This construct will of course defeat the "make sure properties will be
in sync" argument as well.

(2) Easier to extend if a new build scenario arises

Let's throw in something like release candidate builds or similar
(XEmacs's current gamma branch).  In (a) modify build.xml and add a
<property>-element for each property, in (b) create a file and define only those properties that have to
be different from the default values - don't change build.xml at all.

(3) Easy to ensure properties are in sync as well

Just add the new property to and set it to a value
that will make the build fail 8-)


Finally I'm not really sure what types of properties we are talking
about here:

Is this really a variation along build scenarios like in my examples
or are we talking about variations along several axises (sp?) (branch,
operating system, locale ...) - I'm not sure how well either approach
handles these.  I'd think each axis would be independent of the others
so you'd end up with one set of files/one block of property
declarations for each axis as well.

What are these properties used for? 

file names would be better dealt with by hard-coding the property into
the path itself IMHO.  But this may very well be a matter of taste.

flags for conditional target execution or include/exclude patterns?
For patterns one could import/include build scenario specific
patternsets which would probably be a lot easier to read and
maintain. Compare

<import location="${TYPE}.ant" />

where DEV.ant contains

<!-- include all -->
<patternset id="sources" />

and STABLE.ant

<patternset id="sources">
  <exclude name="**/experimental/*.java" />


<!-- don't define for DEV, we need these sources -->
<property name="exclude-experimental-STABLE" value="1" />

<target name="set-exclude-experimental" if="exclude-experimental-${TYPE}" />
  <property name="exclude-experimental" value="1" />

<patternset id="sources">
  <exclude name="**/experimental/*.java" if="exclude-experimental" />


View raw message