Rev 5710 | Blame | Compare with Previous | Last modification | View Log | RSS feed
######################################################################### COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.## Module name : cc2svn_cctest_path.pl# Module type : Makefile system# Compiler(s) : Perl# Environment(s): jats## Description : A script to test the existence of a CC label and Path# Designed to be used as a part of the SVN conversion##......................................................................#require 5.008_002;use strict;use warnings;use JatsError;use JatsSystem;use FileUtils;use JatsBuildFiles;use ArrayHashUtils;use Pod::Usage; # required for help supportuse Getopt::Long;use Cwd;my $VERSION = "1.6.0"; # Update this## Options#my $opt_debug = $ENV{'GBE_DEBUG'}; # Allow global debugmy $opt_verbose = $ENV{'GBE_VERBOSE'}; # Allow global verbosemy $opt_help = 0; # User help levelmy $opt_viewname; # View Namemy $opt_path; # Path for view specmy $opt_prefix = 1; # Prefix the view tag with user-namemy $opt_tag; # View tag insert (build or export or user)my $opt_spec;my $opt_vob;## Globals - Provided by the JATS environment#my $USER = $ENV{'USER'};my $UNIX = $ENV{'GBE_UNIX'};my $GBE_ABT = $ENV{'GBE_ABT'} || '0';my $MACHINENAME = $ENV{'GBE_HOSTNAME'};my $GBE_VIEWBASE = $ENV{'GBE_VIEWBASE'}; # Root of the view## Globals#my $VIEWDIR_ROOT; # Root of the static viewmy $VIEWTAG; # The view tagmy $VIEWDIR; # Absolute path to the viewmy $VIEWPATH; # Path relative to clearcasemy $user_cwd;my $error = 0;my $label_count = 0; # Number of labels to create the viewmy @label_not_locked; # List of unlocked labelsmy @label_locked; # List of labels I lockedmy @error_list; # ClearCmd detected errorsmy $UNIX_VOB_PREFIX = '/vobs';my $VOB_PREFIX = $UNIX ? $UNIX_VOB_PREFIX : '';my $UNIX_VIEW_PREFIX = '/view/'; # Don't know how to determine this valuemy $WIN32_VIEW_PREFIX = 'o:/'; # Don't know how to determine this valuemy $VIEW_PREFIX = $UNIX ? $UNIX_VIEW_PREFIX : $WIN32_VIEW_PREFIX ;my $VOB_SEP = $UNIX ? '/' : '\\';my $view_prefix = "${USER}_";my $ROOT_VOB;my $root_vob_spec;#-------------------------------------------------------------------------------# Function : Mainline Entry Point## Description :## Inputs :### Parse the user options#my $result = GetOptions ("help+" => \$opt_help, # flag, multiple use allowed"manual:3" => \$opt_help, # flag"v|verbose:+" => \$opt_verbose, # flag, multiple use allowed"label=s" => \$opt_spec, # Array of build specs"view=s" => \$opt_viewname, # String"prefix!" => \$opt_prefix, # flag"tag=s" => \$opt_tag, # string);## UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!### Process help and manual options#pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);pod2usage(-verbose => 1) if ($opt_help == 2 );pod2usage(-verbose => 2) if ($opt_help > 2 );InitFileUtils();## Configure the error reporting process now that we have the user options#ErrorConfig( 'name' => 'CC_TESTPATH','verbose' => $opt_verbose );## Validate user options# Use either -label or one command line argument#Error ("Unexpected command line arguments present.","Cannot mix -label and command line label" )if ( $opt_spec && $#ARGV >= 0);$opt_spec = pop @ARGV unless ( $opt_spec );unless( $opt_spec ){Error ("Need a label. -help for options");}## Convert label with embedded VCS information into a 'normal' form.# Form:# CC::label# CC::path::label# CC::::label#if ( $opt_spec =~ m~^(.+?)::(.*?)(::(.+))?$~ ){Error ("Label contains invalid Version Control Identifier($1): $_")if ( $1 ne 'CC' );my $ll = $2;my $path;if ( $3 ){$path = $2;$ll = $4;if ( $path ){Error ("Multiple conflicting Embedded source paths","Path: $opt_path","VCS Spec: $_" ) if ( $opt_path && $path ne $opt_path );$opt_path = $path;}}$opt_spec = $ll;}Verbose ("Clean URL: $opt_spec");## Determine the machine type#Verbose ("Machine Type: UNIX=$UNIX");Error ("Machine Name not determined")unless ( $MACHINENAME );$user_cwd = getcwd;Error ("USER name not determined" )unless ( $USER );## Ensure that the 'cleartool' program can be located#Verbose ("Locate clearcase utility in users path");Error ("Cannot locate the 'cleartool' utility in the users PATH")unless ( LocateProgInPath('cleartool', '--All') );## Clean up the view root directory#$VIEWDIR_ROOT = Realpath($GBE_VIEWBASE) || $GBE_VIEWBASE;Verbose ("Viewpath: $VIEWDIR_ROOT");Error ("Cannot locate view root directory: $VIEWDIR_ROOT" ) unless (-d $VIEWDIR_ROOT);## Remove any user name from the front of the view name# Simplifies the deletion process as the user can provide# the directory name#$view_prefix = "" unless ( $opt_prefix );## Setup user specified viewname# Include the user name to ensure that the view name is unique-ish# Keep the name as short as possible as some compilers display a fixed# length filename in error messages and this name is part of the path## Base the viewname on the view label. This will simplify the creation# of multiple views and reduce the risk of unexpected deletion#$opt_viewname = $opt_spec unless ( defined $opt_viewname );$opt_viewname =~ s~^$view_prefix~~ if (defined($opt_viewname) && $view_prefix );## Create the view tag# Attempt to make this globally unique# Include USER name, MACHINE name, the view name# Optionally include a user 'tag'. Provided to allow the ABT to maintain# multiple instances of a view.#unless ( $opt_tag ){$opt_tag = 'dynamic';}$VIEWTAG = "${USER}_${MACHINENAME}_${opt_tag}_${opt_viewname}";## Create a clearcase view to be used for the view#$VIEWPATH = "$view_prefix$opt_viewname";$VIEWDIR = "$VIEWDIR_ROOT/$VIEWPATH";$VIEWDIR =~ tr~\\/~/~s;Verbose( "Hostname: $MACHINENAME" );Verbose( "Viewtag: $VIEWTAG" );Verbose( "Viewpath: $VIEWPATH" );Verbose( "Viewdir : $VIEWDIR" );## If the user has specified a "source path", then we can extract the VOB# from that path. It will be the first directory#Verbose("Locate Source VOB");Error ("Need a source path" ) unless ( $opt_path );#$opt_path = '/' . $opt_path;$opt_path =~ tr~\\/~/~s;$opt_path =~ s~/+$~~;Error( "Source Path needs leading '/': $opt_path, $opt_spec") unless ( $opt_path =~ m~^/~ );Error( "Source Path is a UNC" ) if ( $opt_path =~ m~^//~ );Error( "Source Path has drive specifier" ) if ( $opt_path =~ m~^[A-Za-z]\:~ );## Extract the VOB from the path#unless ( $opt_vob ){my $vob = $opt_path;$vob =~ s~^/~~g;$vob =~ s~/.*~~g;$opt_vob = $vob;Verbose ("Extract VOB from path: $vob" );}## Setup user specified VOB#$ROOT_VOB = "/$opt_vob";$ROOT_VOB =~ s~//~/~g;## Ensure that the label is present within the specified VOB# Hunt for the user specified label in a number of well known VOBs#if ( $opt_spec ){Verbose("Ensure Label is found in a VOB");my $found = 0;my $spec = $opt_spec;my $vob = $ROOT_VOB;$vob = $UNIX_VOB_PREFIX . $vob if ( $UNIX );(my $vob_name = $vob) =~ s~/~$VOB_SEP~g;Verbose2 ("Examine label $spec in vob: $vob" );my $cmd = ClearToolCmd ('lstype', "lbtype:$spec\@$vob_name");my $cmd_done = 0;open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");while (<CMD>){## Filter output from the user# Stay in loop to avoid Broken Pipe message#chomp;Verbose2("lstype: $_");next if ( $cmd_done );next if ( m~Error~ );next unless ( m~label type~ );push @label_not_locked, $spec unless( m~\(locked\)~ );$label_count++;$found = $vob;$cmd_done = 1;}close(CMD);Error ("Label $spec not found in $ROOT_VOB")unless ( $found );Verbose ("Label $spec found in vob: $found" );$ROOT_VOB = $found;## Create a VOB spec extension#$root_vob_spec = '@' . $ROOT_VOB;$root_vob_spec =~ s~/~$VOB_SEP~g;}## Extracting files then ...#extract_files_from_view();exit 0;#-------------------------------------------------------------------------------# Function : ClearCmd## Description : Execute a cleartool command# Capture error messages only## Inputs : Command to execute# Takes an array of command argumeents and will quote them## Returns : Exit code# Also the global @error_list#sub ClearCmd{@error_list = ();my $cmd = ClearToolCmd(@_);open(CMD, "$cmd 2>&1 |") || Error "can't run command: $!";while (<CMD>){chomp;Verbose ($_);push @error_list, $_ if ( m~Error:~ );}close(CMD);Verbose2 "Exit Status: $?";return $? / 256;}#-------------------------------------------------------------------------------# Function : ClearToolCmd## Description : Create a nice escaped cleartool command## Inputs : An array of cleartool command line arguments## Returns : A string that has been quoted#sub ClearToolCmd{my $cmd = 'cleartool ' . QuoteCommand( @_);Verbose2 $cmd;return $cmd;}#-------------------------------------------------------------------------------# Function : extract_files_from_view## Description : This function will# Create a dynamic view# Copy all the files out of the view# Delete the view## Its used in the creation of escrow directories## Inputs : None# All done via globals## Returns :#sub extract_files_from_view{my $vob_mounted = 1;my $vob_name;## Which config spec# Create config spec in local dir#my $configFile = "config_spec.$$.txt";my $config = create_config_spec( $configFile );## Create the view and insert the config spec#ClearCmd ( 'rmview', '-tag', $VIEWTAG );ClearCmd ( 'mkview', '-tag', $VIEWTAG, '-stgloc', '-auto' );ClearCmd ( 'setcs', '-tag', $VIEWTAG, $config );## Ensure that the base VOB has been 'mounted'# Dynamic views require vobs to be mounted#($vob_name = $ROOT_VOB) =~ s~/~$VOB_SEP~g;$vob_mounted = ClearCmd ('mount', $vob_name);## Calculate where the dynmaic view will be# This differ between UNIX/WINDOWS#my $vpath = $VIEW_PREFIX . $VIEWTAG . $VOB_PREFIX;my $cpath = $vpath;$cpath .= $opt_path if ( $opt_path );## Is the view where we expect it to be#Error ("Cannot locate dynamic view","Looking in: $vpath" ) unless -d $vpath;Verbose("Dynamic view path: $vpath" );Verbose ("Dynamic view tag : $VIEWTAG" );Message ("Dynamic view path: $cpath" );my $valid = -d ($cpath);ClearCmd ( 'rmview', '-tag', $VIEWTAG );unlink $configFile;Error ("View Path not found") unless ($valid);}#-------------------------------------------------------------------------------# Function : create_config_spec## Description : Creates a config spec## Inputs : $config - Path to the config file## Returns : Path to the config spec#sub create_config_spec{my ($config_file) = @_;## Calc the path to a directory in the view which we really want to# consider as the base. Only want to see folders above this base.# Don't want to add elements above the base#my $basepath = ($opt_path) ? "\"${VOB_PREFIX}${opt_path}\"" : $ROOT_VOB;my $elroot = ($opt_path) ? "\"${VOB_PREFIX}${opt_path}/...\"" : '*';my $elpath = ($opt_path) ? $opt_path : '';## Create a config spec to be used to populate the view# Do not branch directories# Do not extract files from lost+found#Verbose( "Create config spec");my @config;push @config, "element * CHECKEDOUT";push @config, "element .../lost+found -none";## Insert rules to prevent branching above the load path# This will be the root of the package#if ( $opt_path ){my $fulldir = $VOB_PREFIX;my @parts = split ('/', $opt_path);shift @parts; # Skip first as its emptypop @parts; # Skip last as its the packageforeach my $dir ( @parts ){$fulldir .= "/$dir";push @config, "element -dir \"$fulldir\" $opt_spec -nocheckout";}}else{push @config, "element -dir \"$ROOT_VOB\" $opt_spec -nocheckout";}## Rules to extract elements within the load path#push @config, "element $elroot $opt_spec";## Load rule# Quote the path so that spaces will be correcly handled#push @config, "load $basepath";Message ("Config Spec", @config )if ( IsVerbose(1) );FileCreate ($config_file, \@config);return $config_file;}#-------------------------------------------------------------------------------# Documentation#=pod=for htmltoc SYSUTIL::cc2svn::=head1 NAMEcc2svn_cctest_path - Test the existence of a ClearCase Path=head1 SYNOPSISjats cc2svn_cctest_path [options] [-label=]labelOptions:-help - brief help message-help -help - Detailed help message-man - Full documentation-label=xxx - Clearcase label-spec=xxx - Same as -label=xxx-path=xxx - Source Path-view=xxx - Modify the name of the created view-vob=vobname - VOB name-build=xxx - Package Name to build-root=xxx - Root directory for generated view-latestroot=xxx - Use the LATEST rootlevel directory 'xxx'-[mk]branch=xxx - Will create a view with a branch rule-config=xxx - Create a view with the provided config spec-tag=xxx - Alternate tag used with in the ViewTag-extract - Extract the view and exit-extractfiles - Extract files, without a view-cache - Refresh local dpkg_archive cache-delete - Remove any existing view and exit-debugOnly - Make only the debug version-prodOnly - Make only the production version-[no]dpkg - Transfer package into dpkg_archive-[no]copy - Transfer pkg directory to the current user directory-[no]reuse - Reuse the view-[no]test - Test package build. Implies nocopy and nodpkg-[no]keep - Keep the view after the build-[no]lock - Lock labels-[no]beta - Release a beta package-[no]merge - Merge packages into dpkg_archive-[no]runtests - Run units tests. Default is runtests-[no]prefix - Supress user prefix in view name. Default prefix is USER=head1 OPTIONS=over 8=item B<-help>Print a brief help message and exits.=item B<-help -help>Print a detailed help message with an explanation for each option.=item B<-man>Prints the manual page and exits.=item B<-label> or B<-spec>The ClearCase label to use as the base for the view.Eg: daf_utils_math_3.2.1=item B<-view name>Specified an alternate view name and tag to be used. This option does not provide thefull name of the view.The view tag will be : "${USER}_${MACHINENAME}_${TAG}_${NAME}"The view path will be: "${USER}_${NAME}"The default "NAME" is the first label specified.The default "TAG" is build. See B<-tag=tagname>.If the user provides a view "name" that is prefixed with their user name('${USER}_'), then the username will be stripped of for internal processing.This allows a user to provide a view path when deleting a view.=item B<-path=xxx>Specifies the source path to the root of the extracted file tree. This option has several uses:=over 8=item *Provide a sanity test of the "Source Path" item within Release Manager=item *Specify the VOB that contains the source. The VOB name will be extracted andused as the B<-vob> parameter.=item *Limit the work to do in extracting the file tree.=back=item B<-vob=xxx>Specifies the Clearcase VOB in which the clearcase label will be located.This is used as the basis for locating and loading the files within the view.By default this utility will examine all the VOBs for the label.=item B<-build=xxx>This option allows the user to specify the packages to be built and theorder in which the packages are to be built.This is useful if the extracted view contains multiple build filesThis option may be used multiple times.There are two forms in which the build target can be specified. It can bespecified as a full package name and vesrion, or as a package name and theproject suffix.By default the program will assume that there is only one build file in theview and will not build if multiple files are present, unless the package to bebuilt can be resolved.The location mechanism operates for both JATS and ANT build files.Example: -build=jats-api.1.0.0000.crThis will locate the build file that builds version 1.0.0000.cr of the jats-apipackage. The version numbers must match exactly.Example: -build=jats-api.cr -build=jats-lib.crThis will located the build files that build the jats_api (cr) package and thejats-lib (cr) package. The version of the packages will not be considered.=item B<-root=xxx>This option allows the location of the generated view to be specified on thecommand line. It overides the value of GBE_VIEWBASE.If the comamnd is invoked within a development sandbox, then the defaultlocation will be the root directory of the development sandbox.=item B<-latestroot=xxx>This option enables a work around for a bad-labelling practice that has existedin the past. This LATEST version of the named (xxx) branch will be added tothe config spec used to create the view.This is a work around for a problem where the top-level directory in the VOB hasnot been labelled. This can result in unreproducible builds.This option allows the utility to construct a view, but the user SHOULD labelthe root level directory to correct the problem.The use of this switch will add the following lines to the config spec:element -directory /DPG_SWBase /main/xxxx/LATEST=item B<-branch=xxx or -mkbranch=xxx>This option will create a view such that files that are checked out will bechecked out on the named branch. This is intended to facilitate the maintenanceof existing packages - the creation of a patch.The named branch must exist within the VOB containing the label. The script willcheck for its existence.The use of this switch will add the following lines to the config spec:element * .../xxx/LATESTelement * label -mkbranch xxxelement * /main/0 -mkbranch xxx=item B<-config=config_spec>This option is an alternate mechanism to create a static view. The view will bebased on the provided configuration spec. This view cannot be used to release a package.The option is intended to simplify development.This option is incompatibale with:-release-label-branch-path-vob=item B<-tag=text>This option alters the ClearCase view tag created for the view. It allowsthe creation of multiple views based on the same label. Intended to be used inthe automated build system to create unique views tags.The default tag is 'build'.=item B<-extract>With this option the view is created and the left in place. The user may thenaccess the files within the view. The view should not be used for aproduction release.=item B<-extractfiles>With this option the utility will create a dynamic view and transfer files fromthe view to the user's tararget. The dynamic view is then removed.This command is intended to simplify the process of creating an escrow.=item B<-cache>Forces external packages to be placed in the local dpkg_archive cache.The normal operation is to copy the packages, only if they do not already existin the local cache. This option may be used to ensure that the local copy iscorrect and up to date.=item B<-delete>Delete the view used by the program, if it exists. This option may be used tocleanup after an error.Note: Ensure that no files are open in the view and that the users currentworking directory is not in the view as these will prevent the view from beingdeleted.=item B<-debugOnly>Make only the debug version of the package. The default it to create both thedebug and production version of the package. The type of build may be furtherlimited by options within the package.=item B<-prodOnly>Make only the production version of the package. The default it to create both thedebug and production version of the package. The type of build may be furtherlimited by options within the package.=item B<-[no]dpkg>Copy the generated package into dpkg_archive. This is the default mode ofoperation.=item B<-[no]copy>Copy the built "pkg" directory to the users current directory. The entire"pkg" subdirectory includes the full package named directory for the packagethat has been built.=item B<-[no]reuse>This flag allows the view created by the program to be re-used.=over 8=item *The view is not deleted before being populated.=item *The view will not be populated if it does exist.=item *The view will not be deleted at the end the process.=backThis option is useful for debugging a build process.=item B<-[no]test>Test the building of the package. This option implies "nocopy" and "nodpkg".=item B<-[no]keep>Keep the clearcase view after the build. The default option is "nokeep"This option is different to the "reuse" in that the view will be deleted, ifit exists, before the build, but will be retained at the completion of theprocess. The user may then manually extract the created package.The view may be deleted with the the "delete" option; taking care to ensure thatno files are open in the view and that the users current working directory isnot in the view.=item B<-[no]lock>Lock any unlocked labels before attempting the build. This operation may be usedto ensure that a release build does not fail due to the labels not being locked.The label is locked before the view is constructed and populated.This operation may fail if the user does not "own" the label.=item B<-[no]beta>This option overrides many of the package release tests to allow a beta packageto be released.=item B<-[no]merge>This option will merge packages being built on multiple machines intodpkg_archive. By default, if a package already exists in the archive it will bedeleted and replaced. With this option the package will be merged. The mergeprocess does not over write files found in the archive.=item B<-[no]runtests>This option will allow the suppression of the running of the unit tests includedwith the component. By default the tests are run. This can be suppressedwithout affecting the release process.=back=head1 DESCRIPTIONThis program is the primary tool for the creation, recreation and release ofpackages within the B<VIX> build environment, although the program can perform anumber of very useful operations required during normal development andmaintenance.This program will build a system containing one or more inter-related buildfiles using the JATS build tools.In normal operation the program will:=over 8=item Remove ViewRemove any existing view of the same name. The view will not be removed if itcontains checked-out files.The view removal may fail if there are any files B<open> within the view or ifany shell has a subdirectory of the view set as a B<current working directory>.=item Locate VOBLocate the VOB that contains the specified label or labels. If multiple labelsare specified they must all exist in the same VOB.=item Lock LabelsLock any unlocked labels, if required.=item Create the viewCreate a static view to containing the files describes by the Clearcaselabel being processed.The program uses a fixed view name. If this view exists then itemwill be deleted before item is created again. Each build starts in a clean view.=item Populate the ViewLoads files into the static view. The user label and the VOB name are used tocreated a clearcase configuration specification. This configurationspecification is then activated and all files within the specified VOB will beloaded into the view if they match the user supplied label.This processed normally results in a lot of error messages that can be ignored.I<Note:> The label placed on the component to be built must extend to theroot of the VOB, otherwise the directory path will not be extracted nor willthe files within the component.I<Note:> If the view is simply being extracted, then this is the end of theprogram. The extracted view is left in place.=item Sanity TestIf the build is being used as a release into dpkg_archive thenvarious tests are performed to ensure the repeatability of the view and thebuild. These tests include:=over 8=item *The view must be constructed from one label=item *That label must be locked=item *The labelled view must contain exactly one build file=item *The view cannot have been re-used.=back=item Locate build filesLocate the build file within the view.It is an error to have multiple build files within the view, unless theB<-build> option is used. By default, only one package will be built.=item Package the resultsUse JATS to build and make the package.The resultant package may be copied to a numbers of locations. These include=over 8=item 1The master dpkg_archive as an official release. This is the default operation.=item 2The users current directory. The package directory from the built package iscopied locally. The "pkg" directory is copied. This is only performed with theB<-copy> option.=back=item Delete the viewDelete the view and all related files.The view will not be deleted if an error was detected in the build process, orthe "reuse" or "keep" options are present.=back=cut