Subversion Repositories DevTools

Rev

Rev 2026 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

########################################################################
# Copyright (C) 1998-2012 Vix Technology, All rights reserved
#
# Module name   : svn2svn_updaterm.pl
# Module type   : Makefile system
# Compiler(s)   : Perl
# Environment(s): jats#
# Description   : Update RM with Subversion Conversion information
#                 Convert OLD svn format into New SVN format
#                 Requires access to SVN repos
# Usage:
#
# Version   Who      Date        Description
#
#......................................................................#

require 5.008_002;
use strict;
use warnings;

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

use JatsError;
use JatsRmApi;
use JatsSvn;
use ConfigurationFile;

#
#   Globals
#
my $RM_DB;
my $VERSION = "1.0.0";                      # Update this
my %packageVcs;
my %packages;
our %SvnCache;

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

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

#
#   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'    =>'SVN2SVN_UPDATERM',
             'verbose' => $opt_verbose,
              );

#
#   Configure RM database to use
#   Default is the TEST(RELMANU1) database
#

$opt_rm = 'RELEASEM' if ( $opt_live );
$ENV{GBE_RM_LOCATION} = 'jdbc:oracle:thin:@auperaprm01:1521:' . $opt_rm;
unless ( $opt_rm eq 'RELEASEM' )
{
    Warning ("Using internal user/passowrd");
    $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';
}

loadCache();
findSvnPackages();
#DebugDumpData('%packages)', \%packages);
processEntry($_) foreach  ( sort sortData keys %packages);
saveCache();
exit 0;

#-------------------------------------------------------------------------------
# Function        : sortData
#
# Description     : 
#
# Inputs          : 
#
# Returns         : 
#
sub sortData
{
    return ( $packages{$a}{version} cmp $packages{$b}{version}  ) if ( $packages{$a}{name} eq $packages{$b}{name} );
    return ( $packages{$a}{name} cmp $packages{$b}{name} );
}

#-------------------------------------------------------------------------------
# Function        : findSvnPackages
#
# Description     : Locate ALL package versions with an SVN VCS
#                   Bit of a Kludge as it assumes the vcs_type
#
# Inputs          : 
#
# Returns         : 
#
sub findSvnPackages
{
    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 pv.PV_ID, p.PKG_NAME, pv.PKG_VERSION, pv.PKG_LABEL, pv.SRC_PATH" .
                   " from RELEASE_MANAGER.PACKAGE_VERSIONS pv," .
                   "      RELEASE_MANAGER.PACKAGES p" .
                   " WHERE pv.VCS_TYPE_ID=23" .
                   " AND pv.PKG_ID = p.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) );

                    my %data;
                    $data{pv_id} = $row[0];
                    $data{name} = $row[1];
                    $data{version} = $row[2];
                    $data{label} = $row[3] || '';
                    $data{path} = $row[4];

                    $packages{$row[0]} = \%data;
                }
            }
            else
            {
                Error ("findSvnPackages:No Data");
            }
            $sth->finish();
        }
    }
    else
    {
        Error("findSvnPackages:Prepare failure" );
    }
}

