Rev 2026 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#! /usr/bin/perl######################################################################### Copyright (c) VIX TECHNOLOGY (AUST) LTD## Module name : jats_cbuilder.pl# Module type : Makefile system# Compiler(s) : n/a# Environment(s):## Description : A script to determine differences between two versions of# a build.## Can, with a bit of work, create a BeyondCompare@ view of# the stuff###......................................................................#require 5.006_001;use strict;use warnings;use JatsError;use JatsSystem;use FileUtils;use Pod::Usage; # required for help supportuse Getopt::Long;use File::Path;use Cwd;use Sys::Hostname; # For hostnamemy $VERSION = "1.5.5"; # Update this## Options#my $opt_debug = $ENV{'GBE_DEBUG'}; # Allow global debugmy $opt_verbose = $ENV{'GBE_VERBOSE'}; # Allow global verbosemy $opt_help = 0;my $opt_manual = 0;my $opt_drive = 'o';my $opt_tag = 'dynamic';my $opt_outfile;## Globals - Provided by the JATS environment#my $USER = $ENV{'USER'};my $UNIX = $ENV{'GBE_UNIX'};my $TMP = $UNIX ? "/tmp" : $ENV{'TMP'};## Globals#my $MACHINENAME;my @error_list; # ClearCmd detected errorsmy $UNIX_VOB_PREFIX = '/vobs';my $VOB_SEP = $UNIX ? '/' : '\\';my $BC2 = 'c:/Program Files/Beyond Compare 2/BC2.exe';my @view_tags;my %files;#-------------------------------------------------------------------------------# Function : Mainline Entry Point## Description :## Inputs :### Parse the user options#my $result = GetOptions ("help+" => \$opt_help, # flag, multiple use allowed"manual" => \$opt_manual, # flag, multiple use allowed"verbose+" => \$opt_verbose, # flag, multiple use allowed"out=s" => \$opt_outfile, # 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 || $#ARGV < 0);pod2usage(-verbose => 1) if ($opt_help == 2 );pod2usage(-verbose => 2) if ($opt_manual || ($opt_help > 2));InitFileUtils();## Configure the error reporting process now that we have the user options#ErrorConfig( 'name' => 'CCVIEW','verbose' => $opt_verbose );## Only for windows#Error ("This program only works under WIndows")if ( $UNIX );#Error ("No output file specified")# unless ( $opt_outfile );## Validate user options# Use either -label or one command line argument#my $label1 = shift @ARGV;my $label2 = shift @ARGV;Error ("Need two labels on the command line")unless ( $label1 && $label2 );Error ("Too many command line arguments" )unless ( $#ARGV < 0 );## Determine the machine type#Verbose ("Machine Type: UNIX=$UNIX");$MACHINENAME = hostname;Error ("Machine Name not determined")unless ( $MACHINENAME );chomp( $MACHINENAME );Error ("USER name not determined" )unless ( $USER );Error ("TMP not found or not a directory")unless ( $TMP && -d $TMP );$TMP = "$TMP/$$";Error ("Beyond Compare not found","Looking in: $BC2" )unless ( -x $BC2 );## 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') );## Create dynamic views for the two views# Verify that the view are present#my $tag1 = create_dynamic_view( $label1 );my $tag2 = create_dynamic_view( $label2 );my $path1 = "$opt_drive:/$tag1";my $path2 = "$opt_drive:/$tag2";Error ("Cannot locate view directory: $path1" ) unless (-d $path1);Error ("Cannot locate view directory: $path2" ) unless (-d $path2);System ( $BC2, $path1, $path2 );exit 0;## Scan the two views and create a hash of the files int he view with a# tag of the view that they are in. The hash key is the file name+branch#my @files1 = files_from_from_view( $path1, 1 );my @files2 = files_from_from_view( $path2, 2 );#DebugDumpData ("Files", \%files );## Create a hash of files that are different# The hash key will be the file name# The tag will be the branch that the file is on#my %diffs;foreach my $file ( sort keys %files ){## These files are the same#next if ( $files{$file}{1} && $files{$file}{2} );my $tag = 1;$tag = 2 if $files{$file}{2};## Break path into file and version#my ($f,$b) = split ('@@', $file );$diffs{$f}{$tag} = $file;# print "$file\n";}## Process files that are common, but have changed#open (FO, ">", $opt_outfile) || Error ("Cannot open file: $opt_outfile");foreach my $file ( sort keys %diffs ){## Files are are common#if ( $diffs{$file}{1} && $diffs{$file}{2} ){ClearDiff("-serial_format $path1/$diffs{$file}{1} $path2/$diffs{$file}{2}");}elsif ($diffs{$file}{1} ){## File has been deleted#}else{## File has been added#}}close FO;#DebugDumpData ("Files", \%diffs);#System ( $BC2, $path1, $path2 );exit (0);#-------------------------------------------------------------------------------# Function : create_dynamic_view## Description : Create a dynamic view, based on a label## Inputs : $label - Base label## Returns :#sub create_dynamic_view{my ($label) = @_;my $config = "${TMP}.config_ccview.txt";## Create a config spec#Verbose ("Create tmp file: $config");open (CF, ">$config" ) || Error ("Cannot create temp config spec file");print CF "element * CHECKEDOUT\n";print CF "element .../lost+found -none\n";print CF "element * $label\n";close CF;my $tag = "${USER}_${MACHINENAME}_${opt_tag}_${label}";push @view_tags, $tag;ClearCmd ( "rmview -tag $tag" );ClearCmd ( "mkview -tag $tag -stgloc -auto" );ClearCmd ( "setcs -tag $tag $config" );unlink $config;return $tag;}#-------------------------------------------------------------------------------# Function : files_from_from_view## Description : Determine the list of files/versions in a given view## Inputs : $vpath - Path to the view# $tag - File tag## Returns : Nothing# Populates the %files array#sub files_from_from_view{my ($vpath, $tag) = @_;my @files;my $cutlen = length ($vpath );my @dir_list = glob ( "$vpath/*" );foreach my $dir ( @dir_list ){## Skip top-level files - there will not be any# Skip ClearCase directories that are place-holders#next unless ( -d $dir );next unless ( glob ("$dir/*") );print "Processing: $dir\n";my $cmd = "cleartool ls -rec -short $dir";Verbose ("ClearTool: $cmd");open(CMD, "$cmd 2>&1 |") || Error "can't run command: $!";while (<CMD>){s~[\r\n]+$~~;tr~\\/~/~s;print "$_\n" if $opt_verbose;## Strip the base path of the file name# They are in differnt VOBS#my $file = substr ($_, $cutlen );$files{$file}{$tag} = 1;}close(CMD);Verbose2 "ClearTool Exit Status: $?";}}#-------------------------------------------------------------------------------# Function : END## Description : This function will be called as the program exists# It will also be called under error conditions# Close down stuff we created## Inputs :## Returns :#sub END{Message ("Cleaning up views") if @view_tags;foreach my $tag ( @view_tags ){# Message ("NOT Cleaning up views");ClearCmd ( "rmview -tag $tag" );}}#-------------------------------------------------------------------------------# Function : ClearDiff## Description : Issue a cleartool command# Filter out many of the stupid messages## Inputs : Options and Command line# Options:# --Quiet - Supress all command output## Returns : Error code#sub ClearDiff{my $quiet;## Scan for initial options# --Quiet#if ( $_[0] eq '--Quiet' ){$quiet = 1;shift;}my $cmd = "cleardiff @_";Verbose ("ClearTool: $cmd");open(CMD, "$cmd 2>&1 |") || Error "can't run command: $!";while (<CMD>){## Filter output from the user#next if ( $quiet );s~(file 1: )$path1/~$1~;s~(file 2: )$path2/~$1~;print FO $_;}close(CMD);Verbose2 "ClearTool Exit Status: $?";return $? / 256;}#-------------------------------------------------------------------------------# Function : ClearCmd## Description : Execute a cleartool command# Capture error messages only## Inputs : Command to execute## Returns : Exit code# Also the global @error_list#sub ClearCmd{my( $cmd ) = @_;Verbose2 "cleartool $cmd";@error_list = ();open(CMD, "cleartool $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;}#-------------------------------------------------------------------------------# Documentation#=pod=head1 NAMEjats_cbuilder - Build a package given a clearcase label=head1 SYNOPSISjats jats_ccview [options] label-1 label-2Options:-help - brief help message-help -help - Detailed help message-man - Full documentation=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.=back=head1 DESCRIPTIONThis program is the primary tool for ...=cut