Ant Coding Style Guidelines

Contents

  1. Introduction
  2. File Names
  3. Build File Structure and Formatting
  4. Projects
  5. Properties
  6. Targets
  7. Tasks
  8. Comments
  9. Example Build File


1. Introduction

Why Have Code Conventions

Code conventions are important to software developers for a number of reasons:

These same reasons apply to build engineers maintaining Ant build files.

Keep in mind that these are guidelines, not hard and fast rules. The ultimate goal is readability and maintainability.

These guidelines have been compiled from the Ant user guide, Sun's Java coding style guidelines, example build files from various Jakarta applications, and e-mail messages on the Ant mailing lists.

Top


2. File Names

The default Ant build file is named "build.xml". Any build system beyond the most basic will have multiple build files for various modules of the application. Having them all named "build.xml" quickly leads to confusion of which does what.

Build file names should indicate the main purpose of the file, and should be in the Java style of mixed upper and lower case letters, with the first letter always capitalized. Words should be spelled out rather than abbreviated, unless the abbreviation is the more common reference. Using the main target name might work well.

Examples:

Build files may load properties from a properties file. These property files should be named the same as the build file name, but with a ".properties" extension.

Examples:

Top


3. Build File Structure and Formatting

Structure

Ant build files will be arranged with the project description first, followed by "global" properties, followed by targets. Properties and targets do not need to be sorted, however, the default target specified by the project must be the first target listed.

Formatting

Four spaces should be used as the unit of indentation.

Do not use tabs instead, use 4 spaces in place of a single tab. Many editors can do this automatically.

Vertically align start and end tags for an element. Indent child elements.

Avoid lines longer than 80 characters, since they're not handled well by many terminals and tools.

Use a single space after a comma.

Group properties by use, for example, group directory definitions together. Insert a single blank line between groups.

Insert two blank lines between targets.

Insert one blank line between tasks within a target.

When an expression will not fit on a single line, break it according to these general principles:

Examples:
    <property name="modules"
        value="libs, junit_tests, images, docs, api_docs, external_libs,
              sources" />
        
    <copy todir="${unit_test_deploy}" overwrite="true">
        <fileset dir="${unit_test_home}">
            <exclude name="**/CVS" />
        </fileset>
    </copy>

This is wrong:

  <target name="test_all" depends="clean,setupApp,
                                    setupTests,setupLogger,
                    startReportServlet,runTests"/>

This is right:

                    
    <target name="test_all" 
        depends="clean, setupApp, setupTests, setupLogger, 
                startReportServlet, runTests"/>

Top


4. Projects

To be acceptable to Ant, each build file must have a "project" element as its root element.

A project has three attributes. This standard deviates slightly from the Ant standard in that the "name" attribute is required and will be the same as the file name without the ".xml" extension.

Attribute Description Required
name the name of the project. This attribute should be the same as the file name without the .xml extension. Yes
default the default target to use when no target is supplied. Yes
basedir the base directory from which all path calculations are done. This attribute might be overridden by setting the "basedir" property beforehand. When this is done, it must be omitted in the project tag. If neither the attribute nor the property have been set, the parent directory of the buildfile will be used. No

Ant allows that a description for the project can be provided as a top-level <description> element. This description will be included in the output of the ant -projecthelp command. While this is optional for Ant, the description element is required by this standard.

Example description:

  
<description>
This build file is used to build the Foo subproject within 
the large and complex Bar project.
</description>

Top


5. Properties

Property names should be short yet meaningful. The choice of a property name should be mnemonic -- that is, designed to indicate to the casual observer the intent of its use. One-character property names should be avoided. Property names will be all lowercase with underscore separating individual words.

Examples:

<property name="build_dir" value="build"/>
<property name="jar_dir" value="${build_dir}/jars"/>
<property name="lib_home" value="lib"/>

Properties may be defined in a properties file. These property files should be named the same as the build file name, but with a ".properties" extension.

Properties may be "grouped" using the "dot" notation. For example, suppose the documentation for a project is divided into several manuals: the user manual, the installation manual, a technical support manual, and a examples manual, with the source for each manual residing in a separate directory. Then properties might look like this:

