Subversion Repositories DevTools

Rev

Blame | Last modification | View Log | RSS feed

#!/usr/local/bin/perl -w

use strict;
use Getopt::Std;
use Clearcase::Cmd;
use Clearcase::FindCmd;
use DeployUtils::Logger;
use DeployUtils::BuildFile;

use vars qw / $opt_h $opt_d $opt_n $opt_c $opt_f $opt_v $opt_b $opt_p $opt_l /;

#==============================================================================
#   Usage
#==============================================================================
sub Usage
{
    my $msg = shift;

    my $useStr = 
"Usage:
$0 [-h] [-d N] [-p] [-n|-c|-f] [-v] [-b BuildName] [-l] [ Version1|Label1 ] [ Version2|Label2 ]
where:
    -h       : This help page
    -d N     : Sets Debugging level to N
    -p       : Waits for enter key to be pressed on termination of the script

    -n       : Display File Names only with - (removed), +(added) or ?(changed) prefix
    -c       : Displays result in csv format \"key, name, FromVer, ToVer\"
    -f       : Displays result in formatted output (default)

    -v       : Verify files with different version by running diff on them
    
    -b       : Use BuildName package name rather than from build.pl (used for Label Creation from version Numbers)
    -l       : Indicates arguments are actual labels rather than version numbers to be converted to labels
             : Must Supply Both Labels when using -l
             : If -b & -l are supplied then no build.pl is required.

    Version1 : Uses this version as the from version 
    Version2 : Uses this as the to version

Version formats allowed are  n.n.n-n.prj or n.n.n.prj or 'LATEST' to use view current files
If Version2 is not supplied it defaults to LATEST
If Version 1 & 2 are not supplied defaults are Version1 = version in build.pl, Version2=LATEST
    
Uses the build.pl in the current directory to get pkgname and converts version & pkgname to Labels
Executes a find on those labels and prints the difference.
";
    print "$msg \n" if ( defined($msg) );
    print $useStr;
    exit 0;
}   # Usage


getopts("hd:pncfvb:l");

