source: release-kits/lirk3/resources/gs3-release-maker/apache-ant-1.6.5/docs/ant_task_guidelines.html@ 14982

Last change on this file since 14982 was 14982, checked in by oranfry, 16 years ago

initial import of LiRK3

File size: 18.1 KB
Line 
1<html><head>
2<title>
3Apache Ant Task Design Guidelines
4</title>
5</head><body>
6
7<h1>Apache Ant Task Design Guidelines</h1>
8
9This document covers how to write ant tasks to a standard required to be
10incorporated into the Ant distribution. You may find it useful when
11writing tasks for personal use as the issues it addresses are still
12there in such a case.
13
14
15<h2>Don't break existing builds</h2>
16
17Even if you find some really hideous problem with ant, one that is easy
18to fix, if your fix breaks an existing build file then we have problems.
19Making sure that every build file out there still works, is one of the
20goals of all changes. As an example of this, Ant1.5 passes the single
21dollar sign "$" through in strings; Ant1.4 and before would strip it. To
22get this fix in we first had to write the test suite to expose current
23behaviour, then change something so that singe $ was passed through, but
24double "$$" got mapped to "$" for backwards compatibility.
25
26
27<h2>Use built in helper classes</h2>
28
29Ant includes helper tasks to simplify much of your work. Be warned that
30these helper classes will look very different in ant2.0 from these 1.x
31versions. However it is still better to use them than roll your own, for
32development, maintenance and code size reasons.
33
34<h4>Execute</h4>
35
36Execute will spawn off separate programs under all the platforms which
37ant supports, dealing with Java version issues as well as platform
38issues. Always use this task to invoke other programs.
39
40<h4>Java, ExecuteJava</h4>
41
42These classes can be used to spawn Java programs in a separate VM (they
43use execute) or in the same VM -with or without a different classloader.
44When deriving tasks from this, it often benefits users to permit the
45classpath to be specified, and for forking to be an optional attribute.
46
47
48<h4>Project and related classes</h4>
49
50Project, FileUtils, JavaEnvUtils all have helper functions
51to do things like touch a file, to
52copy a file and the like. Use these instead of trying to code them
53yourself -or trying to use tasks which may be less stable and fiddlier
54to use.
55
56
57<h2>Obey the Sun/Java style guidelines</h2>
58
59The Ant codebase aims to have a single unified coding standard, and that
60standard is the
61<a href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">
62Sun Java coding guidelines
63</a>
64<p>
65
66It's not that they are better than any alternatives, but they are a
67standard and they are what is consistently used in the rest of the
68tasks. Code will not be incorporated into the database until it complies
69with these.
70
71<p>
72
73If you are writing a task for your personal or organisational use, you
74are free to use whatever style you like. But using the Sun Java style
75will help you to become comfortable with the rest of the Ant source,
76which may be important.
77
78<p>
79
80One important rule is 'no tabs'. Use four spaces instead. Not two,
81not eight, four. Even if your editor is configured to have a tab of four
82spaces, lots of others aren't -spaces have more consistency across
83editors and platforms. Some IDEs (JEdit) can highlight tabs, to stop you
84accidentally inserting them
85<p>
86There is an ant build file check.xml in the main ant directory with runs
87 <a href="http://checkstyle.sourceforge.net">checkstyle</a> over
88 ant's source code.
89
90<h2>Attributes and elements</h2>
91Use the Ant introspection based mapping of attributes into Java datatypes,
92rather than implementing all your attributes as setFoo(String) and doing
93the mapping to Int, bool or file yourself. This saves work on your part,
94lets Java callers use you in a typesafe manner, and will let the Xdocs
95documentation generator work out what the parameters are.
96
97<p>
98The ant1.x tasks are very inconsistent regarding naming of attributes
99-some tasks use <tt>source</tt>, others <tt>src</tt>.
100Here is a list of preferred attribute names.
101
102<table>
103<tr>
104<td>
105 failonerror
106</td>
107<td>
108 boolean to control whether failure to execute should throw a
109 <tt>BuildException</tt> or just print an error.
110 Parameter validation failures should always throw an error, regardless
111 of this flag
112</td>
113</tr>
114<tr>
115<td>
116 destdir
117</td>
118<td>
119 destination directory for output
120</td>
121</tr>
122<td>
123 destfile
124</td>
125<td>
126 destination file for output
127</td>
128</tr>
129<tr>
130<td>
131 srcdir
132</td>
133<td>
134 source directory
135</td>
136</tr>
137<tr>
138<td>
139 srcfile
140</td>
141<td>
142 source file
143</td>
144</tr>
145</table>
146Yes, this is a very short list. Try and be vaguely consistent with the core
147tasks, at the very least.
148
149<h2>Support classpaths</h2>
150
151Try and make it possible for people to supply a classpath to your task,
152if you need external libraries, rather than make them add everything to
153the ANT_HOME\lib directory. This lets people keep the external libraries
154in their ant-based project, rather than force all users to make changes
155to their ant system configuration.
156
157<h2>Design for controlled re-use</h2>
158
159Keep member variables private. If read access by subclasses is required.
160add accessor methods rather than change the accessiblity of the member.
161This enables subclasses to access the contents, yet
162still be decoupled from the actual implementation.
163<p>
164
165The other common re-use mechanism in ant is for one task to create and
166configure another. This is fairly simple.
167
168<h2>Do your own Dependency Checking</h2>
169
170Make has the edge over Ant in its integrated dependency checking: the
171command line apps make invokes dont need to do their own work. Ant tasks
172do have to do their own dependency work, but if this can be done then
173it can be done well. A good dependency aware task can work out the dependencies
174without explicit dependency information in the build file, and be smart
175enough to work out the real dependencies, perhaps through a bit of file parsing.
176The <tt>depends</tt> task is the best example of this. Some of the zip/jar
177tasks are pretty good too, as they can update the archive when needed.
178Most tasks just compare source and destination timestamps and work from there.
179Tasks which don't do any dependency checking do not help users as much as
180they can, because their needless work can trickle through the entire build, test
181and deploy process.
182
183<h2>Support Java 1.2 through Java 1.4</h2>
184
185Ant1.5 and lower was designed to support Java1.1. Ant1.6 and higher
186is designed to support Java1.2: to build on it, to run on it. Sometimes
187functionality of tasks have to degrade in that environment
188- this is usually due to library limitations;
189such behaviour change must always be noted in the documentation.
190<p>
191What is problematic is code which is dependent on Java1.3 features
192-java.lang.reflect.Proxy, or Java1.4 features - java.io.nio for example.
193Be also aware of extra
194methods in older classes - like StringBuffer#append(StringBuffer).
195These can not be used directly by any code and still be able to compile
196and run on a Java 1.2 system.
197If a new method in an existing class
198is to be used, it must be used via reflection and the
199<tt>NoSuchMethodException</tt> handled somehow.
200<p>
201What if code simply does not work on Java1.2? It can happen. It will
202probably be OK to have the task as an optional task, with compilation
203restricted to Java1.3 or later through build.xml modifications.
204Better still, use reflection to link to the classes at run time.
205<p>
206Java 1.4 adds a new optional change to the language itself, the
207<tt>assert</tt> keyword, which is only enabled if the compiler is told
208to compile 1.4 version source. Clearly with the 1.2 compatibility requirement,
209Ant tasks can not use this keyword. They also need to move away from
210using the JUnit <tt>assert()</tt> method and call <tt>assertTrue()</tt>
211instead.
212<p>
213Java 1.5 will (perhaps) add a new keyword - enum, one should avoid
214this for future compatibility.
215
216
217<h2>Refactor</h2>
218
219If the changes made to a task are making it too unwieldy, split it up
220into a cleaner design, refactor the code and submit not just feature
221creep but cleaner tasks. A common design pattern which tends to occur in
222the ant process is the adoption of the adapter pattern, in which a base
223class (say Javac or Rmi) starts off simple, then gets convoluted with
224support for multiple back ends -javac, jikes, jvc. A refactoring to
225split the programmable front end from the classes which provide the back
226end cleans up the design and makes it much easier to add new back ends.
227But to carry this off one needs to keep the interface and behaviour of
228the front end identical, and to be sure that no subclasses have been
229accessing data members directly -because these data members may not
230exist in the refactored design. Which is why having private data members
231is so important.
232
233
234<h2>Test</h2>
235
236Look in <tt>ant/src/testcases</tt> and you will find JUnit tests for the
237shipping ant tasks, to see how it is done and what is expected of a new
238task. Most of them are rudimentary, and no doubt you could do better for
239your task -feel free to do so!
240
241<p>
242
243A well written set of test cases will break the Ant task while it is in
244development, until the code is actually complete. And every bug which
245surfaces later should have a test case added to demonstrate the problem,
246and to fix it.
247
248<p>
249
250The test cases are a great way of testing your task during development.
251A simple call to 'build run-test' in the ant source tree will run all ant
252tests, to verify that your changes don't break anything.
253To test a single task, use the one shot <code>ant run-single-test
254-Dtestcase=${testname}</code> where <code>${testname}</code> is the name of your test class.
255
256
257<p>
258
259The test cases are also used by the committers to verify that changes
260and patches do what they say. If you've got test cases it increases your
261credibility significantly. To be precise, we hate submissions without
262test cases, as it means we have to write them ourselves. This is
263something that only gets done if we need the task or it is perceived as
264utterly essential to many users.
265
266<p>
267
268Remember also that Ant 1.x is designed to compile and run on Java1.2, so
269you should test on Java 1.2 as well as any later version which you use.
270You can download an old SDK from Sun for this purpose.
271<p>
272Finally, run a full <code>build test</code> before and after you start
273developing your project, to make sure you havent broken anything else by
274accident.
275
276<h2>Document</h2>
277
278Without documentation, the task can't be used. So remember to provide a
279succint and clear html (soon, xml) page describing the task in a similar
280style to that of existing tasks. It should include a list of attributes
281and elements, and at least one working example of the task. Many users
282cut and paste the examples into their build files as a starting point,
283so make the examples practical and test them too.
284<p>
285You can use the xdocs stuff in proposal/xdocs to autogenerate your
286documentation page from the javadocs of the source; this makes life
287easier and will make the transition to a full xdoclet generated
288documentation build process trivial.
289
290<h2>Licensing and Copyright</h2>
291
292Any code submitted to the Apache project must be compatible with the
293Apache Software License, and the act of submission must be viewed as an
294implicit transfer of ownership of the submitted code to the Apache
295Software Foundation.
296
297<p>
298This is important.
299
300<p>
301
302The fairly laissez-faire license of Apache is not compabitible with
303either the GPL or the Lesser GPL of the Free Software Foundation -the
304Gnu project. These licenses have stricter terms, "copyleft", which are
305not in the Apache Software Foundation license.
306This permits people and organisations to build
307commercial and closed source applications atop the Apache libraries and
308source -but not use the Apache, Ant or Jakarta Project names without
309permission.
310
311<p>
312
313Because the Gnu GPL license immediately extends to cover any larger
314application (or library, in the case of GLPL) into which it is
315incorporated, the Ant team can not incorporate any task based upon GPL
316or LGPL source into the Ant codebase. You are free to submit it, but it
317will be politely and firmly rejected.
318
319<p>
320
321Once ant-2 adds better dynamic task incorporation, it may be possible to
322provide a framework for indirectly supporting [L]GPL code, but still no tasks
323directly subject to the Gnu licenses can be included in the Ant
324CVS tree.
325
326<p>
327If you link to a GPL or LGPL library, by <code>import</code> or
328reflection, your task must be licensed under the same terms. So tasks
329linking to (L)GPL code can't go into the Apache managed codebase.
330Tasks calling such code can use the 'exec' or 'java' tasks to run the
331programs, as you are just executing them at this point, not linking to
332them.
333<p>
334Even if we cannot include your task into the Apache codebase, we can
335still point to where you host it -just submit a diff to
336xdocs/external.html pointing to your task.
337
338If your task links directly to proprietary code, we have a differnt
339problem: it is really hard to build the tasks. Please use reflection.
340
341<h3>Dont re-invent the wheel</h3>
342
343We've all done it: written and submitted a task only to discover it
344was already implemented in a small corner of another task, or it has
345been submitted by someone else and not committed. You can avoid this
346by being aware of what is in the latest CVS tree -keep getting the daily
347source updates, look at manual changes and subscribe to the dev
348mailing list.
349
350<p>
351
352If you are thinking of writing a task, posting a note on your thoughts
353to the list can be informative -you well get other peoples insight and
354maybe some half written task to do the basics, all without writing a
355line of code.
356
357
358<h2>Submitting to Ant</h2>
359
360The process for submitting an Ant task is documented on the
361<a href="http://jakarta.apache.org/site/guidelines.html">
362jakarta web site</a>.
363The basic mechanism is to mail it to the dev mailing list.
364It helps to be on this list, as you will see other submissions, and
365any debate about your own submission.
366<p>
367You may create your patch file using either of the following approaches.
368The committers recommend you to take the first approach.
369<p>
370<ul>
371<li> <h3>Approach 1 - The Ant Way</h3>
372<p>
373Use Ant to generate a patch file to Ant:
374<pre class="code">
375ant -f patch.xml
376</pre>
377This will create a file named patch.tar.gz that will contain a unified
378diff of files that have been modified and also include files that have
379been added. Review the file for completeness and correctness. This approach
380is recommended because it standardizes the way in which patch files are
381constructed. It also eliminates the chance of you missing to submit new files
382that constitute part of the patch.
383<p>
384<li><h3>Approach 2 - The Manual Way</h3>
385<p>
386Patches to existing files should be generated with
387<code>cvs diff -u filename</code>
388 and save the output to a file. If you want to get
389the changes made to multiple files in a directory , just use <code>cvs
390diff -u</code>. Then, Tar and GZip the patch file as well as any new files
391that you have added.
392</ul>
393<p>
394The patches should be sent as an attachment to a message titled [PATCH]
395and distinctive one-line summary in the subject of the patch. The
396filename/task and the change usually suffices. It's important to include
397the changes as an attachment, as too many mailers reformat the text
398pasted in, which breaks the patch.
399<p>
400Then you wait for one of the committers to commit the patch, if it is
401felt appropriate to do so. Bug fixes go in quickly, other changes
402often spark a bit of discussion before a (perhaps revised) commit is
403made.
404<p>
405
406New submissions should be proceeded with [SUBMIT]. The mailer-daemon
407will reject any messages over 100KB, so any large update should be
408zipped up. If your submission is bigger than that, why not break it up
409into separate tasks.
410<p>
411
412We also like submissions to be added to
413<a href="http://issues.apache.org/bugzilla/">bugzilla</a>, so that they
414dont get lost. Please submit them by first filing the report with a
415meaningful name, then adding files as attachments. Use CVS diff files
416please!
417<p>
418
419If you hear nothing after a couple of weeks, remind the mailing list.
420Sometimes really good submissions get lost in the noise of other issues.
421This is particularly the case just prior to a new point release of
422the product. At that time anything other than bug fixes will tend
423to be neglected.
424
425<h2>Checklists</h2>
426
427These are the things you should verify before submitting patches and new
428tasks. Things don't have to be perfect, it may take a couple of
429iterations before a patch or submission is committed, and these items
430can be addressed in the process. But by the time the code is committed,
431everything including the documentation and some test cases will have
432been done, so by getting them out the way up front can save time.
433The committers look more favourably on patches and submissions with test
434cases, while documentation helps sell the reason for a task.
435
436<h3>Checklist before submitting a patch</h3>
437<ul>
438<li>Added code complies with style guidelines
439<li>Code compiles and runs on Java1.2
440<li>New member variables are private, and provide public accessor methods
441 if access is actually needed.
442<li>Existing test cases succeed.
443<li>New test cases written and succeed.
444<li>Documentation page extended as appropriate.
445<li>Example task declarations in the documentation tested.
446<li>Diff files generated using cvs diff -u
447<li>Message to dev contains [PATCH], task name and patch reason in
448subject.
449<li>Message body contains a rationale for the patch.
450<li>Message attachment contains the patch file(s).
451</ul>
452
453<h3>Checklist before submitting a new task</h3>
454<ul>
455<li>Java file begins with Apache copyright and license statement.
456<li>Task does not depend on GPL or LGPL code.
457<li>Source code complies with style guidelines
458<li>Code compiles and runs on Java1.2
459<li>Member variables are private, and provide public accessor methods
460 if access is actually needed.
461<li><i>Maybe</i> Task has failonerror attribute to control failure behaviour
462<li>New test cases written and succeed
463<li>Documentation page written
464<li>Example task declarations in the documentation tested.
465<li>Patch files generated using cvs diff -u
466<li>patch files include a patch to defaults.properties to register the
467tasks
468<li>patch files include a patch to coretasklist.html or
469optionaltasklist.html to link to the new task page
470<li>Message to dev contains [SUBMIT] and task name in subject
471<li>Message body contains a rationale for the task
472<li>Message attachments contain the required files -source, documentation,
473test and patches zipped up to escape the HTML filter.
474</ul>
475<hr>
476<p align="center">Copyright &copy; 2001-2003,2005 Apache Software Foundation. All rights
477Reserved.</p>
478
479</body></html>
480
Note: See TracBrowser for help on using the repository browser.