HomeStreek ResourcesClient AppsDeveloper ResourcesTalksHowTo Docs
 

Source Code Management

Source Code Management

Version Control Systems

A version control system is critical to managing source code, whether development is occuring in a single- or multiple-developer environment. Version control systems track all changes made to a set of files (allowing for easy, accurate rollback to a clean copy of a codebase when necessary). They provide a failsafe backup mechanism without the overhead of manually-coordinated backups. For groups of developers, a central version control system provides a clean, straightforward mechanism for coordinating each individual's changes to the shared codebase.

CVS: Open-Source Version Control

While anyone with a few hundred thousand dollars to burn is free to purchase a commercial CVS system, an excellent and widely used open-source version control system is free for the downloading: CVS, at http://www.cvshome.org, can be run from servers running a wide variety of operating systems; clients are also available for many operating systems and IDEs.

The Streek project utilizes a CVS repository on canvas.berkeley.edu, a machine maintained by IS&T-CCS.

Change Management Standards

Project Version Numbering

Each project should maintain a three-part version number of the form major-minor-rev (e.g. 1.0.2).

major

This number should increment when a significant number of features are added or when an important technological change has been introduced. Examples:

  1. a web application has been modified to use the servlet filter mechanism introduced in Servlet specification 2.3.
  2. an enterprise application has been modified to use container-managed persistence rather than bean-managed persistence.
minor

This number should increment when a single new feature or enhancement has been added. Examples:

  1. an application has added a calendaring component (new feature).
  2. an application containing rosters has introduced digital photos of the roster members (enhancement).
rev

This number should increment when a refactoring has taken place or when a bug fix is installed. Examples:

  1. an application with several similar data access objects has been simplified so that they all use a common superclass (refactoring).
  2. eliminated out-of-memory error caused by ... (bug fix).

Project Build Number and Timestamp

Each project should maintain a sequential build number that is incremented and timestamped each time the project has a deployment candidate build. Example:

A project contains a build target named "compile" and a build target named "jar". Invoking ant compile would not increment the build number, while ant jar would.

version.properties

Each project should contain a properties file named $project-version.properties where $project is the working or code name of the project. Example:

LMS enterprise integration project name is Strawberry Creek and code name is "streek" so the version properties files would be streek-version.properties.

The properties file should be placed on the classpath of a web application (i.e. $docroot/WEB-INF/classes) or simply included in the jar archive of a support package. A support package should provide a utility class that reports its version information, a web-application should provide a url that does the same.

Deployment Files

Candidate deployment files should be named $project-$deploy-$version.$archive-type. Examples:

Support Package
eberk-test-1-0-0_0080.jar
Web App
rsf-signup-prod-1-0-1_0099.war
Enterprise App
courseweb-qa-1.0.0_0081.ear

Samples

Ant Targets and Properties for Maintaining Version Information
Version Target

The target shown below uses the ant propertyfile task to maintain build number and timestamp:

              
              <target name="version"  depends="compile"
                  description="Maintain build-number and build-date properties.">
                <propertyfile file="${version.props}"
                  comment="streek build number and date">
                <entry key="build-number" type="int" operation="+" pattern="0000" />
                <entry key="build-date" type="date" value="now" />
                </propertyfile>
              </target>
              
              

Executing this target will create or modify the properties file defined by ${version.props}.

                # streek build number and date
                # Wed Mar 13 10:16:50 PST 2002
                build-date=2002/03/13 10\:16
                major=1
                minor=0
                rev=0
                description=Initial release
                build-number=0090
              
Jar Version Target

The target shown builds the current version string:

              
              <target name="jar-version"
                description="Builds version-build-number component of of archive file names.">
                  <property file="${version.props}" />
                  <property name="version.build"
                    value="${major}-${minor}-${rev}_${build-number}"  />
              </target>
              
              
EAR-test Target

The target shown builds the project's enterprise archive file for development deployment:

              
              <target name="ear-test" depends="components,war-test,jar-version">
                  description="Builds current ear file for dev.">
                  <!-- other tasks omitted -->
                  <property name="ear.file" value="${code.name}-test-${version.build}.ear" />
                  <jar jarfile="${ear.file}" basedir="${build.ear.dir}" />
                </target>
              
              
Java Version Reporter
              
              package edu.berkeley.ist.ebf.util;
              import java.util.Properties;
              import java.io.IOException;
              import java.io.StringWriter;
              import java.io.PrintWriter;
              import java.io.InputStream;
              
              /**
               * Version.java
               * Emit project version information.
               *
               * Created: Tue Mar  5 12:44:47 2002
               *
               * @author <a href="mailto:randy@socrates.berkeley.edu">Randy Ballew</a>
               * @version $Revision: 1.3 $ $Date: 2004/11/19 22:44:20 $ $Author: stevem $ 
               */
              
              public class Version {
                  static Properties props;
                  private static final String PROP_FILE  = "/ebf-version.properties";
                  
                  /**
                   * Returns <code>String</code> representation of package version information.
                   */
                  public static String getVersion() {
              	if (props == null) 
              	    loadProps();
              	StringWriter out = new StringWriter();
              	props.list(new PrintWriter(out));
              	return "e-berkeley java framework: " + out.toString();
                  }
                  // load props as resource on classpath
                  private static void loadProps() {
              	InputStream is;
                      props = new Properties();
              	Class clazz = edu.berkeley.ist.ebf.util.Version.class;
                      is = clazz.getResourceAsStream(PROP_FILE);
                      if (is == null) {
                          throw new RuntimeException("Couldn't find: " + PROP_FILE
                                       + " on CLASSPATH");
                      }
                      try {
                          props.load(is);
                          is.close();
                      }catch (IOException ioe) {
                          ioe.printStackTrace();
                      }
                  }
                  // never instantiate this class
                  private Version (){	
                  }
                  /**
                   * command-line query
                   */
                  public static void main(String[] argv) {
                  	System.out.println(getVersion());
                  }
              }// Version