Dashboard > CruiseControl > DynamicClearcaseConfigSpec
DynamicClearcaseConfigSpec Log In View a printable version of the current page.

Added by Roy Wright , last edited by Roy Wright on Aug 11, 2004  (view change)
Labels: 
(None)

This is a method for using CruiseControl with a dynamically generated config.spec that time qualifies a dyanamic clearcase view.

  1. Using Clearcase Labels
  2. Create a config.spec Template
  3. Install Perl
  4. Install the Perl Script
  5. Config.xml Target
  6. Sample Project

Using Clearcase Labels

We use "add to build" (ADD-TO-project) and "steady state" (project-SS) labels to choose which files are included in the build instead of relying on LATEST. This permits us to add files to the VOB incrementally during development, then label them when ready. As such, our config.spec uses several "element * LABEL" selectors. To prevent having files change in our dynamic view during a build, we create a config.spec that uses the "-time" qualifier for all the elements.

Create a config.spec Template

First save a copy of your config.spec to WORK_DIR as config.spec.template. This will be used by the following perl script that adds the time qualifier using CruiseControl's cctimestamp property. For example:

config.spec.template
element * ADD-TO-SPITFIRE
element * SPITFIRE-SS

will be changed to:

config.spec
element * ADD-TO-SPITFIRE -time 10-Aug-2004.16:30:00
element * SPITFIRE-SS -time 10-Aug-2004.16:30:00

Install Perl

First you will need to install the latest version of ActivePerl. I recommend letting the install set up the file association

Install the Perl Script

Now here's the perl script that should be saved in your WORK_DIR:

genConfigSpec.pl
#!/usr/bin/perl -w
use strict;
use Getopt::Long;
use POSIX qw(strftime);

my %config;
 
read_cmdline_args();          # read in any cmd line args
process( %config );           # process the config.spec
exit 0;                       # terminate execution

##############################################################
# help message
sub help {
    print <<END_HELP;
genConfigSpec.pl - Generate a dynamic config.spec for a clearcase view.
usage:
  genConfigSpec.pl {--time yyyymmddhhmmss --template filename --output filename}|{--help}
  where:
    --time yyyymmddhhmmss   The date and time to qualify all the elements
                            in the config.spec template with.
    --template filename     A config.spec to use as a template
    --output filename       The file to write the generate ouput to.
    --help                  Display this message.

END_HELP

    exit 0;
}

##############################################################
# Read the command line args and update the %config hash
sub read_cmdline_args {
    $config{'debug-level'} = 1;

    GetOptions( \%config, 'time=i', 'template=s', 'output=s', 'help' );
    
    my $invalid = 0;
    $invalid++, logError("Missing \"--time yyyymmddhhmmss\" parameter")
        unless exists $config{'time'};
    $invalid++, logError("Missing \"--template filename\" parameter")
        unless exists $config{'template'};
    $invalid++, logError("Missing \"--output filename\" parameter")
        unless exists $config{'output'};
        
    help() if exists $config{'help'} || $invalid;
    
    return %config;
}

##############################################################
# process
sub process
{
    my(%config) = @_;
    my $time = formatTime($config{'time'});
    logDebug("config.spec time qualified to $time");
    
    open(IN, "<$config{'template'}") or
        die "Unable to open template file: $config{'template'}: $!\n";
    open(OUT, ">$config{'output'}") or
        die "Unable to open output file: $config{'output'}: $!\n";

    while(<IN>) {
        s/^(\s*element.*)$/$1 -time $time/;
        print OUT;
    }
    
    close OUT;
    close IN;
}

##############################################################
# formatTime(yyyymmddhhmmss)
sub formatTime {
    my $inTime = shift;
    unless( $inTime =~ /^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/ ) {
        logError("Invalid time string: $inTime");
        help();
    }
    return strftime("%d-%b-%Y.%H:%M:%S", $6, $5, $4, $3, ($2-1), ($1-1900));
}


##############################################################
# debug print statement
sub logDebug {
    my $str = shift;
    if($config{'debug-level'} > 0) {
        print "$str\n";
    }
}

##############################################################
# debug print statement
sub logError {
    my $str = shift;
    print "$str\n";
}

Config.xml Target

Here's the checkout target for the delegating Ant build.xml that dynamically generates and sets the config.spec:

config.xml snippet
<property name="view.root" value="z:\"/>
	<property name="view.tag" value="my_view"/>
	<property name="project.root" value="z:\project"/>
	<property name="clearcase.log.dir" value="${basedir}\logs\clearcase"/>
	<property name="clearcase.log" value="${basedir}\logs\clearcase\log.log"/>
	<property name="config.spec.dir" value="${basedir}"/>
	<property name="config.spec.filename" value="${config.spec.dir}\config.spec"/>
	<property name="config.spec.template" value="${config.spec.dir}\config.spec.template"/>
	<property name="perl" value="perl"/>
	<property name="genConfigSpec.script" value="genConfigSpec.pl"/>

	<target name="checkout" description="Update package from ClearCase">
		<echo message="Cleaning ${clearcase.log.dir}"/>
		<delete dir="${clearcase.log.dir}"/>
		<mkdir dir="${clearcase.log.dir}"/>
		<delete file="${config.spec.filename}"/>
		<echo message="Generate ${config.spec.filename}"/>
		<exec dir="${config.spec.dir}" executable="${perl}" failonerror="true">
			<arg line="${genConfigSpec.script} -time ${cctimestamp} -template ${config.spec.template}
                                -output ${config.spec.filename}"/>
		</exec>
		<echo message="Set ${config.spec.filename}"/>
		<exec dir="Z:\" executable="C:\Program Files\ClearCase\bin\cleartool.exe" failonerror="true">
			<arg line="setcs -tag ${view.tag} ${config.spec.filename}"/>
		</exec>
		<echo message="config.spec set for view"/>
	</target>

