Subversion Repositories DevTools

Rev

Rev 2026 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#! perl
########################################################################
# Copyright ( C ) 2004 ERG Limited, All rights reserved
#
# Module name   : jats.sh
# Module type   : Makefile system
# Compiler(s)   : n/a
# Environment(s): jats
#
# Description   : Build a package specified by a WIP
#                 Needs an rtag_id and a pv_id
#                 It is expected that Release Manager will provide these
#                 details such that they can be cut and pasted.
#
#                 Will create an auto.pl file
#
# Usage         : jats jats_build_a_wip.pl ....
#
# Version   Who      Date        Description
#
#......................................................................#

require 5.006_001;
use strict;
use warnings;
use JatsError;
use JatsSystem;
use JatsVersionUtils;
use JatsRmApi;

use Cwd;
use DBI;
use Getopt::Long;
use Pod::Usage;                             # required for help support

my $GBE_PERL     = $ENV{'GBE_PERL'};
my $GBE_CORE     = $ENV{'GBE_CORE'};


#
#   Release Manager Connection Information
#
my $RM_DB;

################################################################################
#   Global data
#
my $VERSION = "1.0.0";
my %ReleasePackages;            # Packages in the release
my %BuildPackages;              # Packages for this build
my %TargetPackage;              # Package being processed

#
#   Options
#
my $opt_help = 0;
my $opt_manual = 0;
my $opt_verbose = 0;

my $result = GetOptions (
                "help+"     => \$opt_help,          # flag, multiple use allowed
                "manual"    => \$opt_manual,        # flag
                "verbose+"  => \$opt_verbose,       # flag
                );

#
#   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_manual || ($opt_help > 2));

#
#   Configure the error reporting process now that we have the user options
#
ErrorConfig( 'name'    =>'BUILDAWIP',
             'verbose' => $opt_verbose );


#
#   Current interface uses RM line of the form
#       http://erg:8002/ManagerSuite/Release_Manager/fixed_issues.asp?pv_id=104240&rtag_id=6924
#   This should be replaced - lateer
#

Error ("Speficy RM string with pv_id and rtag_id") unless ( $ARGV[0] );
my $PV_ID = $1 if ( $ARGV[0] =~ m~pv_id=(\d+)~ );
my $RTAG_ID = $1 if ($ARGV[0] =~ m~rtag_id=(\d+)~ );

Error ("Could not extract rtad_id and pv_id from command", $ARGV[0]) unless ( $PV_ID && $RTAG_ID );
Verbose( "PV_ID: $PV_ID, RTAG_ID: $RTAG_ID");

#
#   Extract information for the target package
#
GetPackageDetailsByPVID ($PV_ID );
GetBuildDetailsByPVID ( $PV_ID );

#
#   Create a hash of all the packages in the current release
#       Need this generate basis for WIP labels
#       Need this to create current versions
#
getPkgDetailsByRTAG_ID( $RTAG_ID );
DebugDumpData("PackageData", \%TargetPackage);


Message ("Package       : $TargetPackage{name}");
Message ("Version   : $TargetPackage{version}");
Message ("Label     : $TargetPackage{label}");
Message ("Path      : $TargetPackage{path}");
Message ("Change    : $TargetPackage{ChangeType}");
#Message ("BuildType : $TargetPackage{BuildType}");
Message ("BuildStan : $TargetPackage{BS_ID}");
#Message ("RTAG_ID: $TargetPackage{RTAG_ID}");

#
#   Assume that we need to ripple the current build version
#   Generate a new build version. The package may be a WIP
#
my ($pkg_name, $pkg_ver, $pkg_proj ) = NextBuildVersion( $TargetPackage{name}, $TargetPackage{version} ,'r' );

#
#   Body of the process
#
getPkgDetailsByPV_ID( $RTAG_ID, $PV_ID );

#
#   Create a configuration file for use by the JATS rewrite tool
#   This will allow the build.pl file to be re-written
#
my $file = "jats_rewrite.cfg";
open CFG, ">$file" || Error("Cannot create $file" );
print CFG "${pkg_name} ${pkg_ver}.${pkg_proj}\n";

