Subversion Repositories DevTools

Rev

Blame | Last modification | View Log | RSS feed

########################################################################
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
#
# Module name   : cc2svn_updatermKludge.pl
# Module type   : Makefile system
# Compiler(s)   : Perl
# Environment(s): jats
#
# Description   : Update RM with ClearCase to Subversion conversion info
#
#                 Kludged to handle lost data from the TRACS package
#                 where the DATA file got messed up with an aborted
#                 -resume.
#
#                 Extract data from the importsummary.txt
#
# Usage:
#
# Version   Who      Date        Description
#
#......................................................................#

require 5.008_002;
use strict;
use warnings;

use Pod::Usage;
use Getopt::Long;

use JatsError;
use JatsRmApi;

#
#   Globals
#
my $RM_DB;
my $VERSION = "1.0.0";                      # Update this
my %packageVcs;
my %pkgInfo;
my %importData;
#
#   Options
#
my $opt_verbose = 0;
my $opt_help = 0;
my $opt_package;
my $opt_rm = 'RELMANU1';
my $opt_test = 1;
my $opt_force;
my $opt_checkOperation;
my $opt_report = 0;
my $opt_live;
my $opt_grep;

#-------------------------------------------------------------------------------
# Function        : Main Entry
#
# Description     :
#
# Inputs          :
#
# Returns         :
#
my $result = GetOptions (
                "help+"         => \$opt_help,          # flag, multiple use allowed
                "manual:3"      => \$opt_help,
                "verbose:+"     => \$opt_verbose,       # flag
                'package:s'     => \$opt_package,
                'database:s'    => \$opt_rm,
                'test!'         => \$opt_test,
                'force!'        => \$opt_force,
                'check:s'       => \$opt_checkOperation,
                'report:+'      => \$opt_report,
                'live!'         => \$opt_live,
                'grep'          => \$opt_grep,          # Grep friendly - display pkg name
                );

#
#   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);

ErrorConfig( 'name'    =>'CC2SVN_UPDATERM',
             'verbose' => $opt_verbose,
              );

