3.20 Bootstrapping a Build

3.20.1 Problem

You want to use Ant to kick off a nightly build process.

3.20.2 Solution

Create a "bootstrap" buildfile that checks out a clean copy of all sources from revision control. Then, pass off control to the main buildfile that was one of the files just checked out.

3.20.3 Discussion

Many projects set up a build server that performs complete, clean builds at scheduled times. A clean build ensures that every file in the system compiles. If you do not start with a clean slate, you may end up with a successful build just because some obsolete source or class files are lingering in your directory structure.

A clean build consists of the following high-level steps:

  1. Start the build with a scheduling mechanism of some sort. This is generally platform-specific and is not covered here.

  2. Use a script to checkout all files into a clean directory. This is what we are covering in this recipe.

  3. Once all files are checked out, including the main project buildfile, invoke Ant on the main buildfile.

Example 3-10 shows the complete Ant buildfile for performing a bootstrap build. The buildfile uses the cvs task as shown in Recipe 3.19 to checkout or update the entire cookbook directory. Once the latest files are obtained, we invoke Ant on cookbook/build.xml to perform the clean build.

Example 3-10. Bootstrap buildfile
<?xml version="1.0"?>
<project name="Java XP Cookbook" default="build" basedir=".">

  <target name="prepare">
    <!-- convert the CVS repository directory into
         a fully-qualitied Windows directory -->
    <pathconvert targetos="windows" property="cvsrepository.path">
       <path>
         <pathelement location="repository"/>
       </path>
    </pathconvert>
    <!-- store the CVS root in a property -->
    <property name="cvsroot" value=":local:${cvsrepository.path}"/>

    <!-- determine if the files have been checked out -->
    <available file="cookbook" type="dir" property="already.checked.out"/>   
  </target>

  <target name="clean"
          description="Remove the entire cookbook directory.">
    <delete dir="cookbook"/>
  </target>

  <target name="cvscheckout" depends="prepare"
          unless="already.checked.out">
    <cvs cvsroot="${cvsroot}"
         package="cookbook"/>
  </target>

  <target name="cvsupdate" depends="prepare" if="already.checked.out">
    <cvs command="update -dP"
         cvsroot="${cvsroot}"
         dest="cookbook"/>
  </target>

  <target name="build" depends="cvscheckout,cvsupdate">
    <ant dir="cookbook" target="all" inheritAll="false"/>
  </target>
</project>

3.20.4 See Also

Windows users can use "Scheduled Tasks" under the Control Panel to schedule builds for certain times of day. The CruiseControl tool is designed to help with continuous integration, and is available at http://cruisecontrol.sourceforge.net.