mirror of
https://github.com/apache/ant.git
synced 2025-05-17 21:45:12 +00:00
git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269839 13f79535-47bb-0310-9956-ffa450edef68
367 lines
14 KiB
HTML
367 lines
14 KiB
HTML
<html><head>
|
|
<title>
|
|
Apache Ant Task Design Guidelines
|
|
</title>
|
|
</head><body>
|
|
|
|
<h1>Apache Ant Task Design Guidelines</h1>
|
|
|
|
This document covers how to write ant tasks to a standard required to be
|
|
incorporated into the Ant distribution. You may find it useful when
|
|
writing tasks for personal use as the issues it addresses are still
|
|
there in such a case.
|
|
|
|
|
|
<h2>Use built in helper classes</h2>
|
|
|
|
Ant includes helper tasks to simplify mauch of your work. Be warned that
|
|
these helper classes will look very different in ant2.0 from these 1.x
|
|
versions. However it is still better to use them than roll your own, for
|
|
development, maintenance and code size reasons.
|
|
|
|
<h4>Execute</h4>
|
|
|
|
Execute will spawn off separate programs under all the platforms which
|
|
ant supports, dealing with Java version issues as well as platform
|
|
issues. Always use this task to invoke other programs.
|
|
|
|
<h4>Java, ExecuteJava</h4>
|
|
|
|
These classes can be used to spawn Java programs in a separate VM (they
|
|
use execute) or in the same VM -with or without a different classloader.
|
|
When deriving tasks from this, it often benefits users to permit the
|
|
classpath to be specified, and for forking to be an optional attribute.
|
|
|
|
|
|
<h4>Project</h4>
|
|
|
|
Project has some helper functions to touch a file, to
|
|
copy a file and the like. Use these instead of trying to code them
|
|
yourself -or trying to use tasks which may be less stable and fiddlier
|
|
to use.
|
|
|
|
|
|
<h2>Obey the Sun/Java style guidelines</h2>
|
|
|
|
The Ant codebase aims to have a single unified coding standard, and that
|
|
standard is the
|
|
<a href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">
|
|
Sun Java coding guidelines
|
|
</a>
|
|
<p>
|
|
|
|
It's not that they are better than any alternatives, but they are a
|
|
standard and they are what is consistently used in the rest of the
|
|
tasks. Code will not be incorporated into the database until it complies
|
|
with these.
|
|
|
|
<p>
|
|
|
|
If you are writing a task for your personal or organisational use, you
|
|
are free to use whatever style you like. But using the Sun Java style
|
|
will help you to become comfortable with the rest of the Ant source,
|
|
which may be important.
|
|
|
|
<p>
|
|
|
|
One important rule is 'no tabs'. Use four spaces instead. Not two,
|
|
not eight, four. Even if your editor is configured to have a tab of four
|
|
spaces, lots of others aren't -spaces have more consistency across
|
|
editors and platforms.
|
|
|
|
<h2>Recommended Names for attributes and elements</h2>
|
|
|
|
The ant1.x tasks are very inconsistent regarding naming of attributes
|
|
-some tasks use source, others src. Here is a list of preferred attribute
|
|
names.
|
|
|
|
<table>
|
|
<tr>
|
|
<td>
|
|
failonerror
|
|
</td>
|
|
<td>
|
|
boolean to control whether failure to execute should throw a
|
|
<tt>BuildException</tt> or just print an error.
|
|
Parameter validation failures should always throw an error, regardless
|
|
of this flag
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
destdir
|
|
</td>
|
|
<td>
|
|
destination directory for output
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
Yes, this is a very short list. Try and be vaguely consistent with the core
|
|
tasks, at the very least.
|
|
|
|
<h2>Design for controlled re-use</h2>
|
|
|
|
Keep member variables private. If read access by subclasses is required.
|
|
add accessor methods rather than change the accessiblity of the member.
|
|
This enables subclasses to access the contents, yet
|
|
still be decoupled from the actual implementation.
|
|
<p>
|
|
|
|
The other common re-use mechanism in ant is for one task to create and
|
|
configure another. This is fairly simple.
|
|
|
|
<h2>Do your own Dependency Checking</h2>
|
|
|
|
Make has the edge over Ant in its integrated dependency checking: the
|
|
command line apps make invokes dont need to do their own work. Ant tasks
|
|
do have to do their own dependency work, but if this can be done then
|
|
it can be done well. A good dependency aware task can work out the dependencies
|
|
without explicit dependency information in the build file, and be smart
|
|
enough to work out the real dependencies, perhaps through a bit of file parsing.
|
|
The <tt>depends</tt> task is the best example of this. Some of the zip/jar
|
|
tasks are pretty good too, as they can update the archive when needed.
|
|
Most tasks just compare source and destination timestamps and work from there.
|
|
Tasks which don't do any dependency checking do not help users as much as
|
|
they can, because their needless work can trickle through the entire build, test
|
|
and deploy process.
|
|
|
|
<h2>Support Java 1.1 through Java 1.4</h2>
|
|
|
|
Ant is designed to support Java1.1: to build on it, to run on it. Sometimes
|
|
functionality of tasks have to degrade in that environment -<touch>
|
|
is a case in point- this is usually due to library limitations;
|
|
such behaviour change must always be noted in the documentation.
|
|
<p>
|
|
What is problematic is code which is dependent on Java1.2 features
|
|
-Collections, Reader and Writer classes, extra methods in older classes.
|
|
These can not be used directly by any code and still be able to compile
|
|
and run on a Java 1.1 system. So please stick to the older collection
|
|
classes, and the older IO classes. If a new method in an existing class
|
|
is to be used, it must be used via reflection and the
|
|
<tt>NoSuchMethodException</tt> handled somehow.
|
|
<p>
|
|
What if code simply does not work on Java1.1? It can happen. It will
|
|
probably be OK to have the task as an optional task, with compilation
|
|
restricted to Java1.2 or later through build.xml modifications.
|
|
Better still, use reflection to link to the classes at run time.
|
|
<p>
|
|
Java 1.4 adds a new optional change to the language itself, the
|
|
<tt>assert</tt> keyword, which is only enabled if the compiler is told
|
|
to compile 1.4 version source. Clearly with the 1.1 compatibility requirement,
|
|
Ant tasks can not use this keyword. They also need to move away from
|
|
using the JUnit <tt>assert()</tt> method and start calling <tt>assertTrue()</tt>
|
|
instead.
|
|
|
|
|
|
|
|
<h2>Refactor</h2>
|
|
|
|
If the changes made to a task are making it too unwieldy, split it up
|
|
into a cleaner design, refactor the code and submit not just feature
|
|
creep but cleaner tasks. A common design pattern which tends to occur in
|
|
the ant process is the adoption of the adapter pattern, in which a base
|
|
class (say Javac or Rmi) starts off simple, then gets convoluted with
|
|
support for multiple back ends -javac, jikes, jvc. A refactoring to
|
|
split the programmable front end from the classes which provide the back
|
|
end cleans up the design and makes it much easier to add new back ends.
|
|
But to carry this off one needs to keep the interface and behaviour of
|
|
the front end identical, and to be sure that no subclasses have been
|
|
accessing data members directly -because these data members may not
|
|
exist in the refactored design. Which is why having private data members
|
|
is so important.
|
|
|
|
|
|
<h2>Test</h2>
|
|
|
|
Look in <tt>jakarta-ant/src/testcases</tt> and you will find JUnit tests for the
|
|
shipping ant tasks, to see how it is done and what is expected of a new
|
|
task. Most of them are rudimentary, and no doubt you could do better for
|
|
your task -feel free to do so!
|
|
|
|
<p>
|
|
|
|
A well written set of test cases will break the Ant task while it is in
|
|
development, until the code is actually complete. And every bug which
|
|
surfaces later should have a test case added to demonstrate the problem,
|
|
and to fix it.
|
|
|
|
<p>
|
|
|
|
The test cases are a great way of testing your task during development.
|
|
A simple call to 'ant run-test' in the ant source tree will run all ant
|
|
tests, to verify that your changes don't break anything.
|
|
To test a single task, use the one shot <code>ant run-single-test
|
|
-Dtestcase=${testname}</code> where ${testname} is the name of your test class.
|
|
|
|
|
|
<p>
|
|
|
|
The test cases are also used by the committers to verify that changes
|
|
and patches do what they say. If you've got test cases it increases your
|
|
credibility significantly.
|
|
|
|
<p>
|
|
|
|
Remember also that Ant 1.x is designed to compile and run on Java1.1, so
|
|
you should test on Java 1.1 as well as any later version which you use.
|
|
You can download an old SDK from Sun for this purpose.
|
|
|
|
<h2>Document</h2>
|
|
|
|
Without documentation, the task can't be used. So remember to provide a
|
|
succint and clear html (soon, xml) page describing the task in a similar
|
|
style to that of existing tasks. It should include a list of attributes
|
|
and elements, and at least one working example of the task. Many users
|
|
cut and paste the examples into their build files as a starting point,
|
|
so make the examples practical and test them too.
|
|
|
|
<h2>Licensing and Copyright</h2>
|
|
|
|
Any code submitted to the Apache project must be compatible with the
|
|
Apache Software License, and the act of submission must be viewed as an
|
|
implicit transfer of ownership of the submitted code to the Apache
|
|
Software Foundation.
|
|
|
|
<p>
|
|
This is important.
|
|
|
|
<p>
|
|
|
|
The fairly laissez-faire license of Apache is not compabitible with
|
|
either the GPL or the Lesser GPL of the Free Software Foundation -the
|
|
Gnu project. Their license requires all changes to the source to be made
|
|
public, and give the licensee of any software the right to distribute
|
|
copies. It also requires derivative works to be made available under the
|
|
same license terms. None of these requirements are in the Apache Software
|
|
Foundation license, which permits people and organisations to build
|
|
commercial and closed source applications atop the Apache libraries and
|
|
source -but not use the Apache, Ant or Jakarta Project names without
|
|
permission.
|
|
|
|
<p>
|
|
|
|
Because the Gnu GPL license immediately extends to cover any larger
|
|
application (or library, in the case of GLPL) into which it is
|
|
incorporated, the Ant team can not incorporate any task based upon GPL
|
|
or LGPL source into the Ant codebase. You are free to submit it, but it
|
|
will be politely and firmly rejected.
|
|
|
|
<p>
|
|
|
|
Once ant-2 adds better dynamic task incorporation, it may be possible to
|
|
provide a framework for supporting [L]GPL code, but still no tasks
|
|
direcely subject to the Gnu licenses will ever be included in the Ant
|
|
CVS tree.
|
|
|
|
<h3>Dont re-invent the wheel</h3>
|
|
|
|
We've all done it: written and submitted a task only to discover it
|
|
was already implemented in a small corner of another task, or it has
|
|
been submitted by someone else and not committed. You can avoid this
|
|
by being aware of what is in the latest CVS tree -keep getting the daily
|
|
source updates, look at manual changes and subscribe to the ant-dev
|
|
mailing list.
|
|
|
|
<p>
|
|
|
|
If you are thinking of writing a task, posting a note on your thoughts
|
|
to the list can be informative -you well get other peoples insight and
|
|
maybe some half written task to do the basics, all without writing a
|
|
line of code.
|
|
|
|
|
|
<h2>Submitting to Ant</h2>
|
|
|
|
The process for submitting an Ant task is documented on the
|
|
<a href="http://jakarta.apache.org/site/guidelines.html">
|
|
jakarta web site</a>.
|
|
The basic mechanism is to mail it to the ant-dev mailing list.
|
|
It helps to be on this list, as you will see other submissions, and
|
|
any debate about your own submission.
|
|
<p>
|
|
|
|
Patches to existing files should be generated with
|
|
<code>cvs diff -u filename</code>
|
|
and save the output to a file. If you want to get
|
|
the changes made to multiple files in a directory , just use <code>cvs
|
|
diff -u</code>. The patches should be sent as an attachment to a message titled [PATCH]
|
|
and distinctive one-line summary in the subject of the patch. The
|
|
filename/task and the change usually suffices. It's important to include
|
|
the changes as an attachment, as too many mailers reformat the text
|
|
pasted in, which breaks the patch.
|
|
<p>
|
|
Then you wait for one of the committers to commit the patch, if it is
|
|
felt appropriate to do so. Bug fixes go in quickly, other changes
|
|
often spark a bit of discussion before a (perhaps revised) commit is
|
|
made.
|
|
<p>
|
|
|
|
New submissions should be proceeded with [SUBMIT]. The mailer-daemon
|
|
will reject any messages over 100KB, so any large update should be
|
|
zipped up. If your submission is bigger than that, why not break it up
|
|
into separate tasks.
|
|
<p>
|
|
|
|
If you hear nothing after a couple of weeks, remind the mailing list.
|
|
Sometimes really good submissions get lost in the noise of other issues.
|
|
This is particularly the case just prior to a new point release of
|
|
the product. At that time anything other than bug fixes will tend
|
|
to be neglected.
|
|
|
|
<h2>Checklists</h2>
|
|
|
|
These are the things you should verify before submitting patches and new
|
|
tasks. Things don't have to be perfect, it may take a couple of
|
|
iterations before a patch or submission is committed, and these items
|
|
can be addressed in the process. But by the time the code is committed,
|
|
everything including the documentation and some test cases will have
|
|
been done, so by getting them out the way up front can save time.
|
|
The committers look more favourably on patches and submissions with test
|
|
cases, while documentation helps sell the reason for a task.
|
|
|
|
<h3>Checklist before submitting a patch</h3>
|
|
<ul>
|
|
<li>Added code complies with style guidelines
|
|
<li>Code compiles and runs on Java1.1
|
|
<li>New member variables are private, and provide public accessor methods
|
|
if access is actually needed.
|
|
<li>Existing test cases succeed.
|
|
<li>New test cases written and succeed.
|
|
<li>Documentation page extended as appropriate.
|
|
<li>Example task declarations in the documentation tested.
|
|
<li>Diff files generated using cvs diff -u
|
|
<li>Message to ant-dev contains [PATCH], task name and patch reason in
|
|
subject.
|
|
<li>Message body contains a rationale for the patch.
|
|
<li>Message attachment contains the patch file(s).
|
|
</ul>
|
|
|
|
<h3>Checklist before submitting a new task</h3>
|
|
<ul>
|
|
<li>Java file begins with Apache copyright and license statement.
|
|
<li>Task does not depend on GPL or LGPL code.
|
|
<li>Source code complies with style guidelines
|
|
<li>Code compiles and runs on Java1.1
|
|
<li>Member variables are private, and provide public accessor methods
|
|
if access is actually needed.
|
|
<li><i>Maybe</i> Task has failonerror attribute to control failure behaviour
|
|
<li>New test cases written and succeed
|
|
<li>Documentation page written
|
|
<li>Example task declarations in the documentation tested.
|
|
<li>Patch files generated using cvs diff -u
|
|
<li>patch files include a patch to defaults.properties to register the
|
|
tasks
|
|
<li>patch files include a patch to coretasklist.html or
|
|
optionaltasklist.html to link to the new task page
|
|
<li>Message to ant-dev contains [SUBMIT] and task name in subject
|
|
<li>Message body contains a rationale for the task
|
|
<li>Message attachments contain the required files -source, documentation,
|
|
test and patches
|
|
</ul>
|
|
<hr>
|
|
<p align="center">Copyright © 2001 Apache Software Foundation. All rights
|
|
Reserved.</p>
|
|
|
|
</body></html>
|
|
|