Error ("Must specify a package name") unless ( defined $opt_package || $#ARGV >= 0 );

if ( $opt_live )
{
    $opt_rm = 'RELEASEM';
}


$ENV{GBE_RM_LOCATION} = 'jdbc:oracle:thin:@auperaprm01:1521:' . $opt_rm;
unless ( $opt_rm eq 'RELEASEM' )
{
    Warning ("Using internal user/password - Test Database");
    $ENV{GBE_RM_USERNAME} = 'RELEASE_MANAGER';
    $ENV{GBE_RM_PASSWORD} = 'RELEASE_MANAGER';
    $ENV{GBE_RM_LOCATION} = 'jdbc:oracle:thin:@auperaora07.vix.local:1521:' . $opt_rm;
}
else
{
    $ENV{GBE_RM_USERNAME} = 'RM_READONLY';
    $ENV{GBE_RM_PASSWORD} = 'RM_READONLY';
}

#
#   Check operation
#
if ( $opt_checkOperation )
{
    Message ("Check RM operation");
    Error ("PVID must be specified via -package option") unless $opt_package;
    intoReleaseManager ($opt_package, $opt_checkOperation);
    Message ("Check Complete OK");
    exit 0;
}


foreach my $fileName ( $opt_package, @ARGV )
{
    next unless ( defined $fileName );
    next if ( $fileName eq 'Dataman' );

    $fileName =~ s~\.data$~~;
    $fileName =~ s~\.svg$~~;
    $fileName =~ s~\.importlog$~~;

    readImportData($fileName);
    readPackageDataFile($fileName);

    foreach my $packageName( sort keys %pkgInfo )
    {
        getVcsData($packageName) if ( $opt_report <= 1 || $opt_report == 6 );
        processPackage($packageName);
    }
}
exit 0;

#-------------------------------------------------------------------------------
# Function        : getVcsData
#
# Description     : Get existing VCS data from the release Manager
#
# Inputs          : 
#
# Returns         : 
#
sub getVcsData
{
    my ($packageName) = @_;
    %packageVcs = ();
    my $pkg_id = GetPkgIdByName ( $packageName );
    GetData_by_pkg_id ( $pkg_id, $packageName  );
    #DebugDumpData("packageVcs", \%packageVcs );
}

#-------------------------------------------------------------------------------
# Function        : readPackageDataFile
#
# Description     : Read in the data file. It may contain data for more
#                   than one package - but this is rare
#
# Inputs          : 
#
# Returns         : Fills in %pkgInfo
#
#
our %ScmVersions;
sub readPackageDataFile
{
    %pkgInfo = ();
    my ($pname) = @_;
    my $fname = $pname . '.data';
    Verbose2 ('Reading Package Data: ' . $fname);
return unless ( -f $fname );
    Error "Cannot locate $fname" unless ( -f $fname );
    %ScmVersions = ();
    require $fname;

    Error "Data in $fname is not valid\n"
        unless ( keys(%ScmVersions) >= 0 );

    foreach (keys %ScmVersions)
    {
        my $entry = $ScmVersions{$_};
        $pkgInfo{$entry->{name}}{$_} = $entry;
    }

    %ScmVersions = ();
}

#-------------------------------------------------------------------------------
# Function        : processPackage
#
# Description     : Process data for one package
#
# Inputs          : Name of the package
#
# Returns         : 
#
sub processPackage
{
    my ($pname) = @_;
    Error ("Internal: Hash data not found")
        unless ( exists $pkgInfo{$pname});
    my $pkgData = $pkgInfo{$pname};

    my @updateList;
    my $essentialCount = 0;
    my $errorCount = 0;
    my $ecount = 0;
    my $notOk = 0;
    my $transferred = 0;
    my $totalCount = 0;
    my $diffCount = 0;
    my $missingPVID = 0;
    my $rippleProcessed = 0;
    my $globalErrors = 0;
    my $notProcessed = 0;
    my $prjBase = 0;
    my $pkgProject = 0;
    my $badPaths = 0;
    my $adjustedPath = 0;
#    my $rtCount = 0;
    my $rtErrorCount = 0;
    my $importTagCount = 0;
    

    foreach (sort {$a <=> $b}  keys(%{$pkgInfo{$pname}} ) )
    {
        my $pkgEntry = $pkgInfo{$pname}{$_};

        $totalCount ++;
        $notProcessed++ unless $pkgEntry->{Scanned};
        $essentialCount++ if ( $pkgEntry->{Essential}  );
        $rippleProcessed++ if ( $pkgEntry->{rippleProcessed} );

        my $pvid = $_;
        if ( $pkgEntry->{rmRef} eq 'ERROR' && exists $importData{$pvid} )
        {
          $pkgEntry->{rmRef} =  $importData{$pvid};
          $importTagCount++;
print "--- Found: $importData{$pvid}\n";
        }
        else
        {
            $globalErrors++ if ( ($pkgEntry->{data}{errFlags} || '') eq 'e' );
            $prjBase++ if ( $pkgEntry->{data}{BadProjectBase} );
            $pkgProject++ if ( $pkgEntry->{data}{BadMakeProject} );
            $badPaths++ if ( $pkgEntry->{data}{BadPath} );
            $adjustedPath++ if ( $pkgEntry->{data}{adjustedPath} );
        }

        unless ( $pkgEntry->{TagCreated} )
        {
            $errorCount++ if ( $pkgEntry->{Essential}  );
            $ecount++;
            Verbose ("Package Not Processed: " . $pkgEntry->{vname} . ' - ' . ($pkgEntry->{data}{errStr} || 'Unspecified Error')  );

            unless ( $pkgEntry->{DeadWood} ||  $pkgEntry->{locked} eq 'N' )
            {
                $notOk++;
#Warning ("Package Not OK: " . $pkgEntry->{vname} . ' - ' . ($pkgEntry->{data}{errStr} || 'Unspecified Error')  );
            }

        }

#        $rtCount += $pkgEntry->{data}{ReleaseTag}{tCount} || 0;
#        $rtErrorCount += $pkgEntry->{data}{ReleaseTag}{eCount} || 0;
    }

    foreach my $pvid (sort {$a <=> $b}  keys(%{$pkgInfo{$pname}} ) )
    {
        my $pkgEntry = $pkgInfo{$pname}{$pvid};
        if ( $pkgEntry->{TagCreated} )
        {
            $transferred++;
            my $done = '';
            my $rmRef = $pkgEntry->{rmRef} ;

            my $include = 1;
            if ( exists $packageVcs{$pvid} )
            {
                if ( $opt_report == 6 )
                {
                    $include = 0 if ( $packageVcs{$pvid} =~ m~^SVN::~ );
                }
                else
                {
                    $include = 0 if ( ($packageVcs{$pvid} eq $rmRef) );
                }
            }
            else
            {
                $missingPVID++;
                $done = ' < Missing' unless $done;
                $include = 0 ;
            }

            if ( $include || $opt_force)
            {
                    $diffCount++;
                    $done = ' *' unless $done;
                    push @updateList, $pvid;
            }

            Verbose ("Processed: " . $pkgEntry->{vname} . ' :: ' . ($rmRef || '???') . $done );
            
        }
    }

    if ( $opt_report == 6 )
    {
        # Display missing updates
        foreach my $entry ( @updateList )
        {
            print "$pname : $pkgData->{$entry}{vname}\n";
        }
        return;
    }

    if ( $opt_report == 5 )
    {
        #
        #   Packages that use MakeProject
        #
        return unless ( $pkgProject );
        print ("$pname\n");
        return;
    }

    if ( $opt_report == 3 )
    {
        #
        #   Just the packages that have no problems
        #   Short form
        #
#Debug0("$pname", $notOk ,$globalErrors ,$prjBase ,$pkgProject ,$errorCount ,$notProcessed ,$rtErrorCount);
        return if ( $notOk ||$globalErrors || $prjBase || $pkgProject ||  $errorCount || $notProcessed || $rtErrorCount || $badPaths);
        print ("$pname\n");
        return;
    }

    if ( $opt_report == 4 )
    {
        #
        #   Just the packages that Global Errors
        #   Short form
        #
        return if (  !$globalErrors);
        print ("$pname\n");
        return;
    }
    
    
    if ( $opt_report )
    {
        return unless ($globalErrors || $prjBase || $pkgProject ||  $errorCount || $notProcessed || $rtErrorCount || $badPaths);
    }

    sub highlight
    {
        my ($value) = @_;
        return $value ? ' <------' : '';
    }

    my $rmTotal = scalar keys %packageVcs;
    my $tpref = $opt_grep ? "$pname: " : '';
    Message ("Transfer Stats",
            ,"${tpref}Package                   : $pname"
            ,"${tpref}Total RM Versions         : $rmTotal"
            ,"${tpref}Total Packages Processed  : $totalCount"
            ,"${tpref}Packages NOT Processed    : $notProcessed" . highlight($notProcessed)
            ,"${tpref}Packages pruned           : " . ($rmTotal - $totalCount)
            ,"${tpref}Essential Packages        : $essentialCount"
            ,"${tpref}Essential Packages Errors : $errorCount" . highlight($errorCount)
            ,"${tpref}Global Import Errors      : $globalErrors" . highlight($globalErrors)

            ,"${tpref}Bad Source Paths          : $badPaths" . highlight($badPaths)
            ,"${tpref}ProjectBase Error         : $prjBase" . highlight($prjBase)
            ,"${tpref}MakeProject Error         : $pkgProject" . highlight($pkgProject)
            ,"${tpref}Adjusted Paths            : $adjustedPath" . highlight($adjustedPath && ($transferred - $adjustedPath))
            ,"${tpref}Not Transferred Packages  : $ecount"
            ,"${tpref}Transferred Packages      : $transferred" . highlight(!$transferred)
#            ,"${tpref}Release Tags applied      : $rtCount"
#            ,"${tpref}Release Tag errors        : $rtErrorCount" . highlight($rtErrorCount)
            ,"${tpref}Transfer to RM            : $diffCount"
            ,"${tpref}Missing PackageVersions   : $missingPVID" . highlight($missingPVID)
            ,"${tpref}Ripple Processed Early    : $rippleProcessed" . highlight($rippleProcessed)
            ,"${tpref}Tags from import file     : $importTagCount" . highlight($importTagCount)
            );

    if ( $opt_report )
    {
        return;
    }
        

    if ( $opt_test )
    {
        Message('Test Mode : No changes made to RM');
        return;
    }

    unless ( $diffCount )
    {
        Message ('Release Manager entries are all upto date');
        return;
    }

    #
    #   Now do the RM Update
    #
    Message('Updating Release Manager: ' . $opt_rm);
    foreach my $entry ( @updateList )
    {
        intoReleaseManager ( $entry, $pkgData->{$entry}{vname}  ,$pkgData->{$entry}{rmRef} );
    }
}

#-------------------------------------------------------------------------------
# Function        : intoReleaseManager
#
# Description     : Update VCS tags in RM
#
# Inputs          : $pvid           - PVId
#                   $name           - Package Version (text)
#                   $tag            - New Tag
#
# Returns         : 
#
sub intoReleaseManager
{
    my ($pvid, $name, $new_tag ) = @_;
    my @row;
    my $user = 3768;            # buildadm

    connectRM(\$RM_DB, $opt_verbose) unless $RM_DB;

    Verbose ("ToRm: $pvid, $name  - $new_tag");
    my $m_sqlstr =  "begin release_manager.PK_RMAPI.update_vcs_details($pvid, '$new_tag', $user); end;";
    my $sth = $RM_DB->prepare($m_sqlstr);
    if ( defined($sth) )
    {
        if ( $sth->execute( ) )
        {
            if ( $sth->rows )
            {
                while ( @row = $sth->fetchrow_array )
                {
                    print "Data: @row\n";
                }
            }
            $sth->finish();
        }
        else
        {
            Error("Execute failure: $m_sqlstr", $sth->errstr() );
        }
    }
    else
    {
        Error("Prepare failure" );
    }
}

#-------------------------------------------------------------------------------
# Function        : GetPkgIdByName
#
# Description     :
#
# Inputs          : pkg_name
#
# Returns         : pkg_id
#
sub GetPkgIdByName
{
    my ( $pkg_name ) = @_;
    my (@row);
    my $pv_id;
    my $pkg_id;

    #
    #   Establish a connection to Release Manager
    #
    connectRM(\$RM_DB) unless ( $RM_DB );

    #
    #   Extract data from Release Manager
    #
    my $m_sqlstr = "SELECT pkg.PKG_NAME, pkg.PKG_ID" .
                   " FROM RELEASE_MANAGER.PACKAGES pkg" .
                   " WHERE pkg.PKG_NAME = \'$pkg_name\'";
                   
    my $sth = $RM_DB->prepare($m_sqlstr);
    if ( defined($sth) )
    {
        if ( $sth->execute( ) )
        {
            if ( $sth->rows )
            {
                while ( @row = $sth->fetchrow_array )
                {
                    Verbose3( "DATA: " . join(',', @row) );
                    $pkg_id = $row[1] || 0;
                    last;
                }
            }
            else
            {
                Error ("GetPkgIdByName:No Data for package: $pkg_name");
            }
            $sth->finish();
        }
    }
    else
    {
        Error("GetPkgIdByName:Prepare failure" );
    }

    return $pkg_id;
}

#-------------------------------------------------------------------------------
# Function        : GetData_by_pkg_id
#
# Description     : Create a hash of VCS tags for a given package
#
# Inputs          : pv_id
#
# Returns         :
#
sub GetData_by_pkg_id
{
    my ( $pkg_id, $packageName ) = @_;
    my (@row);

    #
    #   Establish a connection to Release Manager
    #
    Verbose2("Extract package versions from Release Manager: $packageName");
    connectRM(\$RM_DB) unless ( $RM_DB );

    #
    #   Extract data from Release Manager
    #
    my $m_sqlstr = "SELECT pkg.PKG_NAME, pv.PKG_VERSION, pkg.PKG_ID, pv.PV_ID, release_manager.PK_RMAPI.return_vcs_tag(pv.PV_ID)".
                   " FROM RELEASE_MANAGER.PACKAGES pkg, RELEASE_MANAGER.PACKAGE_VERSIONS pv" .
                   " WHERE pv.PKG_ID = \'$pkg_id\' AND pkg.PKG_ID = pv.PKG_ID";
                   
                   
    my $sth = $RM_DB->prepare($m_sqlstr);
    if ( defined($sth) )
    {
        if ( $sth->execute( ) )
        {
            if ( $sth->rows )
            {
                while ( @row = $sth->fetchrow_array )
                {
                    Verbose3( "DATA: " . join(',', @row) );
                    $packageVcs{$row[3]} = $row[4];
                }
            }
            else
            {
                Error ("GetData_by_pkg_id: No Data: $m_sqlstr");
            }
            $sth->finish();
        }
        else
        {
                Error ("GetData_by_pkg_id: Execute: $m_sqlstr");
        }
    }
    else
    {
        Error("GetData_by_pkg_id:Prepare failure" );
    }
}

#-------------------------------------------------------------------------------
# Function        : readImportData
#
# Description     : Read data from importsummary.txt
#
# Inputs          : tag     - Name fo package
#
# Returns         : 
#
sub readImportData
{
    my ($tag) = @_;
    %importData = ();

    open (IS, '<', 'importsummary.txt' ) || Error ("Cant read importsummart.txt: $!");
    while ( <IS> )
    {
        my @data = split (';', $_);
        next unless ( $data[1] eq 'G' );
        next unless ( $data[3] eq  $tag );
#DebugDumpData('data', \@data );

        $importData{ $data[2] } = $data[5];
    }
    close IS;
#    DebugDumpData('%importData', \%importData );
}


#-------------------------------------------------------------------------------
#   Documentation
#

=pod

=for htmltoc    SYSUTIL::cc2svn::

=head1 NAME

cc2svn_updaterm - Update Release Manager with CC2SVN information

=head1 SYNOPSIS

  jats cc2svn_updaterm [options] [PackageName]*

 Options:
    -help              - brief help message
    -help -help        - Detailed help message
    -man               - Full documentation
    -verbose           - Enable verbosity
    -[no]test          - Test update. Default: -notest
    -[no]live          - Select database. Default: -nolive
    -package=name      - Specify single package to be processed
    -database=name     - Default: RELMANU1 (test db) Live: RELEASEM
    -[no]force         - Force update of all entries
    -check=string      - Check operation with string
    -report            - Report on errors
    -report=1          - Report on errors
    -report=2          - Report on errors, don't access RM
    -report=3          - Packages that have no problems
    -report=4          - Packages that have global errors
    -report=5          - Packages that use MakeProject
    -report=6          - Display missing updates

=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<-[no]test>

Invoke the program in test mode. This is the default.

In test mode the program will examine each packages 'data' results file
and report status and errors.

In 'notest' the program will update the Release Manager database.

=item B<-[no]live>

Invoke the program in live-database mode. This is the NOT the default.

In live mode the program will access the Live Release Manager database.

In non-live mode the program will access the test (RELMANU1) database

=item B<-package=name>

This option will name one package to be processed. Packages to be
processed can just be named on the command line.

=item B<-database=name>

This option specifies the target database. The default value is 'RELMANU1'.
This is a test database.

The production database is RELEASEM.

The user must specifically specify the database to update the production system.

=item B<-[no]force>

This option will force the Release Manager entries to be updated - even if the
current entry matches the desired result.

Useful in testing.

=item B<-check=string>

This option will pass a string directly to the Release Manager updating proceedure.

With this option no packages will be examined or processed.

It is only useful for testing.

=back

=head1 DESCRIPTION

This program is a tool used in the conversion of ClearCase VOBS to subversion.
It will:

=over 8

=item *

Process all packages named on the command line or with the -package option.

=item *

Examine the packages '.data' file, whcih is created as the package is inserted
into Subversion.

=item *

Report the status of the package import and highlight issues.

=item *

Read the Release Manager entry and ensure that the entry is not the same.
If the entry is the same then it will not be updated, unless the '-force'
option has been used.

=item *

Insert the new Version Control information into the Release Manager entry.

=back

The default operation of this utility is to test the import process. The
user needs to provide specific options in order to update the production
database. This is intentional.

=cut