Bug 20867

Summary: The possibility of getting properties from ant scripts
Product: Ant Reporter: Tomislaw Kitynski <t.kitynski>
Component: Core tasksAssignee: Ant Notifications List <notifications>
Status: REOPENED ---    
Severity: enhancement    
Priority: P3    
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: All   

Description Tomislaw Kitynski 2003-06-18 12:06:44 UTC
Currently I can load properties via eg. <property/> or <loadproperties/> and 
this is good. Now, I have several projects that depend on each other in much 
sophisticated way that could <ant/> task to resolve. I put as many properties 
to external files as possible and I load them into via appriopriate task into 
ant scripts where necessary, but still I have to play with some properties in 
each build script. Let's say I want to include current velocity jar into each 
project---if there's newer version of it, I have to change every build file to 
point to correct file. Well, you can say I could have one properties file with 
all the paths and load it, but since I have different machines, I would like 
to spare myself the nescessity of setting absolute paths. Instead I rather set 
$VELOCITY_HOME and change it when new velocity appears, but using env 
variables is not possible in properties files, and again: loading just the 
current jar name and joining it within an ant script currently forces me to do 
it in every build.xml file.

So it would be great to have something, that have the possibility of setting 
props like now, use $ references to names, and that would allow include those 
properties in running script---this is exactly inversely to what <ant/> task 
does (in the meaning of passing properties).

I've looked at the faq and documentation, but I haven't found anything like 
that---if this actually IS implemented, then please let me know.

TIA
Comment 1 Erik Hatcher 2003-06-18 12:52:48 UTC
Have a look at how I deal with libraries in the JavaDevWithAnt project: http://
www.ehatchersolutions.com/JavaDevWithAnt/ant.html#lib 

With a bit of indirection you can achieve the separation you are aiming for.
Comment 2 Tomislaw Kitynski 2003-06-18 13:14:29 UTC
Hmm, looks interresting---first of all it turned out, that actually using $ 
references in properties IS allowed 8) Great! 8) I guess this solves much of 
much concerns, and with help of your description it seems that I'll be able to 
do what I intented to---thanks a lot!
Comment 3 Erik Hatcher 2003-06-18 14:27:33 UTC
Just marking as WONTFIX so its not an issue on the to-do list.
Comment 4 Tomislaw Kitynski 2003-06-20 19:57:05 UTC
Uhm, I let myself to reopen this rfi, since after my enthusiasm on your 
solution I shortly find out, that it still doesn't resolve all my problems.

But let's get to the point. It is great thing, that the loaded properties are 
parsed against ${var} references. It really is very helpfull, but still I can 
not get rid of redundant code. Similary to what you'd suggested in the link 
you have provided last time, I've defined lib.properties, prj.properties 
(common properties for most projects) and commons.xml (common tasks for most 
projects). All those files are placed in .ant directory available to all build 
scripts. Besides I have build.xml and build.properties in each project's ant 
folder. File build.properties holds release, version, revision numbers, 
compiler options, some per-projects settings, etc.

File commons.xml contains (amongs others) three targets: release, version and 
revision, which are called in init target of the commons.xml, which of course 
is called from each build.xml/init target. These targets utilize 
<propertyfile/> task to eventually set new version numbers, depending on build 
mode passed via -D property. This works fine.

The point is, that now I have to 1) put version numbers (or shall I say: 
version string) into lib.properties and 2) replace it every time I change 
version number of some of my projects. Besides it's redundant. Well, I could 
work this around, and place in lib.properties file just the path to the 
project dir (some libs are "external"---provided by other people/companies, 
and some are "internal"---provided by me and their sources are somewhere in my 
fs) and read the build.properties for needed subproject (lib) in each 
build.xml and set necessary strings, but I have to do it in each build file---
the code is exactly the same and from the point of view of a programmer it's 
terrible solution.

What shall be done, then? Well, it would be great to add more processing power 
to properties files or (that's what I would vote for) have the possibility to 
include properties (and eventually all refs) to build files. With this I could 
change lib.properties into lib.xml and set there complete <path/> or 
<fileset/>---in most cases it's common for most of the projects, I could set 
there some filterset, properties a.s.o.

I have prj.properties skelton like this (just two properties to make it more 
clear):

...
prj.tag = ${prj.name}-${release}.${version}.${revision}
prj.jar = ${prj.tag}.jar
...

This file is placed in shared folder (let's call it .ant). Version numbers of 
each project are placed in build.properties, eg:

...
release = 1
version = 3
revision = 43
...

To set default properties in each build file I have to:

<property file="build.properties"/>
<property file="${.ant}/prj.properties"/>

and that's okay. Worse if I need to use subproject and to know this subproject 
version numbers. I can ofcourse do

<property file="${subprj.path}/ant/build.properties" prefix="${subprj.name}"/>

but I can not make use of ${subprj.name}.prj.tag and -.jar like I did in the 
main build file.

I think of some kind of task like this:

<include prefix="${subprj.name}">
	<filelist dir="${subprj.path}/ant" files="build.properties"/>
	<filelist dir="${.ant}" files="prj.properties"/>
</include>

I think that <include/> element (or whatever would it be called) could make 
use of inheritAll and -Refs attrs too. By default all inherit attrs should be 
set to false IMO. Further, we could include not only props and refs, but also 
targets---in this case the immutability rule should apply too. (It should be 
discussed if targets are to be prefixed also---maybe we could add a switch 
prefixTargets="true|false" for that reason). The prefix atribute is optional 
and the sequence of <filelist/> elements and files named in files attribute 
must be preserved. Maybe, for shortening, an attribute files (and optionally 
dir?) could appear in DTD for <include/> element too.

The ability to include props, refs and targets into build scripts would 
greately reduce the amount of code in each script and thus the nescessity of 
updating of tones of files when something changes.

Well, I am not sure if I am completly understandable with my explenation---
English is not my native language, besides I am writting it as I am thinking 
of it, so I do not have precise vision of including build scripts. But I hope 
in general it's obvious what I think of---thank you for your time.