<property name="docs_dir" value="docs"/>
<property name="docs.user_manual" value="${docs_dir}/user_manual"/>  
<property name="docs.install_manual" value="${docs_dir}/installation"/>  
<property name="docs.tech_manual" value="${docs_dir}/techman"/>  
<property name="docs.examples_manual" value="${docs_dir}/examples"/>

Top


6. Targets

Like property names, target names should be short and meaningful. A target name should descript the overall intent of the target function. Target names should start with a verb, in mixed case with the first letter lowercase and with the first letter of each internal word capitalized.

Examples:

All targets that are likely to be called directly, that is, from the Ant command line, should have the description attribute filled in. This description will be included in the output of the ant -projecthelp command.

Targets that should not be called directly from the command line should start with a hyphen, for example,

-cleanDocDir.

Top


7. Tasks

Avoid use of the "exec" task if possible as this reduces portability.

This is bad as it assumes that the 'tar' utility is installed on the current path:

    <exec executable="tar" dir="${java.tmp.dir}/libraries">
        <arg line="-xzf ${build_dir}/${libraries_tar}"/>
    </exec>
This is good:
    <untar src="${build_dir}/${libraries_tar}" compression="gzip"
        dest="${java.tmp.dir}/libraries"/>

Top


8. Comments

More is better! In particular, write comments for the intended use of properties and targets. The build file itself will tell what is happening, the comments should explain why.

For target comments, use a block comment similar to this example:

<!-- ==================== Dist Target ================================ 

    The "dist" target creates a binary distribution of the application
    in a directory structure ready to be archived in a tar.gz or zip file.
    This target depends on two others:

    * "compile" so that the entire web application (including external
      dependencies) will have been assembled

    * "javadoc" so that the application Javadocs will have been created

-->
Place target comments immediately above the target element, with a single blank line between the end of the comment and the start of the target.

For other comments, such as for properties or within a target, use the standard xml single line comment like this:

<!-- this is a comment -->

If a comment is longer than a single line, wrap it and indent the second and subsequent lines 4 spaces, for example:

<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file,
    then copy it and the source jar to the ${dist} directory so 
    everything will be ready for moving to the ftp server. -->

Do not put a blank line between a single line comment and the element it is describing, for example:

    <!-- this is where the api documents live -->
    <property name="api_docs" value="${docs_home}/api"/>
Top


9. Example Build File

The following example build file follows these guidelines. This build file would be stored on disk as "MyProject.xml".


<project name="MyProject" default="dist" basedir=".">
    <description>
        simple example build file
    </description>
    
    <!-- set global properties for this build -->
    
    <!-- where the source files are -->
    <property name="src" location="src"/>
    
    <!-- where the compiled classes go -->
    <property name="build" location="build"/>
    
    <!-- where to place the finished jar file -->
    <property name="dist"  location="dist"/>

    <!-- ========== Dist Target ===================================
        The dist target compiles all the source code and creates
        a jar file for distribution.
    -->
    <target name="dist" depends="clean, compile"
        description="generate the distribution" >
        <!-- Create the distribution directory -->
        <mkdir dir="${dist}/lib"/>

        <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar
            file -->
        <jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar"
            basedir="${build}"/>
    </target>

    <!-- ========== Init Target ====================================
        This target initializes the build by creating a time stamp
        for use in the jar file name and creating the directory
        to hold the compiled classes.
    -->
    <target name="-init">
        <!-- Create the time stamp -->
        <tstamp/>
      
        <!-- Create the build directory structure used by compile -->
        <mkdir dir="${build}"/>
    </target>

    <!-- ========== Compile Target =================================
        The compile target compiles all files in the source directory
        into the build directory.
    -->
    <target name="compile" depends="-init" 
        description="compile the source " >
        
        <!-- Compile the java code from ${src} into ${build} -->
        <javac srcdir="${src}" destdir="${build}"/>
        
    </target>

    <!-- ========== Clean Target ====================================
        The clean target deletes all files from the build directory
        and the dist directory. 
    -->
    <target name="clean" description="clean up" >
        <!-- Delete the ${build} and ${dist} directory trees -->
        <delete dir="${build}"/>
        <delete dir="${dist}"/>
    </target>
</project>
Top