#-------------------------------------------------------------------------------
# Function        : processEntry
#
# Description     : Process on PVID entry
#
# Inputs          : $pvid               - pvid to process
#
# Returns         : 
#
sub processEntry
{
    my ($pvid) = @_;
    return unless ( exists $packages{$pvid} );
    my $entry = $packages{$pvid};
    my $name = $entry->{name} . ' ' . $entry->{version};
    my $pname = $entry->{name};
    my $baseurl = $entry->{path};
#    return if ( $entry->{path} =~ m~^FRBESA~ );

    if ( ($entry->{label} ne 'N/A') and ($entry->{label} ne '') )
    {
        Verbose2("Already processed: $name");
        return;
    }
    Verbose ("Processing: $name, $baseurl");

Debug0('Path:', $entry->{path});

    #
    #   Backtrack from entry
    #
    if ( $entry->{path} =~ m~/?(.*)/((tags|branches|trunk)(/|$|@)(.*))$~ )
    {
        my $tgt = $2;
        my $ttb = $3;
        my $root = $1;
        my $tag = $5 if ( $ttb eq 'tags');
        my $peg = $1 if ( $tag && $tag =~ m~\@(\d+)$~ );
        my $devBranch;
        my $label;
        my $bt = '-';

        #
        #   If the existing source path is a 'tag' then we need to backtrack
        #   Other wise we can calulate it
        #
        if ( $ttb ne 'tags' )
        {
            #
            #   Not a TAG
            #   Expecting ..../trunk@nnnn or /branches/xxxxx@xxxx
            #
            if ( $entry->{path} =~ m~(.*)\@(\d+)$~ )
            {
                $devBranch = $1;
                $label = $2;
            }
        }
        else
        {
            my $found = 0;
            my $error = 0;
            until ( $found || $error )
            {
                if ( exists $SvnCache{$pname}{$tgt} )
                {
                    Verbose ("Cached result for $tgt");
                    $bt = $SvnCache{$pname}{$tgt};
                }
                else
                {
                    my $svnSession = NewSessionByUrl ( $baseurl, 1 );

            #Debug0('base:', $baseurl, $tgt );
                    my $data;
                    $bt = $svnSession->backTrackSvnLabel($tgt, 'data' => \$data);

Error ("The return value from backTrackSvnLabel has changed since the code was written",
       "The result is now a path relative to the base of the Repo",
       "Result: $bt");


#            Debug0( 'Back:' , $bt );
#            DebugDumpData('$data', $data );

                    if ( ! exists $data->{isaBranch}  ) {
                        Warning ("Cannot backtrack: $name");
                        $error = 1;
                        next;

                    } elsif ( $data->{changeSets} > 1 ) {
                        Warning ("Package: $name has changes on branch: " . $data->{changeSets});
            DebugDumpData('$data', $data );
                        $error = 1;
                        next;
                    }

                    #
                    #   Save for other lookup attempts
                    #   Processing order has been sorted to assist
                    #
                    $SvnCache{$pname}{$tgt} = $bt;
                    saveCache();
                }

                if ( $bt =~ m~^tags/~ )
                {
                    $tgt = $bt;
                    Verbose ("Backtracked to another TAG: $bt");
                }
                else
                {
                    $found = 1;
                }

            }
    

            if ( $bt =~ m~^(.*)(/|\@)(.*)$~ )
            {
                if ( $bt =~ m~^tags/~ )
                {
                    Warning ("Backtracked to another TAG");
                }
                else
                {
                    $devBranch = $root . '/' .$1;
                    if ( $tag ) {
                        $label = $tag;
                    } else {
                        $label = $peg;
                    }
                    $label = $tag || $3;
                }
            }
        }

        if ( ! $devBranch || ! $label )
        {
            Warning("Cannot parse: $name", $entry->{path}, $entry->{label}, $bt, $devBranch, $label );
        }
        else
        {
            Verbose ("Process results: $name, $bt");
            my $tag =  join( '::', 'SVN', $devBranch, $label);
            Message ("Processed: $pvid, $name, $tag");
            intoReleaseManager( $pvid, $tag)
        }
    }
    else
    {
        Warning ("Package does not conatin TTB");
    }
}

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

    if ( $opt_test )
    {
        Information ("No RM write: $pvid, $new_tag");
        return;
    }

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

    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        : loadCache
#
# Description     : Load cached data
#                   Allows the process to be run ahead of time
#                   Speeds up the operations
#
# Inputs          : 
#
# Returns         : 
#
sub loadCache
{

    my $fname = 'svn2svn_cache.txt';
    unless ( -f $fname )
    {
        Warning "Cannot locate $fname" ;
    }
    else
    {
        require $fname;

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

#    DebugDumpData("SvnCache", \%SvnCache );
}

#-------------------------------------------------------------------------------
# Function        : saveCache
#
# Description     : Write out cached results
#
# Inputs          : 
#
# Returns         : 
#
sub saveCache
{
    my $file = 'svn2svn_cache.txt';
    Message ("Create: $file");
    my $fh = ConfigurationFile::New( $file );

    $fh->DumpData(
        "\n# Cached Data.\n#\n",
        "SvnCache", \%SvnCache );

    #
    #   Close out the file
    #
    $fh->Close();
}

#-------------------------------------------------------------------------------
#   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
    -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=2          - Report on errors, don't access RM

=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<-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