I would like to call a macro from inside an element of another macro.
Let's suppose I have the following macro:
<macrodef name="jc">
<attribute name="name" />
<attribute name="destdir" />
<element name="fileset-list" optional="false" />
<sequential>
<jar destfile="#{destdir}${file.separator}#{name}.jar" update="false">
<fileset-list />
<manifest>
<attribute name="Manifest-Version" value="1.0" />
</manifest>
</jar>
</sequential>
</macrodef>
and another macro
<macrodef name="defaultfs" description="Defines the default fileset">
<attribute name="path" />
<sequential>
<fileset dir="${dir.build.classes}">
<include name="#{path}/**/*.class" />
</fileset>
<fileset dir="${src.ehs}">
<include name="#{path}/**/icons/**" />
<include name="#{path}/**/sounds/**" />
<include name="#{path}/**/*.gif" />
<include name="#{path}/**/*.png" />
<include name="#{path}/**/*.wav" />
<include name="#{path}/**/*.jpg" />
<include name="#{path}/**/*.properties" />
<include name="#{path}/**/*.xml" />
<include name="#{path}/**/jaxb.index" />
</fileset>
</sequential>
</macrodef>
I use these macros as follow:
<jc destdir="${dir.build.jar}" name="thejar">
<fileset-list>
<defaultfs path="org/path/inner" />
</fileset-list>
</jc>
What I get is the following error message:
jar doesn't support the nested "defaultfs" element.
What is wrong?
You could try making macro call within your main macro 'jc' and pass fileset path to consider as an additional attribute
<macrodef name="jc">
<attribute name="name" />
<attribute name="destdir" />
<attribute name="fileset.path.to.consider" />
<sequential>
<jar destfile="#{destdir}${file.separator}#{name}.jar" update="false">
<defaultfs path="#{fileset.path.to.consider}"/>
<manifest>
<attribute name="Manifest-Version" value="1.0" />
</manifest>
</jar>
</sequential>
</macrodef>
And then your main macro call could look like :
<jc destdir="${dir.build.jar}" name="thejar" fileset.path.to.consider="org/path/inner"/>
(not tested, you could give it a try )
Related
I have an Ant Macrodef that has an <element> placeholder. I am attempting to use the <element> to pass a resourceCollection for processing. The contents of the <element> is populated correctly prior to invoking the macrodef. Unfortunately, during invocation, it comes in as empty.
Macrodef:
<macrodef name="doStuff" description="Amazing macrodef that fails me.">
<element name="fs" optional="true" description="resource/element/fileset to be manipulated />
<sequential>
<echo message="fs: ${toString:fs}" />
<pathconvert property="outputProp" pathsep=" ">
<fs />
</pathconvert>
</sequential>
</macrodef>
and it is invoked via the following pieces of a build.xml file I have:
<fileset id="files1" dir=".">
<include name="inc/*" />
<include name="lib/*" />
</fileset>
<fileset id="files2" dir=".">
<include name="bin/*" />
</fileset>
<union id="allFiles">
<resources refid="files1" />
<resources refid="files2" />
</union>
<target name="doStuffToFiles">
<doStuff>
<fs>
<resources refid="allFiles" />
</fs>
</doStuff>
</target>
I'm unsure why, but going through the union and resources, instead of using a direct fileset with a refid, seemed to be confusing my Ant setup. The following has worked for me on Ant 1.9.2
<macrodef name="doStuff" description="Amazing macrodef that fails me.">
<element name="fs"
optional="false"
description="resource/element/fileset to be manipulated />
<sequential>
<pathconvert property="outputProp" pathsep=" ">
<fs />
<map from="${basedir}/" to=""/>
</pathconvert>
</sequential>
</macrodef>
<target name="doStuffToFiles">
<fileset id="files1" dir=".">
<include name="inc/**"/>
<include name="lib/**"/>
</fileset>
<fileset id="files2" dir=".">
<include name="bin/**"/>
</fileset>
<doStuff>
<fs>
<fileset refid="files1" />
<fileset refid="files2" />
</fs>
</doStuff>
</target>
I would like to use the fileset in below macrodef.
I wish to change attribute jar to dir so that all jar files in dir can be processed.
<macrodef name="unjartemp">
<attribute name="jar" />
<sequential>
<!-- Remove any existing signatures from a JAR file. -->
<tempfile prefix="unjar-"
destdir="${java.io.tmpdir}" property="temp.file" />
<echo message="Removing signatures from JAR: #{jar}" />
<mkdir dir="${temp.file}" />
<unjar src="#{jar}" dest="${temp.file}" />
<delete file="#{jar}" failonerror="true" />
</sequential>
</macrodef>
To keep it flexible you may use macrodef with nested element attribute for 1-n filesets, f.e.
a macrodef that creates a dirlisting in xmlformat for nested filesets :
<macrodef name="dir2xml">
<attribute name="file"
description="xmlfile for filelisting"/>
<attribute name="roottag"
description="xml root tag"/>
<attribute name="entrytag"
description="xml tag for entry"/>
<element name="fs"
description="nested filesets for listing"/>
<sequential>
<pathconvert
property="files.xml"
dirsep="/"
pathsep="</#{entrytag}>${line.separator} <#{entrytag}>"
>
<!-- 1-n nested fileset(s) -->
<fs/>
</pathconvert>
<!-- create xmlfile -->
<echo message="<#{roottag}>${line.separator} <#{entrytag}>${files.xml}</#{entrytag}>${line.separator}</#{roottag}>" file="#{file}"/>
</sequential>
</macrodef>
Usage :
<dir2xml file="filelistant.xml" entrytag="antfile" roottag="antfilelist">
<fs>
<fileset dir="." includes="**/*.xml"/>
<fileset dir="../ant_xml" includes="**/*.xml"/>
</fs>
</dir2xml>
Add your fileset:
<fileset dir="${jars.dir}" id="jars_to_unjar">
<include name="**/*.jar"/>
</fileset>
call you macros:
<unjartemp filesetref="jars_to_unjar"/>
And you can try this modified macros:
<macrodef name="unjartemp">
<attribute name="filesetref" />
<sequential>
<for param="file">
<fileset refid="#{filesetref}"/>
<sequential>
<!-- Remove any existing signatures from a JAR file. -->
<tempfile prefix="unjar-"
destdir="${java.io.tmpdir}" property="temp.file" />
<echo message="Removing signatures from JAR: #{file}" />
<mkdir dir="${temp.file}" />
<unjar src="#{file}" dest="${temp.file}" />
<delete file="#{file}" failonerror="true" />
</sequential>
</for>
</sequential>
</macrodef>
I have the following code:
<dirset id="aa" dir="FOLDER" includes="example*" excludes=".*">
</dirset>
<pathconvert pathsep="," property="bb" refid="aa">
<mapper type="flatten"/>
</pathconvert>
<echo message="LIST:${bb}"/>
and the output is for example 'examle.aa,example.bb'
And I would like to call another target for each example.*.. Can you help me please?
A macrodef would work for this, you could invoke it with custom attributes or elements based on you current property:
macrodef
Try antcontrib for the loop functionality. Here's an example
<project>
<target name="test">
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="./lib/ant-contrib-1.0.jar" />
<for param="file">
<dirset dir="." />
<sequential>
<task dir="#{file}" />
</sequential>
</for>
</target>
<macrodef name="task">
<attribute name="dir" />
<sequential>
<echo>#{dir}</echo>
</sequential>
</macrodef>
</project>
Please, find below a few targets from my ant file:
<fileset id="test-dep-jars" dir="o:/java">
<include name="junit-4.10.jar"/>
<include name="easymock-3.1\easymock-3.1.jar"/>
<include name="easymockclassextension-3.1\easymockclassextension-3.1.jar"/>
</fileset>
<target name="copy-test-deps">
<mkdir dir="${deploy.dir}"/>
<copy todir="${deploy.dir}">
<fileset refid="test-dep-jars"/>
<flattenmapper/>
</copy>
</target>
<target name="jar" depends="copy-test-deps">
<jar destfile="${deploy.dir}/test-${ant.project.name}.jar" basedir="${test.classes.dir}"
includes="**/*.class" filesetmanifest="skip">
<manifest>
<attribute name="Class-Path"
value="${ant.project.name}.jar junit-4.10.jar easymock-3.1.jar easymockclassextension-3.1.jar"/>
</manifest>
</jar>
</target>
My problem is that I have to state the test dependency jars twice - once when defining the test-dep-jars fileset and the second time when specifying the Class-Path manifest attribute of the produced jar.
If I only could get hold on the flattenmapper result, then I would be able to use it in the Class-Path as is.
How can I get hold on the flattenmapper result?
Thanks.
If you want to use flattenmapper you can use following...
<pathconvert property="mf.classpath" pathsep=" ">
<path refid="build.class.path" />
<flattenmapper />
</pathconvert>
<manifest>
<attribute name="Class-Path"
value="${ant.project.name}.jar ${mf.classpath}"/>
</manifest>
I would recommend using the manifestclasspath task instead:
<manifestclasspath property="jar.classpath" jarfile="${jar.file}">
<classpath>
<fileset dir="${deploy.dir}" includes="*.jar"/>
</classpath>
</manifestclasspath>
<jar destfile="${jar.file}" basedir="${classes.dir}">
<manifest>
<attribute name="Main-Class" value="${jar.main.class}" />
<attribute name="Class-Path" value="${jar.classpath}" />
</manifest>
</jar>
It will generate the correct classpath property definition and even works with relative paths (for example if you were to place the dependent jars in sub-directory).
The following attempts to make copies of a list of directories. It doesn't copy anything. Are filelists not permitted to reference directories?
<macrodef name="collect-services-from-build-tree">
<attribute name="src" default="NOT SET"/>
<attribute name="target" default="NOT SET"/>
<sequential>
<property name="src" value="#{src}"/>
<property name="target" value="#{target}"/>
<filelist id="packages" dir="${src}">
<!-- more like this -->
<file name="interface/ui/ui-server/target/ui-install"/>
</filelist>
<delete dir="${target}" quiet="true"/>
<mkdir dir="${target}"/>
<copy todir="${target}">
<filelist id="packages"/>
</copy>
</sequential>
</macrodef>
Try changing :
<copy todir="${target}">
<filelist id="packages"/>
</copy>
Into :
<copy todir="${target}">
<filelist refid="packages"/>
</copy>