foreach my $pkg ( keys %BuildPackages )
{
    foreach my $prj ( keys %{$BuildPackages{$pkg}} )
    {
        my $ver = $BuildPackages{$pkg}{$prj};
        if ( $prj )
        {
            print CFG "${pkg} ${ver}.${prj}\n";
        }
        else
        {
            print CFG "${pkg} ${ver}\n";
        }
    }
}
close CFG;

#
#   Massage the build.pl file to create the auto.pl file
#   That will be used to create the final package.
#
Message "Calling jats_rewrite.pl\n";
JatsTool ('jats_rewrite.pl', "-conf", $file, "-verb" ) && Error("Did not rewrite build.pl file");

exit 0;

#-------------------------------------------------------------------------------
# Function        : NextBuildVersion
#
# Description     : Determine the next build version number
#                   Assume this is a SIMPLE ripple build
#
# Inputs          : pkg_name
#                   pkg_ver
#                   type        - M,m,p,r
#                               Major, Minor, Patch or Ripple
#
# Returns         :
#
sub NextBuildVersion
{
    my ( $name, $ver, $type ) = @_;

    #
    #   Extract the version number from the project name
    #
    my ( $pn, $pv, $pp ) = SplitPackage( $name, $ver );
    if ( $pv eq 'WIP' )
    {
        ($pv) = keys %{$ReleasePackages{$pn}{$pp}};
        Error ("Cannot determine current version for package", "$name $ver" ) unless ( $pv );

        $type = $TargetPackage{ChangeType};
        Error ("Cannot determine WIP change Type", "$name $ver" ) unless ( $type );
    }

    #
    #   Create a hash of existing versions for the required package
    #   These will be used to assist in determing the next version number
    #
    my $versions = GetPackageVersions( $name );
    $versions = $versions->{$pp};

    #
    #   Scan the versions and create a hash to assist in determing if a version
    #   already exists.
    #       Key it by MAJOR, MINOR, PATCH
    #
    my %vhash;
    foreach ( @{$versions} )
    {
        next if ( m/WIP/i );
        my ($major, $minor, $patch, $build ) = SplitVersion( $_ );
        $vhash{$major}{$minor}{$patch}{$build} = 1;
    }
#    DebugDumpData ("VVVV", \%vhash );

    #
    #   Extract the major, minor, patch and build number
    #
    my ($major, $minor, $patch, $build ) = SplitVersion( $pv );

#print "Base: $major, $minor, $patch, $build, Type: $type\n";
    my $done = 0;
    while ( !$done )
    {
        #
        #   Bump the reqired part of the version number
        #
        if ( $type eq 'M' ) {
            $major++;
            next if ( exists $vhash{$major} );
            $minor = 0;
            $patch = 0;
            $build = 0;

        } elsif ( $type eq 'm' || $type eq 'N' ) {
            $minor++;
            next if ( exists $vhash{$major}{$minor} );
            $patch = 0;
            $build = 0;

        } elsif ( $type eq 'p' || $type eq 'P' ) {
            $patch++;
            next if ( exists $vhash{$major}{$minor}{$patch} );
            $build = 0;

        } else {
            $build++;
            next if ( exists $vhash{$major}{$minor}{$patch}{$build} );
        }
        $done = 1;
    }

    #
    #   Build number retains its 3 character extension
    #
    Error ("Build number is too big: $build" )
        if ( $build >= 999 );
    $build = sprintf( "%-03.3d", $build );


    #
    #   Join them back again
    #
    Message "Current Version: $name, $ver",
            "Next Version:    $name, $major.$minor.${patch}${build}.$pp\n";
    return ( $name, "$major.$minor.${patch}${build}", $pp  );
}

