tags:

views:

28

answers:

2

Say that I need to do something like:

<copy todir="${DEPLOYMENT_DIR}" overwrite="true">
    <fileset dir="dir1" />
    <fileset dir="dir2" />
    <fileset dir="dir3" />
    ...
    <if>
        <equals arg1="${SPECIAL_BUILD}" arg2="true"/>
        <then>
            <fileset dir="dir7" />
            <fileset dir="dir8" />
            ...
        </then>
    </if>
</copy>

(The real task is not copy, I'm just using it to illustrate the point.)

Ant will complain that my task doesn't support nested <if> which is fair enough. I've been thinking along these lines:

I could add a macrodef with an "element" attribute like this:

<macrodef name="myCopy">
    <element name="additional-path" />
    <sequential>
        <copy todir="${DEPLOYMENT_DIR}" overwrite="true">
            <fileset dir="dir1" />
            <fileset dir="dir2" />
            <fileset dir="dir3" />
            ...

            <additional-path/>
        </copy>
    </sequential>
</macrodef>

But that would mean that the caller (target) must specify the additional path which I want to avoid (if many targets call this task, they would have to repeat the fileset definitions in the additional-path element).

How to code the additional filesets inside the macrodef so that Ant doesn't complain?

+1  A: 

AntContrib has an Ant FileSet object augmented with if and unless conditions.

http://ant-contrib.sourceforge.net/fileset.html

if Sets the property name for the 'if' condition. The fileset will be ignored unless the property is defined. The value of the property is insignificant, but values that would imply misinterpretation ("false", "no") will throw an exception when evaluated.

unless Set the property name for the 'unless' condition. If named property is set, the fileset will be ignored. The value of the property is insignificant, but values that would imply misinterpretation ("false", "no") of the behavior will throw an exception when evaluated.

You could use it like this:

<copy todir="${DEPLOYMENT_DIR}" overwrite="true">
    <fileset dir="dir1" />
    <fileset dir="dir2" />
    <fileset dir="dir3" />
    ...
    <fileset dir="dir7" if="SPECIAL_BUILD" />
    <fileset dir="dir8" if="SPECIAL_BUILD" />

</copy>
Mads Hansen
That's nice but the copy+fileset was chosen just as an example. In my case the "copy" is "mxmlc" (Flex application compiler) and "fileset" is "include-libraries". Still upvoting as the contrib FileSet seems useful.
Borek
@Borek - another approach that I have taken is to invoke an XSLT stylesheet to build a costom ANT build.xml, then invoke that custom-generated build.xml file from within the main build.xml's target. If you update the question with something more in line with what you are trying to do, I could post an example.
Mads Hansen
I'd rather stay with "pure Ant" which is messy enough :) I've posted my current solution - not the most elegant one but achieves the task.
Borek
That's cool. It's probably the most appropriate for your needs. FYI - `<if>` is not "pure Ant", it's also an ant-contrib extension that is more procedural than declarative Ant style.
Mads Hansen
A: 

One way (not sure if a good one) to achieve that is to create two macrodefs - one "public" for general use and one "internal" that does the real work and is intended to be called only from the "public" macro. Like this:

<macrodef name="task-for-public-use">
    <sequential>
        <if>
            <equal arg1="${SPECIAL_BUILD}" arg2="true" />
            <then>
                <internal-task>
                    <additional-path>
                        ...
                    </additional-path>
                </internal-task>
            </then>
            <else>
                <internal-task ... />
            </else>
        </if>
    </sequential>
</macrodef>


<macrodef name="internal-task">
    <element name="additional-path" />
    <sequential>
        <copy ...>
            ...
            <additional-path/>
        </copy>
    </sequential>
</macrodef>

I don't like it much though and hope there's a better way.

Borek