开发者

Can a macrodef Task be Called Dynamically

I have a number of macrodef tasks that I would like to call but would like to wrap the calls with some timestamping code. This could be easily done if the tasks were targets instead of macrodefs by using antcall.

Is it possible to do the same thing with macrodef?

Example:

The "macrocall" l开发者_Python百科ine is the hypothetical kind of task that I would like to use (akin to "antcall")

<target name="run.tests">
    <run.named.test name="macro1" />
    <run.named.test name="macro2" />
</target>

<macrodef name="run.named.test">
    <attribute name="name" />
    <sequential>
        <echoTime />
        <macrocall name="@{name}" />
        <echoTime />
    </sequential>
</macrodef>

<macrodef name="macro1">
</macrodef>

<macrodef name="macro2">
</macrodef>


Why not wrap your macro1 macro2 with targets and use an antcall for the "macrocall". the new macro1, macro2 targets will each run in their own project (properties and ref passed in, but not back out) which may or may not be a good thing depending on what you're trying to accomplish.

There no pure ant way to accomplish what you want as far as i know -- dynamically calling a task. You'd probably need to find some outside package to even come close, but it would probably be uglier.


This is a very late reply, but I had been struggling with the exact same issue for a while and just now came up with a solution, so I figured I'd contribute.

First of all, I think it's safe to definitively say that there is no way to do this simply with Ant alone, outside of doing something extremely hacky like echoing Ant code to a new file and then calling a macrodef from the file.

Anyway, I decided to use the Groovy Ant task to run some Groovy code. Here's what I came up with:

<groovy>
    ant."${properties["macrodef.name"]}"("dir":properties["dir"])
</groovy>

Explanation:

-ant. is simply the prefix for telling Groovy to run an Ant task. For example, ant.echo() runs the <echo> task.

-"${properties["macrodef.name"]}" pulls the property named "macrodef.name" from my Ant project.

-With the two above combined together like this, I'm telling Groovy to run an Ant task with the same name as the value of the property "macrodef.name". For example, if ${macrodef.name} in my Ant project currently holds the value of "compile", Groovy will read this line as ant.compile.

-("dir":properties["dir"]) tells Groovy to run the macrodef with the attribute "dir" using the value of the Ant property also named "dir". To be clear, this is because my macrodef requires this attribute. In Ant, it would look like this: <compile dir="${dir}" />

I hope this helps anyone who comes across it! For the record, I wanted to avoid using the more generic <script> task, because apparently it runs noticeably slower than basic Ant or the Groovy task. The ideal solution would probably be to actually write a custom Ant task, but unfortunately I don't quite have to knowledge to do that yet.


There are two ways to resolve macrodef name dynamically

1) Macrodef names are not constant and resolved during load time depending on "what-to-say" variable. As a result, only one macrodef gets "say-something" name, there other one's name is not resolved (so not available to call)

<property name="what-to-say" value="bye"/>

<property name="say-${what-to-say}" value="say-something"/>

<macrodef name="${say-hi}">
        <sequential>
            <echo>hi!</echo>
        </sequential>
</macrodef>
<macrodef name="${say-bye}">
        <sequential>
            <echo>bye!</echo>
        </sequential>
</macrodef>

<target name="test">
    <say-something/>
</target>

2) Create two additional files with macrodef definitions, e.g.

<project name="macrodefs-hi.xml>
    <macrodef name="say-something">
            <sequential>
                <echo>hi!</echo>
            </sequential>
    </macrodef>
</project>
<project name="macrodefs-bye.xml>
    <macrodef name="say-something">
            <sequential>
                <echo>bye!</echo>
            </sequential>
    </macrodef>
</project>

And include just one of them to your main project

<property name="what-to-say" value="bye"/>

<import file="macrodefs-${what-to-say}.xml"/>

<target name="test">
    <say-something/>
</target>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