#-------------------------------------------------------------------------------
# Function        : GetPackageVersions
#
# Description     : Get a hash of package versions for the named package
#
# Inputs          : $name           - Package name
#
# Returns         :
#
sub GetPackageVersions
{
    my ($name ) = @_;

    my $foundDetails = 0;
    my (@row);
    my %versions;

    # if we are not or cannot connect then return 0 as we have not found anything
    connectRM(\$RM_DB) unless ( $RM_DB );

    #
    #   Determine all versions of the named package
    #

    my $m_sqlstr = "SELECT pkg.PKG_NAME, pkg.PKG_ID, pv.PKG_VERSION FROM PACKAGES pkg, PACKAGE_VERSIONS pv WHERE pkg.PKG_NAME = \'$name\' 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 )
                {
                    my $id = $row[1];
                    my ( $name, $ver, $proj ) = SplitPackage( $row[0], $row[2] );
                    push @{$versions{$proj}}, $ver;
                }
            }
            $sth->finish();
        }
    }
    else
    {
        Error("GetPackageVersions:Prepare failure" );
    }

#    $RM_DB->disconnect() || Error ("Disconnect failed");
#    DebugDumpData("Versions", \%versions );
    return \%versions;
}


#-------------------------------------------------------------------------------
# Function        : getPkgDetailsByPV_ID
#
# Description     : Extract the dependancies for a specified package
#                   This is not a function of RTAG_ID, only the PV_ID
#
# Inputs          : RTAG_ID
#                   PV_ID
#
# Returns         :
#
sub getPkgDetailsByPV_ID
{
    my ( $rtag_id, $pv_id ) = @_;
    my (@row);

    # if we are not or cannot connect then return 0 as we have not found anything
    connectRM(\$RM_DB) unless ( $RM_DB );

    #
    #   Extract the package dependacies
    #
    my $m_sqlstr = "SELECT pkg.PKG_NAME, pv.PKG_VERSION" .
                " FROM PACKAGE_DEPENDENCIES pd, PACKAGE_VERSIONS pv, PACKAGES pkg" .
                " WHERE pd.PV_ID = \'$pv_id\' AND pd.DPV_ID = pv.PV_ID AND pv.PKG_ID = pkg.PKG_ID";
    my $sth = $RM_DB->prepare($m_sqlstr);
    if ( defined($sth) )
    {
        if ( $sth->execute( ) )
        {
            if ( $sth->rows )
            {
                while ( @row = $sth->fetchrow_array )
                {
                    my ( $pn, $pv, $pp ) = SplitPackage( $row[0], $row[1] );
                    my ($rp) = keys %{$ReleasePackages{$pn}{$pp}};

                    $BuildPackages{$pn}{$pp} = $rp;

#                    print  ' ' x 4, "$pn $pv $pp\n";
#                    if ( $rp ne $pv )
#                    {
#                        print "  ----- Package not in release. Needs $rp";
#                    }
#                    print "\n";
                }
            }
            $sth->finish();
        }
    }
    else
    {
        Error("GetDepends:Prepare failure" );
    }
}

#-------------------------------------------------------------------------------
# Function        : getPkgDetailsByRTAG_ID
#
# Description     : Build up a structure for all the currently released
#                   packages in a given release
#
# Inputs          : rtag_id
#
# Returns         : Hash
#

sub getPkgDetailsByRTAG_ID
{
    my ($RTAG_ID) = @_;
    my $foundDetails = 0;
    my (@row);

    # if we are not or cannot connect then return 0 as we have not found anything
    connectRM(\$RM_DB) unless ( $RM_DB );

    # First get details from pv_id

    my $m_sqlstr = "SELECT pv.PV_ID, pkg.PKG_NAME, pv.PKG_VERSION" .
                   " FROM RELEASE_CONTENT rc, PACKAGE_VERSIONS pv, PACKAGES pkg" .
                   " WHERE rc.RTAG_ID = $RTAG_ID AND rc.PV_ID = pv.PV_ID AND pv.PKG_ID = pkg.PKG_ID";
    my $sth = $RM_DB->prepare($m_sqlstr);
    if ( defined($sth) )
    {
        if ( $sth->execute( ) )
        {
            if ( $sth->rows )
            {
                while ( @row = $sth->fetchrow_array )
                {
                    my $pv_id   = $row[0];
                    my $name    = $row[1];
                    my $version = $row[2];

                    my ( $pn, $pv, $pp ) = SplitPackage( $name,  $version );
                    $ReleasePackages{$pn}{$pp}{$pv} = $pv_id;
                }
            }
            $sth->finish();
        }
        else
        {
            Error ("getPkgDetailsByRTAG_ID: Execute error");
        }
    }
    else
    {
        Error("getPkgDetailsByRTAG_ID: Prepare failure" );
    }
}

