| “Strategies in (*)ability” | [iDareMedia] [JWare] [PET] [CI-Dashboard] |
We originally created the JWare/AntXtras packages as part of our internal continuous-integration build environment. Because a large percentage of the Ant components were generic and could be used by other Ant users, we released them under the JWare open-source umbrella. The JWare/AntXtras Foundation package (AntX) includes our most independent and reusable Ant components divided into five main categories: Fixture-Control, Execution-Rules, Flow-Control, Feedback, and Helpers. You can select individual AntX components or use the entire package in your own Ant build scripts.
The rest of this overview will introduce you to AntX: it will briefly describe the most important AntX components and demonstrate some of their uses in a build program. Throughout our descriptions, we use the term “taskset” to refer to a task that can contain other tasks; see the “JWare/AntXtras Foundation Quick Start Guide” for a discussion on tasksets and other fundamental AntX design concepts and terminology. The Quick Start Guide also contains many more build scripts that demonstrate the range of AntX’s capabilities. Use the “JWare/AntXtras Foundation User Guide” as a detailed catalog of all AntX tasks, types, conditions, and their options. See the AntX Value URIs Guide for the builtin value URI handler documentation. Subscribe to our announcements mailing list to be notified of new AntX releases.
AntX and its documentation are written for experienced Ant users and developers. AntX is not intended for someone new to Ant or for someone evaluating Ant unless you are concerned about the Ant shortcomings that AntX specifically addresses. AntX, binary and source form, is released under the Free Software Foundation’s GNU LGPL; a copy of this license can be found on the Free Software Foundation’s website at http://www.fsf.org/licenses/lgpl.html. Please read the LGPL carefully before using any of the AntX source in your own application.
| Task/Type | General Description |
| msgsbundle, strings, properties, etc. |
Shareable, structured items containing build fixture data (messages, URLs, files, etc.). Because structured items are usually verified as they are created instead of when they are (first) used, you notice invalid declarations or modifications immediately. You would use structured data for a variety of reasons: to minimize the number of attributes a macrodef defines, or to group related properties together explicitly, or to control the various AntX looping tasks. |
| managebundles, manageuris, etc. |
Administrator tasks that let you define primordial build fixture settings; for instance, the <managebundles> task lets you define the top-level messages resource bundle for the various AntX feedback tasks that can read messages from resource bundles. Like standard <typedef>s or <macrodefs>s, you can use any administrator task as part of an antlib script that is loaded by your build’s initialization. |
| autorun | A taskset that is defined in a standard Ant antlib script and automatically executed when the antlib is loaded. The <autorun> task exists mainly for two reasons: to let you decorate a core (readonly) script for your specific needs, and to let you include otherwise antlib-incompatible fixture control tasks (like <property>) inside a single antlib script. |
| isolate, overlay |
Tasksets that let you control locally what a set of tasks see and affect in the active project’s environment. The <isolate> task lets you create a “bubble” that shields the project from most modifications and an <overlay> lets you create a “net” that removes, adds, or overrides selective bits of fixture (i.e. properties) for enclosed tasks. |
| overlay-msgs, overlay-emit, etc. |
Configuration tasksets that let you overlay custom types of information for enclosed tasks; for example, the <overlay-msgs> taskset lets you add another messages resource bundle that nested tasks can access when they search for messages. |
| assign, assignimport, unassign |
Tasks to create and edit mutable properties (also called variables or exported properties) that persist across task, target, and (sub)project boundaries. Mutable properties let you reduce the number of extraneous, temporary properties you would otherwise create with the standard Ant write-once properties. Editable properties are also very useful when you need to create automated test scripts or to time the duration of tasks. |
| datadef | A task that lets you conditionally create and insert data objects into the project’s reference table. Basically the data object’s reference id (id) is not made public (to be referenced via a refid) until its enclosing target or script block is executed. |
| capturelogs, copylogged, |
Tasks that capture and save task outputs and byproducts for further processing or examination. These tasks are also very useful when you want to capture and verify task output in automated test scripts. |
| copyproperty, copyreference |
Tasks to copy resource messages, other properties, variables, and references to standard project properties. Also useful when combined with AntX’s flow-control tasks to pass-along fixture information to sub-projects. |
You can chain value URIs by piping the results of the first handler into a second and those results into a third and so on; for example “${$var:nextname|$property:|$ospath:}” converts the property defined by the the variable nextname to a absolute platform-specific path. The pipe instruction is the “|” (vertical bar). Only the first handler can have a query portion in its fragment; subsequent handlers are passed a fragment that is composed of the results of the preceding handler and any custom query string.
To get your value URIs interpreted, you must install the AntX custom property handler using the <manageuris> task. This task also lets you define exactly which schemes you want to activate in the current build iteration. Because child projects do not automatically inherit their parent’s property handlers, you must call <manageuris> to activate value uri handling in child projects (you do not have to reinstall each uri handler, you only need to activate processing). Below is a partial description of the builtin AntX value URI schemes. See the antx/valueuri/antlib.xml file in the AntX distribution for the complete list of builtin value URIs. See the AntX Value URIs Guide and javadocs for a detailed description of your input’s expected format.
| URI Scheme | General Description |
| $prop: or $property: |
[Fixed] Extracts the named property’s current setting and supports C-style -> to get at items inside a <properties> or <propertyset>. Also helps minimize attribute declaration lists for <macrodef>s. |
| $var: or $variable: |
[Fixed] Extracts the named mutable property’s current setting. Also useful as a workaround to the missing recursive property expansion in Ant. |
| $default: | Extracts default AntX build-iteration options. This includes options defined by AntX as well as those defined by the application. Helps minimize dependency on explicit configuration property names. |
| $string: or $message: |
Extracts a message from the current build iteration’s installed resource bundles. Like an inlined <copymsg> that does not generate a new project property. |
| $list:, $map: |
Extracts information from a structured list or map data object like a <strings> or <properties> object. Because several AntX tasks let you generate an item collections dyamically, you need a way to access such an item’s contents. |
| $criteria: or $test: |
Executes the named AntX <tally> or <criteria> and reflects its results as a simple boolean string. Lets you seamlessly link task execution with complex execution criteria. |
| $alltrue:, $isnumeric:, etc. |
Executes the named AntX short hand condition and reflects its results as a simple boolean string. The complete list of short hand conditions is included in the AntX QuickStart Guide. Like inlined versions of AntX’s new conditions that you can use with flow control tasks. |
| $newrefid:, $random: |
Generates a pseudo-random values (strings or integers). You can use these functions to generate a transient reference id or scratch property names that are unique within a particular project. |
| $ospath:, $uppercase:, etc. |
Converts the fragment part of the URI according to the named transformation. Currently limited to a subset of the <copyproperty>’s transform parameter. |
| $iteration: | Extracts various bits of information about the current AntX iteration; for instance, you can find out the iteration’s implementation class name. Useful as a diagnostic aid. |
| $truefalse: | Normalizes Ant boolean strings like “yes” and “off” into either “true” or “false”. |
<capturelogs importantfrom="info" splitentries="yes" includesource="yes">
<javadoc packagenames="com.mycompany.*" sourcepath="src" destpath="docs/apis" ...>
...
</javadoc>
<copylogged tofile="${logs.dir}/javadoc.log"/>
</capturelogs>
2) The following macrodef snippet declares a structured strings list template.filetypes the first time it is called if and only if the enclosing project does not already include such a data object. The <datadef> task lets the macro create a default dataset if the project does not provide its own.
<macrodef name="mktemplatefilters">
...
<datadef name="template.filetypes" overwrite="no">
<strings>
<string value="txt"/>
<string value="java"/>
<string value="xml"/>
<string value="properties"/>
</strings>
</datadef>
<foreach i="filetype" items="template.filetypes" mode="local">
...
3) The following script snippet declares a structured URL list default.webservers. The URLs are verified for well-formedness as the data item is declared not when (if) the item is ever used. The data item will be used directly by other AntX components like the flow-control <callforeach>.
<urls id="default.webservers" prefix="http://www." suffix=".info/">
<url value="idaremedia"/>
<url value="jware"/>
<url value="antxtras"/>
</urls>
...
<callforeach i="url" items="default.webservers" tryeach="yes" mode="local"
macros="check-http-alive,http-alive-update"/>
4) The following script snippet uses AntX mutable properties to record how long it takes to compile a particular set of java sources. The captured information is then broadcast to all build monitors.
<target name="compile-apis" depends="...">
<emit msgid="banner.compiling" msgarg1="APIs"/>
<assign var="time" op="now"/>
<copyproperty name="compile.start" variable="time" transform="datetime"/>
<javac srcdir="${source}" destdir="${classes}"
debug="${javac.isdebug}" optimize="${$not:javac.isdebug}"
deprecation="${javac.isdebug}"
includes="**/*.java"
excludes="**/doc-files/"/>
<assign var="time" op="-now"/>
<copyproperty name="compile.duration" variable="time" transform="duration"/>
<emit msgid="banner.compiling.done"
msgarg1="${compile.start}" msgarg2="${compile.duration}"/>
</target>
5) The following macrodef snippet is a reworking of the preceding example so that the common compilation tasks can be reused for different sets of java sources. The macrodef relies on AntX mutable properties and the $var: value URI to record how long it takes to compile a particular set of java sources. The captured information is then broadcast to all build monitors.
<macrodef name="compilejava">
...
<emit msgid="banner.compiling" msgarg1="@{caller}"/>
<assign var="time" op="now"/>
<assign var="compile.start" fromvar="time" transform="datetime"/>
<javac srcdir="@{sources}" destdir="@{classes}"
debug="${javac.isdebug}" optimize="${$not:javac.isdebug}"
deprecation="${javac.isdebug}"
includes="**/*.java"
excludes="**/doc-files/"/>
<assign var="time" op="-now"/>
<assign var="compile.duration" fromvar="time" transform="duration"/>
<emit msgid="banner.compiling.done"
msgarg1="${$var:compile.start}" msgarg2="${$var:compile.duration}"/>
...
6) The following script snippet shows part of a macrodef mkreadmes’s definition that uses some of the AntX value URIs to gain access to different kinds of information for use as fall back values.
<macrodef name="mkreadmes">
<attribute name="haltiferror" default="${$default:haltiferror}"/>
<attribute name="license" default="${$default:license?LGPLv2-1}"/>
<sequential>
...
</macrodef>
[Back to top]| Task/Type | General Description |
| assert, fixturecheck |
A combination of the <condition> and <fail> tasks; if the condition is false the build process is immediately stopped. These tasks are designed to provide an extensive range of test conditions with minimal build script. You can disable the <assert> task by setting the appropriate configuration option. |
| prefer | A combination of the <condition> and <property> tasks; if the condition is false, a property is (re)set to some default value. This task allows a build script to specify default values for undefined or improperly defined build properties while issuing the appropriate warnings to the build’s monitors. |
| rule | A reusable condition definition comprised of either all requirements (<require>) or all preferences (<prefer>). Only useful if referenced by an AntX build-rule task like <assert>. |
| rulemacro | A rule macro definition comprised of either all requirements (<require>) or all preferences ((<prefer>). Useful if you want to create parameterized rules where caller supplies one more properties used in definition. |
| tally | A collection of condition evaluators. Extends the standard <condition> to include support for all the additional AntX conditions as well as shareable tallysets. |
| tallyset | A reusable collection of is-available type conditions. Only useful if referenced by an AntX <tally> task or another <tallyset>. |
| matches | A rule task that updates a project property if a value matches a specified regular expression (or not). Can also be used as an embedded condition. |
| criteria | A reusable test definition that can contain items other than conditions. Useful if you want to define non-trivial loop termination tests that are called repeatedly and have side-effects other than setting a single property or variable. |
| batchchecks | A wrapper taskset for <assert>s and <fixturecheck>s that lets you execute a set of checks in a single pass. If at least one check fails, the batch operation fails after all checks performed. |
<target name="-default-disttype" unless="defaults.disabled">
<-- checks the current value of our 'dist.type' ->
<assert isset="defaults.disttype" msgid="defaults.disttype.set"/>
<matches pattern="internal|local|public" property="dist.type"
falseproperty="broken.disttype"/>
<-- if not recognized, default and issue warning ->
<prefer isnotset="broken.disttype" msgid="warn.unknown.disttype"
falseproperty="dist.type" default="${$prop:defaults.disttype?local}"/>
</target>
2) The following build script excerpt uses a build-rule strict.dist to ensure certain properties are not defined at build-iteration start if a strict distribution is being generated. The rationale is that if these properties exist, the integrity of the build’s output cannot be guaranteed.
<rule id="strict.dist"> [a shareable "strict-dist" rule]
<require failproperty="dist.adhoc" msgid="err.dist.adhoc">
<noneset>
<property name ="build.number">
<property name ="disable.fetch">
<property name ="disable.clean">
<property name ="disable.docs">
</noneset>
</require>
</rule>
…
<target name="dist" depends="init,…">
…
</target>
…
<target name="strict-dist">
<assert ruleid="strict.dist"/> [enforce the prerequisite]
<callinline targets="dist"/> [then reuse "dist" target]
</target>
3) The following antlib snippet defines an AntX rule-based assertion that checks a series of build configuration prerequisites. If at least one of the assertions fails the entire rule fails but not before each requirement is checked. This batching lets the script report all the problems at one time. This rule might be evaluated by inserting the <assert-required-client-locations/> call in an initialization target.
<?xml version="1.0"?>
<antlib>
<rulemacro name="assert-required-client-locations">
<batchchecks> [look for *all* required configuration]
<assert isset="userscratch.dir"
msgid="saladbar.userscratch.set"
malformed="reject" whitespace="reject"/>
<assert isset="buildmeta.dir"
msgid="saladbar.buildmeta.set"
malformed="reject" whitespace="reject"/>
...[snip]
</batchchecks>
</rulemacro>
…
</antlib>
[Back to top]| Task/Type | General Description |
| protect | A taskset that captures build errors generated from nested tasks and allows the script-author to specify how to handle the error. Similar in functionality to the Java language try-catch-finally construct. |
| do, dowhile |
A sequence of conditionally executed tasks. Like the standard <sequential> task with support for an extended collection of execution condition specifiers. When used with a test attribute, the effect is like using an if-then Java-style construct. The <dowhile> taskset lets you execute the nested tasks repeatedly until the named test returns false (like a Java language while loop block construct). |
| domatch | A taskset that tries to match a selection criterion to a set of named, nested tasksets. If a choice is matched, the <domatch> executes the selected taskset’s nested tasks. Similar in functionality to the Java language if-else[if] construct or the switch-case-default construct but with support for non-constant choices. |
| step | A nested inlined target. Only useful when combined with either the <call>, <callinline>, or <callforeach> flow-control tasks. Although you can call them from within a script, steps do not register as standard Ant targets (that can be called from the command line). |
| call, callinline |
Tasks that execute a sequence of steps, targets, or macros. Both tasks provide a set of error-handling options if one or more of the called targets fail. Supplements the standard <antcall> task. |
| callforeach | An extension of the <call> task that adds several looping options. Includes support for iterating a series of strings, a FileSet, a DirSet, a Path, a bounded integer range, or any iterable data structure. |
| foreach | A variant of <callforeach> that defines the tasks to be executed within the foreach block itself. Similar in form to the Java language for-loop block construct. |
| stop or stopbuild | Like a <fail> but with support for resource bundle-based messages and custom build error types. |
<do unlessAntLike=".* 1\.5\.4 .*">
<property file="ant16.properties"/>
<typedef file="presets.xml"/>
</do>
2) The following macrodef snippet mkjunitreports loops through a passed-in reference test.properties that points to a map data object (like a <properties> or <propertyset>) and adjusts a dynamically built <junit> instruction. (Also note that this script relies heavily on the builtin AntX value URI handlers to do its work.)
<macrodef name="mkjunitreports">
<attribute name="test.properties" default=""/>
…
<-- create a <junit> instruction we can tweak ->
<assign var="myjunit" value="${$newrefid:?mkjunitreports}"/>
<createtask name="${$var:myjunit}">
<junit fork="yes" forkmode="perBatch">...[snip]
</createtask>
<-- add optional system properties to test run ->
<do true="${$notwhitespace:@{test.properties}}">
<foreach i="key" list="${$map:@{test.properties}?keys}" mode="local">
<altertask name="${$var:myjunit}" resolveproperties="yes">
<sysproperty key="${key}" value="${$map:@{test.properties}?@(key)}"/>
</altertask>
</foreach>
</do>
<-- now run our junit instruction for results ->
<performtask name="${$var:myjunit}"/>
<unassign var="myjunit"/>
…
</macrodef>
3) The following build file excerpt defines several build process steps inside a single public target. The target’s implementation is modular without exposing its internals as public-facing Ant targets. As shown, a user can only build against the actual Ant target, prepare-sources. Note that the checkout and merge steps are called for each module in the modules property.
<target name="prepare-sources" unless="disable.fetch">
<-- ensure fixture is setup properly ->
<assert msgid="err.prep.required.properties">
<isnotwhitespace property="modules"/>
<assert isdirectory="${work}"/>
<assert isdirectory="${originals}"/>
<isboolean property="is.public.build"/>
<isset property="SCM_TAG_DATE"/>
</assert>
<copyproperty name="cvstag" value="" unless="cvstag"/>
<-- (foreach) fetch new to readonly area ->
<step name="checkout">
<cvs command="checkout -A" dest="${originals}"
failonerror="${is.public.build}"
package="${module_id}" tag="${cvstag}"/>
<echo message="${SCM_TAG_DATE}"
file="${originals}/${module_id}/checkout.last"/>
</step>
<-- (foreach) merge new in work area ->
<step name="merge">
<copy filtering="true" todir="${work}" includeEmptyDirs="false">
<fileset dir="${originals}/${module_id}/java">
<include name="src/"/>
<include name="examples/">
</fileset>
<filterset refid="copyfilters.exported.srcfiles"/>
</copy>
</step>
<-- create combined work area for all modules ->
<callforeach i="module_id" list="${modules}" mode="local"
steps="checkout,merge"/>
</target>
4) The following build file excerpt defines a target “put-javadocs-latest” that can run javadoc for a series of named subdirectories, package the results as a single archive or as individual archives, and post the package(s) to a remote ftp server. The build iteration can specify an explicit list of subdirectories, or the default handling defaults to all subdirectories named in the file ${javadoc.projects.listfile}. The full definition has been abbreviated where it is not essential to showing use of an AntX flow-control tasks.
<criteria id="javadocs-uptodate" resultvar="out:javadocs-uptodate">
<assert isset="project" msg="javadocs-uptodate: '$project' set"/>
<property name="srcs" value="${basedir}/${project}/java"/>
<property name="html" value="${basedir}/${project}/docs/apis"/>
<tally truevariable="out:javadocs-uptodate">
<issettrue property="disable.apidocs"/>
<isnotset property="clean"/>
<uptodate targetfile="${html}/index.html">
<srcfiles dir="${srcs}">
...[snip]
</srcfiles>
</uptodate>
</tally>
</criteria>
...
<target name="put-javadocs-latest" depends="...">
<assign var="batchmode" value="${$issettrue:batch.enabled}"/>
<step name="mkjavadocs">
<do false="${$test:javadocs-uptodate}">
<javadoc .../>
<domatch value="${$var:batchmode}">
<true>
<zip .../>
</true>
<otherwise>
<zip .../>
<ftp .../>
<delete .../>
</otherwise>
</domatch>
</do>
</step>
<domatch value="${$property:javadoc.projects|$isdefined:}">
<true>
<callforeach i="project" list="${javadoc.projects}"
steps="mkjavadocs" mode="local"/>
</true>
<otherwise>
<callforeach i="project" infile="${javadoc.projects.listfile}"
steps="mkjavadocs" mode="local"/>
</otherwise>
</domatch>
<do true="${$var:batchmode}">
<ftp .../>
<delete .../>
</do>
<unassign var="batchmode"/>
</target>
[Back to top]| Task/Type | General Description |
| show | A ResourceBundle/MessageFormat version of <echo>. Messages can be templates with up to two dynamic arguments. |
| emit, checkpoint |
Tasks that broadcast information to all listening logging and/or reporting systems. A checkpoint is a specialized <emit> that is used to broadcast diagnostic "you-are-here" information. |
| emitconfiguration | A shareable data type that defines a set of feedback settings any another type or task can use to broadcast information. By default works with a Log4j-based logging system but easily extended for other logging systems. |
| emitlogs | A special taskset that copies messages logged to the standard Ant infrastructure by enclosed tasks to any listening build monitors. |
| emitmappings | A shareable data type that maps Ant log messages to specific log4j categories. Messages are selected based on their origin (like target name or task class), or by their contents (using regular expression matching). |
<msgsbundle resource="${resources}/defaultmsgs.properties"/> [declare messages]
…
<target name="init">
<checkpoint msgid="enter.init"/> [use messages]
<assert ruleid="required.build.properties"/>
<domatch property="dist.type">
<equals value="local">
<property name="defaults.isdebug" value="true"/>
<property name="defaults.isopt" value="false"/>
<property name="defaults.access" value="package"/>
</equals>
<equals value="public">
<property name="defaults.isdebug" value="false"/>
<property name="defaults.isopt" value="true"/>
<property name="defaults.access" value="protected"/>
<property name="is.public.build" value="true"/>
</equals>
<default>
<stop msgid="err.bad.disttype" msgarg1="${dist.type}"/> [use messages]
</default>
</domatch>
…
<checkpoint msgid="leave.init"/> [use messages]
</target>
2) The following test build file excerpt copies all Ant messages logged by tasks within the testABC target to any log4j-based monitors. The included event mapping (log4j.labels) tells the <emitlogs> task how to automatically place the various messages into custom log4j categories.
<emitconfiguration id="emit.defaults"
noiselevel="info"
from="Testing.Regression"
wrt="shortdate"/>
<emitmappings id="log4j.labels">
<mapping type="project" like=".*" label="AntX"/>
<mapping type="target" name="testABC" label="AABBCC"/>
<mapping type="message" like="^Setting project property.*" label="SPLUNK.properties"/>
<mapping type="message" like="^(Adding reference){1}.*" label="SPLUNK.references"/>
</emitmappings>
<target name="testABC">
<step name="saydoink">
<echo level="info" message="doink"/>
</step>
<emitlogs with="emit.defaults" labels="log4j.labels"> [cc all logs to log4j too]
<property name="a.p" value="1st-try"/>
<echo message="HHHHHIIIII"/>
<property name="a.p" value="2nd-try"/>
<call steps="saydoink"/>
</emitlogs>
</target>
[Back to top]| Task/Type | General Description |
| printenv, |
Tasks to display specified project properties, variables, and references. Also helpful for debugging your <rules> and <tallyset> declarations. Arbitrary data types can be displayed using the AntX <printer> type definition. |
| tempdir, newtempdir |
Tasks that locate a suitable temporary directory in which scratch files and directories can be safely created. The new directory is based on the platform-specific temporary directory (for example, $TMPDIR on Unix systems). |
| newfile, newtempfile |
Tasks that creates (temporary) files in a specified directory. Temporary files are automatically marked for deletion on normal termination of the Ant runtime. These tasks can also initialize the new file's contents from a source prototype file or resource. Usually used with the two tempdir tasks. |
| printerror | Task that displays the contents of an ErrorSnapshot. An ErrorSnapshot is an AntX data type used to capture failure information within a build process (specifically by the AntX <protect> taskset). |
| listdir | Task that generates a directory listing and saves it into a local project string list. You can then use the list like you would an statically defined string list. |
| evaluatelogged | Task that evaluates a set of captured log information for some script-supplied acceptance criteria. Usually used to determine if a task such as <javadoc> has issued non-fatal warnings that should be captured. |
| vendorinfo | Task to stamp the build information of a JWare-based Ant product to a set of local properties. Useful to transfer version information for display or evaluation. |
<vendorinfo name="antx" prefix="ax." fields="date,longversion"/>
<show msgid="info.antx.build" msgarg1="${ax.longversion}" msgarg2="${ax.date}"/>
2) The following snippet copies a series of files from a source directory SRC to a target directory DST while applying a predefined filterset.
<step name="copynextfile">
<copy todir="${DST}" file="${file}" filtering="yes">
<filterset refid="..."/>
</copy>
</step>
<listdir path="${SRC}" torefid="files" onlyfiles="yes"/>
<callforeach i="file" items="files" mode="local" steps="copynextfile"/>
<unassign reference="files"/>
3) The following snippet defines a diagnostic macro grab-universe that captures bits of fixture information like properties and variables and saves it to several files.
<tempdir subdirectory="${user.name}/.antdump" pathproperty="tmp.root"/>
…
<macrodef name="grab-universe">
<attribute name="todir" default="${tmp.root}"/>
<attribute name="onlyproperties" default="no"/>
<sequential>
<echo message="Dumping Ant universe to: @{todir}"/>
<assert isdirectory="@{todir}" msg="'@{todir}' is a directory"/>
<newfile path="@{todir}/all.properties">
<propertyset>
<propertyref builtin="all"/>
</propertyset>
</newfile>
<newfile path="@{todir}/system.properties">
<propertyset>
<propertyref builtin="system"/>
</propertyset>
</newfile>
<newfile path="@{todir}/args.properties">
<propertyset>
<propertyref builtin="commandline"/>
</propertyset>
</newfile>
<do false="@{onlyproperties}">
<print references="all"
tofile="@{todir}/references.list"/>
<print variables="all"
tofile="@{todir}/variables.list"/>
</do>
</sequential>
</macrodef>