Sample Project

Now let's put it together in a sample project where:

  • dynamic view tag = spitfire_view
  • view share = Z:\
  • project = Z:\spitfire
  • java Ant build script = Z:\spitfire\java\build.xml
  • working directory = D:\build\cruisecontrol
  • CruiseControl config file = D:\build\cruisecontrol\config.xml
  • delegating Ant build script = D:\build\cruisecontrol\build-spitfire.xml
  • config.spec template file = D:\build\cruisecontrol\config.spec.template
  • dynamic config.spec generating script = D:\build\cruisecontrol\genConfigSpec.pl
config.xml
<crusecontrol>
	<project name="jspitfire" buildafterfailed="true">
		<bootstrappers>
			<currentbuildstatusbootstrapper file="d:\build\cruisecontrol\logs\spitfire\buildstatus.txt"/>
		</bootstrappers>
		<modificationset requiremodification="true" quietperiod="600">
			<clearcase branch="spitfire-dev" viewpath="Z:\spitfire" recursive="true"/>
		</modificationset>
		<schedule interval="3600">
			<ant antscript="D:\java\apache-ant-1.6.2\bin\ant.bat"
                                uselogger="true"
                                usedebug="false"
                                buildfile="d:\build\cruisecontrol\build-spitfire.xml"
                                target="masterbuild"/>
		</schedule>
		<log dir="d:\build\cruisecontrol\logs\spitfire">
			<merge dir="Z:\spitfire\java\reports\tests"/>
			<merge dir="Z:\spitfire\java\reports\metrics"/>
		</log>
		<publishers>
			<currentbuildstatuspublisher file="d:\build\cruisecontrol\logs\spitfire\buildstatus.txt"/>
			<artifactspublisher dir="Z:\spitfire\java\reports" dest="d:\build\cruisecontrol\artifacts\spitfire"/>
			<htmlemail mailhost="smtp.your.domain" 
                                         returnaddress="dev-team@your.domain"
                                         buildresultsurl="http://build.machine:8080/cruisecontrol/buildresults/spitfire" 
                                         skipusers="true" 
                                         spamwhilebroken="true" 
                                         subjectprefix="Build:" 
                                         logdir="D:\build\cruisecontrol\logs\spitfire"
                                         xsldir="D:\java\cruisecontrol-2.1.6\reporting\jsp\xsl"
                                         css="D:\java\cruisecontrol-2.1.6\reporting\jsp\css\cruisecontrol.css">
				<always address="admin@your.domain"/>
			</htmlemail>
		</publishers>
		<labelincrementer defaultLabel="spitfire.1"/>
	</project>
</crusecontrol>
  • and the delegating ant build script:
    build-spitfire.xml
    <project name="cruisecontrol driver for spitfire" default="masterbuild" basedir="d:\build\cruisecontrol">
    	<property name="view.root" value="z:\"/>
    	<property name="project.root" value="z:\spitfire\java"/>
    	<property name="clearcase.log.dir" value="${basedir}\logs\clearcase"/>
    	<property name="clearcase.log" value="${basedir}\logs\clearcase\log.log"/>
    	<property name="config.spec.dir" value="${basedir}"/>
    	<property name="config.spec.filename" value="${config.spec.dir}\config.spec"/>
    	<property name="config.spec.template" value="${config.spec.dir}\config.spec.template"/>
    	<property name="perl" value="perl"/>
    	<property name="genConfigSpec.script" value="genConfigSpec.pl"/>
    
    	<target name="masterbuild" depends="checkout,build,label">
    		<echo message="build-spitfire Target: masterbuild"/>
    	</target>
    
    	<target name="checkout" description="Update package from ClearCase">
    		<echo message="Cleaning ${clearcase.log.dir}"/>
    		<delete dir="${clearcase.log.dir}"/>
    		<mkdir dir="${clearcase.log.dir}"/>
    		<delete file="${config.spec.filename}"/>
    		<echo message="Generate ${config.spec.filename}"/>
    		<exec dir="${config.spec.dir}" executable="${perl}" failonerror="true">
    			<arg line="${genConfigSpec.script} -time ${cctimestamp} -template ${config.spec.template} 
                                              -output ${config.spec.filename}"/>
    		</exec>
    		<echo message="Set ${config.spec.filename}"/>
    		<exec dir="Z:\" executable="C:\Program Files\ClearCase\bin\cleartool.exe" failonerror="true">
    			<arg line="setcs -tag aus_spitfire_view d:\build\cruisecontrol\config.spec"/>
    		</exec>
    		<echo message="config.spec set for view"/>
    	</target>
    
    	<target name="build">
    		<echo message="build project: ${project.root}\.build.xml  Target: cleanbuild"/>
    		<ant dir="${project.root}" antfile="${project.root}\build.xml" target="cleanbuild"/>
    	</target>
    
    	<target name="label" description="Adds label to current snapshot">
    		<echo message="set label to @quot;${label}@quot;"/>
    		<fail unless="label" message="@quot;label@quot; property is not set"/>
    		<exec dir="${view.root}" executable="cleartool" failonerror="true">
    			<arg line="mklbtype -c @quot;Autobuild label@quot; ${label}"/>
    		</exec>
    		<exec dir="${view.root}" executable="cleartool" failonerror="true">
    			<arg line="mklabel -recurse ${label} ."/>
    		</exec>
    	</target>
    </project>
Powered by a free Atlassian Confluence Open Source Project / Non-profit License granted to ThoughtWorks, Inc.. Evaluate Confluence today.
Powered by Atlassian Confluence 2.7.1, the Enterprise Wiki. Bug/feature request - Atlassian news - Contact administrators