Usage() if ( defined($opt_h) || $#ARGV > 1 );
Usage("Can only Supply one of -n, -c or -f") if ( defined($opt_n) && defined($opt_c) && defined($opt_f) );
Usage("If -l is supplied must supply both labels") if ( defined($opt_l) && $#ARGV != 1 );

$opt_f = 1 if ( !defined($opt_n) && !defined($opt_c) && !defined($opt_f) );

setLogLevel($opt_d) if ( defined($opt_d) );

my ( @versions, @labels, @findArgs );

my $buildFileInfo;

$buildFileInfo = DeployUtils::BuildFile->new() unless ( defined($opt_b) && defined($opt_l) );

my $pkgName = ( defined($opt_b) ) ? $opt_b : $buildFileInfo->getBuildName();

# if no arg1 version then use the version from buildfile, however if -b & -l are defined both labels
# must be provided so we know we wont ever call getBuildVersion, which is good cause we dont init it above
if ( $#ARGV < 0 )
{
    $versions[0] = $buildFileInfo->getBuildVersion(); 
}
else
{
    $versions[0] = $ARGV[0];
}

# if no arg2 version then use LATEST version
if ( $#ARGV < 1 )
{
    $versions[1] = "LATEST";
}
else
{
    $versions[1] = $ARGV[1];
}

# if -l not supplied then we need to convert to upper case, if -l is supplied leave as is
if ( ! defined($opt_l) )
{
    $pkgName     =~ tr/[a-z]/[A-Z]/;
    $versions[0] =~ tr/[a-z]/[A-Z]/;
    $versions[1] =~ tr/[a-z]/[A-Z]/;
}

for ( my $i = 0; $i <= 1; $i++ )
{
    if ( ! defined($opt_l) )
    {
        if ( $versions[$i] eq "LATEST" )
        {
            $labels[$i]   = "LATEST";
            $findArgs[$i] = "-cview";
        }
        elsif ( $versions[$i] =~ /^(\d+)\.(\d+)\.(\d+)\-(\d+)\.([a-zA-Z]*)$/ )
        {
            $labels[$i]   = sprintf("%s_%s_R_%02d%02d%02d_%02d", $5, $pkgName, $1, $2, $3, $4);
            $findArgs[$i] = "-all -version lbtype($labels[$i])";
        }
        elsif ( $versions[$i] =~ /^(\d+)\.(\d+)\.(\d+)\.([a-zA-Z]*)$/ )
        {
            $labels[$i]   = sprintf("%s_%s_R_%02d%02d%02d", $4, $pkgName, $1, $2, $3);
            $findArgs[$i] = "-all -version lbtype($labels[$i])";
        }
        else
        {
            Usage("Parameter $++i [$versions[$i]] Invalid Version number.\n");
        }
    }
    else
    {
        if ( $versions[$i] eq "LATEST" )
        {
            $labels[$i]   = "LATEST";
            $findArgs[$i] = "-cview";
        }
        else
        {
            $labels[$i]   = $versions[$i];
            $findArgs[$i] = "-all -version lbtype($labels[$i])";
        }
    }
}

LogNorm("Comparing Files against labels $labels[0] and $labels[1]");

my $find1 = Clearcase::FindCmd->new(".", $findArgs[0]);
my $find2 = Clearcase::FindCmd->new(".", $findArgs[1]);

$find1->CCexecute();
$find2->CCexecute();

my $diff = $find2->getDiffListFrom($find1);

if ( defined($opt_v) )
{
    LogInfo("Running Diff accross found versions for verification");
    my $diffCmd = Clearcase::Cmd->new();

    $diffCmd->abortOnError(0);
    $diffCmd->processOutput(0);
    $diffCmd->CCcmd("diff");

    foreach my $name ( sort keys %$diff )
    {
        # Can only check items that are different not ones that are new or removed
        if ( $diff->{$name}{OLD} ne "" && $diff->{$name}{NEW} ne "" )
        {
            $diffCmd->CCargs("-options -status_only \"$name\@\@$diff->{$name}{OLD}\" \"$name\@\@$diff->{$name}{NEW}\"");
            # if files are the same then remove from hash
            if ( $diffCmd->CCexecute() == 0 )
            {
                LogDebug("CClabelDiff Removing item $name from diff list as versions are the same.");
                delete($diff->{$name});
            }
            $diffCmd->reset();
        }
    }
}

if ( defined($opt_n) )
{
    print("Key, Name\n");
    foreach my $name ( sort keys %$diff )
    {
        printf("%s %s\n", ( $diff->{$name}{OLD} ne "" && $diff->{$name}{NEW} ne "" ) ? "?" : ( $diff->{$name}{OLD} eq "" ) ? "+" : "-", $name);
    }
}
elsif ( defined($opt_c) )
{
    print("Key, Name, From, To\n");
    foreach my $name ( sort keys %$diff )
    {
        printf("%s,%s,%s,%s\n", ( $diff->{$name}{OLD} ne "" && $diff->{$name}{NEW} ne "" ) ? "?" : ( $diff->{$name}{OLD} eq "" ) ? "+" : "-",
               $name, $diff->{$name}{OLD}, $diff->{$name}{NEW});
    }
}
elsif ( defined($opt_f) )
{
    foreach my $name ( sort keys %$diff )
    {
        if ( $diff->{$name}{OLD} ne "" && $diff->{$name}{NEW} ne "" )
        {
            printf("? %s\n        %s => %s\n", $name, $diff->{$name}{OLD}, $diff->{$name}{NEW});
        }
        elsif ( $diff->{$name}{OLD} eq "" )
        {
            printf("+ %s\n        %s\n", $name, $diff->{$name}{NEW});
        }
        elsif ( $diff->{$name}{NEW} eq "" )
        {
            printf("- %s\n        %s\n", $name, $diff->{$name}{OLD});
        }
        print("- - - - - - - - - - - - - - -\n");
    }
}


# regardless of how or where this program end this will run (unless user Ctrl-C etc)
# so if -p supplied we put a wait for enter
END
{
    if ( $opt_p )
    {
        LogNorm("Press Enter To Continue");
        getc();
    }
}