我正在尝试使用macrodef
"函数化"几行反代码。但是它会导致如下错误:
copy doesn't support the nested "my-macro" element.
如果我"内联"我的宏的定义,在复制任务中添加过滤器,它可以工作。
我的测试目标看起来像这样-
<target name="copy-files">
<sequential>
<copy todir="abc" >
<fileset dir="xyz">
<!--needy includes/excludes -->
</fileset>
<my-macro/>
</copy>
</sequential>
</target>
my-macro是这样的:
<macrodef name="my-macro">
<sequential>
<filterchain>
<fixcrlf includes="**" eol="lf"/>
</filterchain>
</sequential>
</macrodef>
正常工作的代码(inline -one)如下所示:
<target name="copy-files">
<sequential>
<copy todir="abc" >
<fileset dir="xyz">
<!--needy includes/excludes -->
</fileset>
<filterchain>
<fixcrlf includes="**" eol="lf"/>
</filterchain>
</copy>
</sequential></target>
复制任务不接受嵌套的宏元素,这是errormessage告诉我们的。
将所有的copy内容放入macrodef中,例如:
<macrodef name="my-macro">
<attribute name="dest"/>
<attribute name="fsdir"/>
<attribute name="fsincludes"/>
<attribute name="fsexcludes"/>
<attribute name="fixincl"/>
<sequential>
<copy todir="@dest}">
<fileset dir="@{fsdir}">
<include name="@{fsincludes}"/>
<exclude name="@{fsexcludes}"/>
</fileset>
<filterchain>
<fixcrlf includes="@{fixincl}" eol="lf"/>
</filterchain>
</copy>
</sequential>
</macrodef>
—EDIT—
如果文件集的数量不同,如果对所有文件集无效,则删除fsincludes和fsexcludes属性,并使用如下元素:
<macrodef name="my-macro">
<attribute name="dest"/>
<element name="fs" description="nested filesets"/>
<attribute name="fixincl"/>
<sequential>
<copy todir="@dest}">
<!-- 1-n nested filesets) -->
<fs/>
<filterchain>
<fixcrlf includes="@{fixincl}" eol="lf"/>
</filterchain>
</copy>
</sequential>
</macrodef>
<my-macro dest="C:/whatever" fixincl="**">
<fs>
<fileset dir="." includes="**/*.foo"/>
<fileset dir="../foo" includes="**/*.xml"/>
<!-- ... -->
</fs>
</my-macro>
—EDIT—
要复制带有嵌套文件集的单个文件,使用:
<fileset file="C:/somepath/some.file"/>
—EDIT—如果需要文件到文件的其他复制步骤,如果足够的话,可以使用其他元素:
<macrodef name="my-macro">
<attribute name="dest"/>
<element name="copyfiles" description="nested copy"/>
<element name="fs" description="nested filesets"/>
<attribute name="fixincl"/>
<sequential>
<copy todir="@dest}">
<!-- 1-n nested filesets) -->
<fs/>
<filterchain>
<fixcrlf includes="@{fixincl}" eol="lf"/>
</filterchain>
</copy>
<copyfiles/>
</sequential>
</macrodef>
<my-macro dest="C:/whatever" fixincl="**">
<fs>
<fileset dir="." includes="**/*.foo"/>
<fileset dir="../foo" includes="**/*.xml"/>
<!-- ... -->
</fs>
<copyfiles>
<copy file="..." tofile="..."/>
<!-- ... -->
</copyfiles>
</my-macro>
通常对于文件的批量重命名使用映射器。
毕竟,如果它变得更复杂,您应该考虑使用Groovy编写脚本,或者编写自己的Ant Task。
Rebse的答案已经显示了您应该如何使用<macrodef>
,下面是一些解释。
<copy>
、<macrodef>
、<sequential>
为Ant任务。每个Ant任务都有Java代码支持。大多数内置Ant任务的Java类都在org.apache.tools.ant.taskdefs
下,例如Copy.java是<copy>
任务的后端。
任务的嵌套元素由任务的Java代码处理。对于<copy>
任务,它是Copy.java(或它所依赖的其他类)中处理嵌套元素的代码。
您将在Copy.java中看到以createFilterChain
、addFileset
、createMapper
和其他名称命名的方法。这就是为什么<copy>
支持文件集,过滤器链,映射器和其他嵌套元素在Copy的手册页中说明的原因。
Macrodef
使用嵌套任务作为模板定义一个新任务。
Macrodef是一种不用Java编码就可以定义Ant任务的方法。它将嵌套的Ant xml行转换为一个新任务,其工作方式与其他Ant任务相同。
显然,您不应该仅仅将<filterchain>
放在<macrodef>
中,因为<filterchain>
不是Ant任务,而是Ant类型。