#-------------------------------------------------------------------------------
# Function        : GetPackageDetailsByPVID
#
# Description     : Determine the package details
#
#
# Inputs          : PV_ID
#
# Returns         :
#
sub GetPackageDetailsByPVID
{
    my ($pv_id) = @_;
    my (@row);

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

    #
    #   Extract data from Release Manager
    #   Note: The required package may be in one of a number of tables
    #
    my $m_sqlstr = "SELECT pkg.PKG_NAME, pkg.PKG_ID, pv.PKG_VERSION, pv.PV_ID, pv.SRC_PATH, pv.PKG_LABEL, pv.CHANGE_TYPE ,pv.BUILD_TYPE, pv.BS_ID" .
                   " FROM PACKAGES pkg, PACKAGE_VERSIONS pv" .
                   " WHERE pv.PV_ID = $pv_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 )
                {
                    $TargetPackage{name} = $row[0];
                    $TargetPackage{version} = $row[2];
                    $TargetPackage{path} = $row[4] || Error("Package path not in RM");
                    $TargetPackage{PKG_ID} = $row[1];
                    $TargetPackage{PV_ID} = $row[3];
                    $TargetPackage{label} = $row[5] || Error("Package Label not in RM");
                    $TargetPackage{ChangeType} = $row[6] || 'None';
                    $TargetPackage{BuildType} = $row[7] || '';
                    $TargetPackage{BS_ID} = $row[8] || '';


                    Verbose ("DATA: @row");
                    last;
                }
            }
            else
            {
                Error("Package with PV_ID of $PV_ID not found in RM");
            }
            $sth->finish();
        }
    }
    else
    {
        Error("GetData:Prepare failure" );
    }

#    DebugDumpData("PackageData", \%TargetPackage);
}

#-------------------------------------------------------------------------------
# Function        : GetBuildDetailsByPVID
#
# Description     : Determine the package details
#
#
# Inputs          : PV_ID
#
# Returns         :
#
sub GetBuildDetailsByPVID
{
    my ($pv_id) = @_;
    my (@row);

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

    #
    #   Extract data from Release Manager
    #
    my $m_sqlstr = "SELECT pbi.BSA_ID, pbi.BM_ID" .
                    " FROM PACKAGE_BUILD_INFO pbi" .
                    " WHERE pbi.PV_ID = \'$pv_id\'";

    
    my $sth = $RM_DB->prepare($m_sqlstr);
    if ( defined($sth) )
    {
        if ( $sth->execute( ) )
        {
            if ( $sth->rows )
            {
                while ( @row = $sth->fetchrow_array )
                {

                    #
                    #   BSA_ID: 1:debug, 2:prod, 3:debug+prod, 4:Java1.4 5: Java 1.5
                    #   BM_ID : 1:solaris, 2:win32, 3: linux, 4:generic
                    #
                    Verbose ("DATA: @row");
                    print "----- BM_ID : $row[1]\n";
                    print "----- BSA_ID: $row[0]\n";
                    $TargetPackage{BUILD}{$row[1]} = $row[0];


                }
            }
            else
            {
                Error("Package with PV_ID of $PV_ID not found in RM");
            }
            $sth->finish();
        }
    }
    else
    {
        Error("GetData:Prepare failure" );
    }

#    DebugDumpData("PackageData", \%TargetPackage);
}