我有一些我想调用的macrodef任务,但是我想用一些时间戳代码来包装调用。如果任务是目标而不是宏def,那么使用antcall可以很容易地做到这一点。
有可能用macrodef做同样的事情吗?
例子:
"macrocall" 行是我想使用的假设类型的任务(类似于"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>
为什么不将macro1 macro2与目标包裹起来,并为"macrocall"使用antcall呢?新的macro1, macro2目标将在各自的项目中运行(属性和ref被传入,但不退出),这可能是一件好事,也可能不是,这取决于你想要完成什么。
据我所知,没有一种纯粹的方法可以完成你想要的——动态调用任务。您可能需要找到一些外部包来接近,但它可能会更难看。
这是一个非常晚的回复,但我一直在努力解决同样的问题一段时间,现在才想到一个解决方案,所以我想我应该贡献一下。
首先,我认为可以肯定地说,仅仅使用Ant是没有办法做到这一点的,除非做一些非常糟糕的事情,比如将Ant代码回显到一个新文件中,然后从文件中调用macrodef。
无论如何,我决定使用Groovy Ant任务来运行一些Groovy代码。这是我想到的:
<groovy>
ant."${properties["macrodef.name"]}"("dir":properties["dir"])
</groovy>
解释:
—ant.
只是告诉Groovy运行Ant任务的前缀。例如,ant.echo()
运行<echo>
。
- "${properties["macrodef.name"]}"
从我的Ant项目中提取名为"macrodef.name"的属性。
—像这样将上面两个组合在一起,我告诉Groovy以与属性"macrodef.name"的值相同的名称运行一个Ant任务。例如,如果我的Ant项目中的${macrodef.name}
当前持有"compile"的值,Groovy将把这行读取为ant.compile
。
- ("dir":properties["dir"])
告诉Groovy使用同样名为"dir"的Ant属性的值运行带有"dir"属性的macrodef。需要说明的是,这是因为我的macrodef需要这个属性。在Ant中,看起来像这样:<compile dir="${dir}" />
我希望这能帮助任何遇到它的人!需要说明的是,我希望避免使用更通用的<script>
任务,因为它显然比基本Ant或Groovy任务运行得慢得多。理想的解决方案可能是实际编写一个自定义Ant任务,但不幸的是,我还没有足够的知识来做到这一点。
有两种方法可以动态解析macrodef name
1) Macrodef名称不是常量,并在加载时根据"what-to-say"变量进行解析。因此,只有一个macrodef获得了"saywhat"的名称,其他的名称没有被解析(因此无法调用)
<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)创建两个带有macrodef定义的附加文件,例如
<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>
并将其中一个包含到您的主项目
<property name="what-to-say" value="bye"/>
<import file="macrodefs-${what-to-say}.xml"/>
<target name="test">
<say-something/>
</target>