ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Richard Russell" <>
Subject Re: Thinking in Ant...
Date Tue, 05 Oct 2004 17:10:47 GMT
Ant (or make) is not a general purpose scripting language!
Mr. Bourne wrote a pretty good scripting language.

Yes, but sh (& friends) are not installed by default on Windows, and 
hence, scripts written for them aren't portable... In make (which isn't 
portable, I know), you can basically embed sh scripts, in a fairly 
standard (modulo make's awkwardness regarding tabs and escaping $'s and so 
on) manner. i.e. a Makefile describes the dependencies between different 
processes that are used to build/deploy etc the software. Not that I like 
make -- I'm just using it as a point of comparison.

So, what you're really saying here is that Ant is the wrong tool for what 
I'm trying to do, and I should really be scripting it, perhaps using the 
<script> task, or writing my own new task to do it... I think I 
understand, but I have to say that I'm dissappointed -- mainly because it 
means more work, more reading documentation, and less output for me in my 
specific situation here and now. I had been hoping against hope that my 
screwdriver was indeed a hammer that I was holding wrong.


Richard Russell 
Deutsche Bank AG London 
Global Markets Customer Solutions
Office: +44 (0)20 7545 8060
Mobile: +44 (0)79 0661 2237

Peter Reilly <>
10/05/2004 04:49 PM
Please respond to "Ant Users List"

        To:     Ant Users List <>
        Subject:        Re: Thinking in Ant...

Ant (or make) is not a general purpose scripting language!
Mr. Bourne wrote a pretty good scripting language.

There are a number of issues with using ant as a scripting language:

 - there is no pipe like mechanism
 - the tasks are not ortoginal (concat has different parameters than 
copy for example)
 - property imutablilty makes things difficult.
 - support for looping is done via third-party addons like ant-contrib 
or antxtras.

 - (ant-contrib's var unset=true uses reflection to get access to 
private fields so it might
   not work in future releases of ant)

One can extend ant by writting new tasks/types so
here is my solution to the problem:

    <pr:scripttypedef name="relativefileset" language="beanshell">
      import java.util.ArrayList;
      import java.util.Iterator;
      public class RelativeFileSet extends ProjectComponent {
         private ArrayList list = new ArrayList();
         public void addConfigured(FileSet fileset) {
            for (file : 
fileset.getDirectoryScanner(getProject()).getIncludedFiles()) {
         public Iterator iterator() {
            return list.iterator();

    <property name="source.dir" location=".."/>
    <property name="target.dir" location="target"/>
    <mkdir dir="${target.dir}"/>

    <ac:for param="file">
        <fileset dir="${source.dir}" includes="**/build.xml"/>
        <concat destfile="${targetdir}/@{file}.concatenated">
          <fileset file="${source.dir}/@{file}"/>
              <token key="parameter" value="value"/>

Matt Benson wrote:

>--- Richard Russell <> wrote:
>>I tried using <for> and <var>, but found that I
>>couldn't do much with 
>><var>, as it appeared that the only way I could set
>>the var was with the 
>><var> task, and I needed to use functionality in
>><propertycopy> to get 
>>double-redirection. I can't *quite* recall why this
>>didn't work, but it 
>>didn't. If you like, I'll try to recreate what I was
>>trying to do, and see 
>>if I can demonstrate the problem I had...
>Okay... my understanding of the problem was that you
>had a set of files whose contents you wanted to append
>to identically named files in another location... so I
>am ignoring recursive property resolution because I
>don't see how it applies... <var> is for use with
><pathconvert>.  You don't *really* need it, but here I
>would use it personally.  Even better would be local
>properties for macros, but that's another story... so
>we are going to use <for> and <concat>...
>>I'm not sure what <pathconvert> can do for me
>>here... A mapper sounds more 
>>useful (eg <globmapper from="${dir1}/*"
>>to="${dir2}/*"/>), but I don't think it can be used
>>with <concat> ...
>Ah, but since 1.6.2 <pathconvert> supports a nested
><mapper>.  Actually before that it also supported
>limited mapping via its <map> subelements, but I'm
>personally more comfortable with <mapper>s so that's
>what we'll use here... the following is untested:
><property name="dest.dir" location="dest" />
><property name="src.dir" location="src" />
><!-- mapper may not be perfect; experiment -->
><mapper id="src2dest" type="glob"
>        from="${src.dir}/*" to="${dest.dir}/*" />
><for param="f">
>  <fileset id="fs" dir="${src.dir}" includes="*" />
>  <sequential>
>    <!-- unset so we can reuse -->
>    <var name="destfile" unset="true" />
>    <fileset id="f" file="@{f}" />
>    <pathconvert property="destfile">
>      <path>
>        <fileset refid="f" />
>      </path>
>      <mapper refid="src2dest" />
>    </pathconvert>
>    <concat destfile="${destfile}" append="true">
>      <fileset refid="f" />
>    </concat>
>  <sequential>
>As you can see, I only used <var> to unset the
>destfile property.  The alternative is to use a
>different property for every file... @{f}.dest
>perhaps, but large numbers of dynamically generated
>property names just feels wrong to me.  That's an old
>argument.  Anyway, the above should be somewhere in
>the neighborhood assuming I understood the problem
>Do you Yahoo!?
>New and Improved Yahoo! Mail - Send 10MB messages!
>To unsubscribe, e-mail:
>For additional commands, e-mail:

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

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

View raw message