Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6887 dpurdie 1
########################################################################
2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
3
#
4
# Module name   : rmMerge_syncRelease.pl
5
# Module type   : JATS Utility
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   : Sync a Release from Pulse to Original
10
#
11
# Usage         : See POD at the end of this file
12
#
13
#......................................................................#
14
 
15
require 5.008_002;
16
use strict;
17
use warnings;
18
 
19
use Pod::Usage;
20
use Getopt::Long;
21
 
22
use JatsError;
23
use JatsRmApi;
24
use JatsSystem;
25
use FileUtils;
26
use ConfigurationFile;
27
use File::Copy;
28
use DBI;
29
my $RM_DB;
30
 
31
my $opt_reuse=1;
32
my $opt_help=0;
33
my $opt_verbose=0;
34
my $opt_debug=0;
35
my $opt_order;
36
my $opt_type;
37
my $opt_noShow = 0;
38
my $opt_refresh;
39
my $opt_commands;
40
my $opt_rtagId;
41
my $opt_pulseRtagId;
42
 
43
our %basePackageVersions;
44
our %testPackageTip;
45
our %usedBy;
46
my %old;
47
my %oldPnames;
48
my %oldPackages;
49
my %newPnames;
50
my %new;
51
my %essential;
52
my %releaseContents;
53
my %releaseNames;
54
my %pvidLookup;
55
my %pvidLookupOld;
56
my %pulseImport;
57
 
58
my %data;
59
my %stats;
60
 
61
my $VERSION = "1.0";
62
my $SplitPvid = 1150630;
63
my $oldRMCred = ['OLD', 'jdbc:oracle:thin:@auawsards001:1521:RELEASEM', 'RM_READONLY', 'RM_READONLY'];
64
my $newRMCred = ['NEW', 'jdbc:oracle:thin:@auawsards002:1521:RELEASEM', 'RM_READONLY', 'Tp8WmmDKMq2Z'];
65
my $localDataStore = "LocalSyncData.txt";
66
 
67
my $dirSame = 'data/same';
68
my $dirDiff = 'data/diff';
69
my $dirBuildDiff = 'data/build_diff';
70
my $dirSkip = 'data/skip';
71
my $dirBroken = 'data/broken';
72
my $dirWork = 'data/work';
73
my $dirLog  = 'data/log';
74
mkdir ('data');
75
mkdir ($dirWork);
76
mkdir ($dirLog);
77
unlink 'stopfile';
78
 
79
#-------------------------------------------------------------------------------
80
# Function        : Mainline Entry Point
81
#
82
# Description     :
83
#
84
# Inputs          :
85
#
86
my $result = GetOptions (
87
                "help:+"        => \$opt_help,
88
                "manual:3"      => \$opt_help,
89
                "verbose:+"     => \$opt_verbose,
90
                "debug:+"       => \$opt_debug,
91
                'PulseRtagid:i' => \$opt_pulseRtagId,
92
                'Rtagid:i'      => \$opt_rtagId,
93
                "reuse!"        => \$opt_reuse,
94
                "order:n"       => \$opt_order,
95
                "type:s"        => \$opt_type,
96
                "refresh!"      => \$opt_refresh,
97
                "commands!"     => \$opt_commands,
98
                );
99
 
100
                #
101
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
102
                #
103
 
104
#
105
#   Process help and manual options
106
#
107
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
108
pod2usage(-verbose => 1) if ( $opt_help == 2 );
109
pod2usage(-verbose => 2) if ( $opt_help > 2 );
110
#pod2usage(-verbose => 0, -message => "Version: $VERSION") if ( $#ARGV < 0 );
111
 
112
#
113
#   Configure the error reporting rmMerge_process now that we have the user options
114
#
115
ErrorConfig( 'name'    =>'SYNC',
116
             'verbose' => $opt_verbose,
117
             'debug' => $opt_debug,
118
            );
119
Error ("No rtagId in old Rm provided") unless defined $opt_rtagId;
120
Error ("No rtagId in Pulse Rm provided") unless defined $opt_pulseRtagId;
121
 
122
#
123
#   Control output
124
#
125
if ($opt_order || $opt_type || $opt_commands) {
126
    $opt_noShow = 1;
127
}
128
 
129
my $pulseData = GetDataReleaseData ($newRMCred, $opt_pulseRtagId );
130
my $oldData =   GetDataReleaseData ($oldRMCred, $opt_rtagId );
131
 
132
#
133
#   Report NEW packages - need to be rmMerge_processed manually
134
#   
135
foreach my $key ( keys %{$pulseData}) {
136
    unless (exists $oldData->{$key}) {
137
        ReportError("New Package - $key");
138
    }
139
}
140
 
141
#
142
#   Report new package versions that can be transferred
143
#
144
my @changedPvidList;
145
foreach my $key ( keys %{$pulseData}) {
146
    next unless (exists $oldData->{$key});
147
    unless ($oldData->{$key}[1] eq $pulseData->{$key}[1]) {
148
        Warning("Package Version change: $pulseData->{$key}[0] $pulseData->{$key}[1], $oldData->{$key}[1] ");
149
        $pulseData->{$key}[10] = 'M';
150
        push @changedPvidList,  $pulseData->{$key}[5]; 
151
    }
152
}
153
 
154
unless (@changedPvidList) {
155
    Message("No changes detected");
156
    exit 0;
157
}
158
 
159
#
160
#   Determine the transfer order
161
#   
162
 
163
my $txOrder = GetDependencyData($newRMCred, \@changedPvidList);
164
foreach my $key ( @{$txOrder} ) {
165
    print("jats eprog rmMerge_migrate_package.pl $pulseData->{$key}[0] $pulseData->{$key}[1]\n");
166
}
167
 
168
 
169
 
170
#DebugDumpData("pulseData", $pulseData);
171
restoreLocalData();
172
saveLocalData();
173
exit 0;
174
 
175
#-------------------------------------------------------------------------------
176
# Function        : GetDependencyData 
177
#
178
# Description     : 
179
#
180
# Inputs          : 
181
#
182
# Returns         : 
183
#
184
sub GetDependencyData
185
{
186
    my ($rmRef, $refChanges) = @_;
187
    my $m_sqlstr;
188
    my $list = join(',', @{$refChanges});
189
    my $depData;
190
 
191
    #
192
    #   Insert info for base packages
193
    #       Capture those packages that have no dependencies
194
    #
195
    $m_sqlstr = <<"END_SQL";
196
    SELECT p1.pkg_name, pv1.pkg_version, pv1.v_ext from
197
        release_manager.PACKAGES p1,
198
        release_manager.PACKAGE_VERSIONS pv1
199
 
200
    WHERE pv1.pv_id in ( $list )
201
    AND pv1.pkg_id = p1.pkg_id
202
 
203
END_SQL
204
    my $data = getDataFromRm('GetDependencyData2',$m_sqlstr, $rmRef, { dump => 0, sql => 0} );
205
    foreach ( @{$data}) {
206
        my $key = join($;, $_->[0], $_->[2]);
207
        $depData->{$key} = {};
208
    }
209
 
210
    #
211
    #   Now Capture dependency information
212
    #   
213
    $m_sqlstr = <<"END_SQL";
214
    SELECT p1.pkg_name, pv1.pkg_version, pv1.v_ext, p.pkg_name, pv.pkg_version, pv.v_ext from
215
        release_manager.PACKAGE_DEPENDENCIES pd,
216
        release_manager.PACKAGES p,
217
        release_manager.PACKAGES p1,
218
        release_manager.PACKAGE_VERSIONS pv,
219
        release_manager.PACKAGE_VERSIONS pv1
220
 
221
    WHERE pd.pv_id in ( $list )
222
    AND pd.dpv_id = pv.pv_id
223
    AND pv.pkg_id = p.pkg_id
224
    AND pd.pv_id = pv1.pv_id
225
    AND pv1.pkg_id = p1.pkg_id
226
 
227
END_SQL
228
    $data = getDataFromRm('GetDependencyData',$m_sqlstr, $rmRef, { dump => 0, sql => 0} );
229
    foreach ( @{$data}) {
230
        my $key = join($;, $_->[0], $_->[2]);
231
        my $dkey =join($;, $_->[3], $_->[5]);
232
        $depData->{$key}{$dkey} = 1;
233
    }
234
 
235
#DebugDumpData("depData", $depData);
236
    #
237
    #   Determine the rmMerge_processing order
238
    #
239
    my @order;
240
    my $orderNum = 0;
241
 
242
    while (keys %{$depData})
243
    {
244
        $orderNum++;
245
 
246
        #
247
        #   Resolve the transfer order
248
        #       Remove dependencies that are not primary keys - assume they have already been transferred
249
        foreach my $key ( sort keys %{$depData} ) {
250
            foreach my $dkey ( keys $depData->{$key} )
251
            {
252
                unless ( exists($depData->{$dkey}) ) {
253
                    delete $depData->{$key}{$dkey};
254
    #                Debug0("Delete $dkey from $key");
255
                }
256
            }
257
        }
258
 
259
        #
260
        #   Can now action those with no dependencies
261
        foreach my $key ( keys %{$depData} ) {
262
            unless (keys $depData->{$key}) {
263
                push @order, $key;
264
                delete $depData->{$key};
265
            }
266
        }
267
    }
268
 
269
#DebugDumpData("depData2", \@order);
270
    return \@order;
271
}
272
 
273
 
274
#-------------------------------------------------------------------------------
275
# Function        : GetDataReleaseData
276
#
277
# Description     : Get data for a Release
278
#
279
# Inputs          : 
280
#
281
# Returns         : 
282
#
283
sub GetDataReleaseData
284
{
285
    my ($rmRef, $rtagId) = @_;
286
 
287
    my $m_sqlstr = <<"END_SQL";
288
    SELECT p.pkg_name, pv.pkg_version, pv.v_ext, release_manager.PK_RMAPI.return_vcs_tag(pv.PV_ID), NVL(pv.PKG_IDEXT,'-'), pv.pv_id  from
289
        release_manager.RELEASE_CONTENT rc,
290
        release_manager.PACKAGES p,
291
        release_manager.PACKAGE_VERSIONS pv
292
 
293
    WHERE rc.rtag_id = $rtagId
294
    AND rc.pv_id = pv.pv_id
295
    AND pv.pkg_id = p.pkg_id
296
 
297
END_SQL
298
    my $data = getDataFromRm('GetDataReleaseData',$m_sqlstr, $rmRef, { dump => 0} );
299
    my $procData;
300
    foreach ( @{$data}) {
301
        my $key = join($;, $_->[0], $_->[2]);
302
        $procData->{$key} = $_;
303
    }
304
    #DebugDumpData("Proc", $procData);
305
    return $procData;
306
}
307
 
308
#-------------------------------------------------------------------------------
309
# Function        : getDataFromRm 
310
#
311
# Description     : Get an array of data from RM 
312
#
313
# Inputs          : $name           - Query Name
314
#                   $m_sqlstr       - Query
315
#                   $rmRef          - Ref to RM
316
#                   $options        - Ref to a hash of options
317
#                                       sql     - show sql
318
#                                       data    - show data
319
#                                       dump    - show results
320
#                                       oneRow  - Only feth one row
321
#                                       error   - Must find data
322
#                                       
323
# Returns         : 
324
#
325
sub getDataFromRm
326
{
327
    my ($name,$m_sqlstr, $rmRef, $options ) = @_;
328
    my @row;
329
    my $data;
330
 
331
    if (ref $options ne 'HASH') {
332
        $options = {}; 
333
    }
334
 
335
    $ENV{GBE_RM_LOCATION} = $rmRef->[1];
336
    $ENV{GBE_RM_USERNAME} = $rmRef->[2];
337
    $ENV{GBE_RM_PASSWORD} = $rmRef->[3];
338
    connectRM(\$RM_DB, $opt_verbose);
339
 
340
    if ($options->{sql}) {
341
        Message("$name: $m_sqlstr")
342
    }
343
    my $sth = $RM_DB->prepare($m_sqlstr);
344
    if ( defined($sth) )
345
    {
346
        if ( $sth->execute( ) ) {
347
            if ( $sth->rows ) {
348
                while ( @row = $sth->fetchrow_array ) {
349
                    if ($options->{data}) {
350
                        Message ("$name: @row");
351
                    }
352
                    #Debug0("$name: @row");
353
                    push @{$data}, [@row];
354
 
355
                    last if $options->{oneRow};
356
                }
357
            }
358
            $sth->finish();
359
        } else {
360
            Error("Execute failure:$name: $m_sqlstr", $sth->errstr() );
361
        }
362
    } else {
363
        Error("Prepare failure:$name" );
364
    }
365
    disconnectRM(\$RM_DB);
366
 
367
    if (!$data && $options->{error}) {
368
        Error( $options->{error} );
369
    }
370
 
371
    if ($data && $options->{oneRow}) {
372
        $data = $data->[0];
373
    }
374
 
375
    if ($options->{dump}) {
376
        DebugDumpData("$name", $data);
377
    }
378
    return $data;
379
}
380
 
381
#-------------------------------------------------------------------------------
382
# Function        : procData 
383
#
384
# Description     : rmMerge_process the collected data 
385
#
386
# Inputs          : 
387
#
388
# Returns         : 
389
#
390
sub procData
391
{
392
    Message("Process Data");
393
    foreach my $pvid ( sort {uc $pvidLookup{$a} cmp uc $pvidLookup{$b}} keys %essential) {
394
 
395
        #
396
        #   Examine this package
397
        #
398
        my ($key,$pname, $pver, $proj) = split($;, $pvidLookup{$pvid});
399
        $data{$key}{$pver}{pvid} = $pvid;
400
        $data{$key}{$pver}{proj} = $proj;
401
        $data{$key}{$pver}{txt} = "$pname $pver.$proj";
402
        $stats{"Total Packages"} ++;
403
 
404
        #
405
        #   If the packageName.Proj does not exist in the old then its a simple transfer
406
        #   
407
        if ( ! exists ($oldPackages{$pname}) ) {
408
            $data{$key}{$pver}{state} = 'N';        # New package
409
            $stats{"New Package"} ++;
410
 
411
        } elsif (! exists $old{$key}) {
412
            $data{$key}{$pver}{state} = 'n';        # New Project in an existing package
413
            $stats{"New Project"} ++;
414
 
415
        } elsif ($pvid < $SplitPvid ) {
416
            #
417
            #   PV is a pre-split version no work to be done
418
            #   
419
            $data{$key}{$pver}{state} = 'P';        # Pre Clone version
420
            $stats{"Pre Clone"} ++;
421
 
422
        } elsif (! exists $old{$key}{$pver}) {
423
            #
424
            #   If the packageName.Proj does exist, but the version does not then
425
            #   is a mostly simple transfer
426
            #
427
            $data{$key}{$pver}{state} = 'S';        # Not a clash
428
            $stats{"No Clash"} ++;
429
 
430
        } else {
431
            testPackage($key, $pver);
432
            $data{$key}{$pver}{state} = getState($key, $pver);
433
            $stats{"Total Clashes"} ++;
434
            $stats{"ClashMode-" . getState($key, $pver)}++;
435
        }
436
    }
437
 
438
    unless ($opt_noShow) {
439
        print("Packages to Merge\n");
440
        print("Keys: N: New Package, n:New Project, P:PreClone, S:No Clash, D:Diff, d: Build Diff, G:Identical in both, K:Skip Diff\n");
441
        foreach my $pname ( sort keys %data){
442
            foreach my $pver ( sort keys %{$data{$pname}}) {
443
                print("    ",$data{$pname}{$pver}{state}, ' ' ,$data{$pname}{$pver}{txt}, "\n");
444
            }
445
        }
446
    }
447
 
448
 
449
#DebugDumpData("Data", \%data);
450
DebugDumpData("Stats", \%stats) unless ($opt_noShow);
451
 
452
    print("Clashes to resolve\n");
453
    foreach my $pname ( sort keys %data){
454
        foreach my $pver ( sort keys %{$data{$pname}}) {
455
            next unless ($data{$pname}{$pver}{state} =~ m/[dD]/ );
456
            my ($oldPvid, $oldVcs, $oldPname, $oldProj) = split($;, $old{$pname}{$pver} );
457
            my $newPvid =  $data{$pname}{$pver}{pvid};
458
 
459
            print("    ",$data{$pname}{$pver}{state}, " $pname, $pver (N:$newPvid, O:$oldPvid)\n");
460
            foreach my $rtagId (keys %{$releaseContents{$newPvid}} ) {
461
                my $mode = $releaseContents{$newPvid}{$rtagId} > 1 ? " [indirectly]": "";
462
                print("         Used by: $rtagId, $releaseNames{$rtagId}$mode\n");
463
            }
464
 
465
            if (my $usageData = GetUsedProjects($oldPvid,$oldRMCred)) {
466
                foreach my $entry ( @$usageData) {
467
                    print("         Used by Old Release: $entry->[2], $entry->[1] - $entry->[3]\n");
468
                }
469
            }
470
 
471
            if (my $usageData = GetUsedSdks($oldPvid,$oldRMCred)) {
472
                foreach my $entry ( @$usageData) {
473
                    print("         Used by Old SDK: $entry->[2], $entry->[1] - $entry->[3]\n");
474
                }
475
            }
476
 
477
            if (my $usageData = GetUsedSboms($oldPvid,$oldRMCred)) {
478
                foreach my $entry ( @$usageData) {
479
                    print("         Used by Old SBOM: $entry->[2], $entry->[1] - $entry->[3]\n");
480
                }
481
            }
482
 
483
        }
484
    }
485
 
486
    #
487
    #   Examine packages that do exist in the old system to determine if they can be
488
    #   merged to the SVN tip in the old system
489
    #   
490
    #   Only need to rmMerge_process those package-versions that do not clash (S)
491
    #   New 'projects' (n) may need to be branched
492
    #
493
    Verbose("Determine SVN branch needs\n");
494
    foreach my $pname ( sort keys %data){
495
        foreach my $pver ( sort keys %{$data{$pname}}) {
496
            if ($data{$pname}{$pver}{state} eq 'n' ) {
497
                $data{$pname}{$pver}{bstate} = 'F';
498
                $data{$pname}{$pver}{numChanges} = 0;
499
                next;
500
            }
501
            next unless ($data{$pname}{$pver}{state} =~ m/[S]/ );
502
            Verbose("Examine ($data{$pname}{$pver}{state}) $pname, $pver");
503
            my $bstate = '-';
504
            my $numChanges = 0;
505
            if ($numChanges = testPackageChanges($pname,$pver) ) {
506
                $bstate = testPackageTip($pname,$pver);
507
            }
508
            $data{$pname}{$pver}{bstate} = $bstate;
509
            $data{$pname}{$pver}{numChanges} = $numChanges;
510
 
511
            $data{$pname}{$pver}{branchVersion} =  getBranchVersion($pname, $pver);
512
        }
513
    }
514
 
515
    unless ($opt_noShow) {
516
        print("SVN branching\n");
517
        print("Key. Col1: N: New Package, n:New Project, P:PreClone, S:No Clash, D:Diff, d: Build Diff, G:Identical in both, K:Skip Diff\n");
518
        print("Key. Col2  -: No Changes to old Repo, S:Tip Identical, D:Tip Diff, d: Tip Build Diff, F:Force Branch\n");
519
        print("Those marked as 'D' will need to be branched\n");
520
        my $branchCount = 0;
521
        foreach my $pname ( sort {uc $a cmp uc $b } keys %data){
522
            foreach my $pver ( sort {$data{$pname}{$a} cmp $data{$pname}{$b} } keys %{$data{$pname}}) {
523
                next unless (exists $data{$pname}{$pver}{bstate} );
524
                printf( "    %s%s %3.3s %s %s\n",$data{$pname}{$pver}{state},$data{$pname}{$pver}{bstate}, $data{$pname}{$pver}{numChanges} , $pname, $pver);
525
                $branchCount++ if $data{$pname}{$pver}{bstate} =~ m/[DF]/; 
526
            }
527
        }
528
    print("Number of branches: $branchCount\n");
529
    }
530
 
531
    ###########################################################################
532
    #   Determine the rmMerge_processing order
533
    #   Test essential data
534
    #
535
    foreach my $pvid ( keys %essential) {
536
        unless (exists $pvidLookup{$pvid} ) {
537
            ReportError ("PVID not in lookup: $pvid");
538
        }
539
    }
540
    ErrorDoExit();
541
    my %depOrder;
542
    my $order=0;
543
    my %depData;
544
 
545
    foreach my $pvid ( keys %essential) {
546
        $depData{$pvid} = {};
547
        foreach my $dpvid ( keys %{$essential{$pvid}}) {
548
            $depData{$pvid}{$dpvid} = 1;
549
        }
550
    }
551
 
552
    #
553
    #   Cleanup
554
    #   Also delete those where we know the package has been transferred to the old Repo already
555
    #       
556
    foreach my $key ( sort keys %data){
557
        foreach my $pver ( sort keys %{$data{$key}}) {
558
            next unless ( exists ($data{$key}{$pver}{state}));
559
            #next unless ( exists ($data{$key}{$pver}{bstate}));
560
            #next unless ($data{$key}{$pver}{bstate} =~ m~-~);
561
            next unless ($data{$key}{$pver}{state} =~ m~[PGK]~);
562
            delete $depData{$data{$key}{$pver}{pvid}} ;
563
        }
564
    }
565
 
566
    #
567
    #   First pass - remove dependencies that don't exists in the set
568
    #       Hopefully these have already been rmMerge_processed
569
    #
570
    foreach my $pvid ( keys %depData) {
571
        foreach my $dpvid ( keys %{$depData{$pvid}} ) {
572
            delete $depData{$pvid}{$dpvid} unless exists( $depData{$dpvid});
573
        }
574
    }
575
 
576
    while (1) {
577
        $order++;
578
        my @found;
579
        last unless scalar keys %depData;
580
 
581
        # locate items that have no dependencies
582
        foreach my $pvid ( keys %depData) {
583
            my @deps = keys %{$depData{$pvid}};
584
            unless (@deps) {
585
                $depOrder{$pvid} = $order;
586
                push @found, $pvid;
587
                delete $depData{$pvid};
588
                if (exists $pvidLookup{$pvid} ) {
589
                    my ($key,$pname, $pver, $proj) = split($;, $pvidLookup{$pvid});
590
                    if (exists ($data{$key}) && exists ($data{$key}{$pver})) {
591
                        $data{$key}{$pver}{order} = $order;
592
                    }
593
                }
594
            }
595
        }
596
 
597
        # Remove those items that have been rmMerge_processed
598
        foreach my $pvid (keys %depData) {
599
            foreach my $dpvid ( @found) {
600
                delete $depData{$pvid}{$dpvid};
601
            }
602
        }
603
    }
604
 
605
    #
606
    # Print summary of what we have discovered
607
    #
608
    my $pkgCount = 0;
609
    my @commands;
610
    print("Packages to Merge\n");
611
    print("Col1 - Keys: N: New Package, -:New Project, P:PreClone, S:No Clash, D:Diff, d: Build Diff, G:Identical in both, K:Skip Diff\n");
612
    print("Col2 - Keys -: No Changes to old Repo, S:Tip Identical, D:Tip Diff, d: Tip Build Diff, F: Force Branch\n");
613
    print("Col3 - Insertion Order\n");
614
    print("Col4 - Number of changes in oldRm since split\n");
615
    print("Col5 - Package Name and Version\n");
616
    foreach my $pname ( sort { uc $a cmp uc $b } keys %data){
617
        foreach my $pver ( sort {uc $a cmp uc $b} keys %{$data{$pname}}) {
618
 
619
            #
620
            #   If filtering the order
621
            #
622
            if ($opt_order) {
623
                next unless exists $data{$pname}{$pver}{order};
624
                next unless $data{$pname}{$pver}{order} <= $opt_order;
625
            }
626
 
627
            if ($opt_type) {
628
                next unless ($data{$pname}{$pver}{proj} eq $opt_type);
629
            }
630
 
631
            if ($opt_commands) {
632
                if (exists $data{$pname}{$pver}{order}){
633
                    push @commands, join($;, $data{$pname}{$pver}{order}, $data{$pname}{$pver}{txt} );
634
                }
635
            }
636
 
637
           $pkgCount++;
638
 
639
           #
640
           #    Determine branch point information
641
           #    Display old version and branch name
642
           #    
643
           my $bpText = "";
644
           if (exists($pulseImport{$pname})) {
645
               my ($okey,$opname, $opver, $oproj) = split($;, $pvidLookupOld{$pulseImport{$pname}{pvid}});
646
               $bpText = "$opver.$oproj ($pulseImport{$pname}{pvid})";
647
 
648
               if (exists($pulseImport{$pname}{branchName})) {
649
                   $bpText .= " Branch:" . $pulseImport{$pname}{branchName};
650
               }
651
           }
652
 
653
 
654
           printf("    %s%s %2.2s: %3.3s %s , %s , %s\n",
655
                  $data{$pname}{$pver}{state}, 
656
                  $data{$pname}{$pver}{bstate} || ' ', 
657
                  $data{$pname}{$pver}{order} || 'x', 
658
                  $data{$pname}{$pver}{numChanges} || ' ' , 
659
                  $data{$pname}{$pver}{txt},
660
                  $data{$pname}{$pver}{branchVersion} || '',
661
                  $bpText
662
                  );
663
        }
664
    }
665
    print("Packages displayed: $pkgCount\n");
666
 
667
    if ($opt_commands) { 
668
        foreach  ( sort @commands) {
669
            my ($order, $text) = split($;, $_);
670
            print("jats eprog rmMerge_migrate_package.pl $text\n");
671
        }
672
    }
673
 
674
DebugDumpData("Stats", \%stats);
675
#DebugDumpData("Data", \%data);
676
#DebugDumpData("Essentials", \%essential);
677
#DebugDumpData("depOrder", \%depOrder);
678
 
679
 
680
}
681
 
682
#-------------------------------------------------------------------------------
683
# Function        : testPackageChanges 
684
#
685
# Description     : See if there have been any changes to a package in the OLD
686
#                   RM since the clone 
687
#
688
# Inputs          : $key (pname + proj)
689
#                   $pver - version to test 
690
#
691
# Returns         : Number of versions in the old RM created since the split 
692
#
693
sub testPackageChanges
694
{
695
    my ($key,$pver) = @_;
696
    my $found =0;
697
 
698
    foreach my $pver ( keys %{$old{$key}}) {
699
        my ($oldPvid, $oldVcs, $oldPname, $oldProj) = split($;, $old{$key}{$pver} );
700
        if ($oldPvid > $SplitPvid) {
701
            $found ++;
702
        }
703
    }
704
    return $found;
705
}
706
 
707
#-------------------------------------------------------------------------------
708
# Function        : getBranchVersion
709
#
710
# Description     : Determine the package-version in the old Release Manager that would
711
#                   be a suitable branch point for this package-version
712
#                   
713
#                   Assume:
714
#                   For a given packageName/Extension determine the highest PVID before the split
715
#
716
# Inputs          : $key (pname + proj)
717
#                   $pver - version to test 
718
#
719
# Returns         : The package version in the old RM
720
#
721
sub getBranchVersion
722
{
723
    my ($key,$pver) = @_;
724
    my $maxPvid = 0;
725
    my $maxPver;
726
 
727
    foreach my $pver ( keys %{$old{$key}}) {
728
        my ($oldPvid, $oldVcs, $oldPname, $oldProj) = split($;, $old{$key}{$pver} );
729
        if ($oldPvid <= $SplitPvid) {
730
            if ($oldPvid > $maxPvid) {
731
                $maxPvid = $oldPvid;
732
                $maxPver = $pver; 
733
            }
734
        }
735
    }
736
    return $maxPver;
737
}
738
 
739
#-------------------------------------------------------------------------------
740
# Function        : testPackageTip 
741
#
742
# Description     : Test a new packageVersion against the tip of the same package
743
#                   in the old Repo. If there are only build file changes, then
744
#                   its a simple merge.
745
#
746
# Inputs          : $key (pname + proj)
747
#                   $pver - version to test 
748
#
749
# Returns         : Diff Mode
750
#                       'D' - Code diff
751
#                       'd' - Build Diff
752
#                       'S' - Same
753
#                       '?' - Error
754
#
755
sub testPackageTip
756
{
757
    my ($key,$pver) = @_;
758
    my $rCode = "?";
759
 
760
    if (-f 'stopfile') {
761
        Error('StopFile detected');
762
    }
763
 
764
    if (exists $testPackageTip{$key}{$pver}) {
765
        return $testPackageTip{$key}{$pver};
766
    }
767
 
768
    my ($newPvid, $newVcs, $newPname, $newProj) = split($;, $new{$key}{$pver} );
769
 
770
    #
771
    #   Need to massage the newVcs to extract the tip of the package in the old system
772
    #       
773
    my $oldVcs = $newVcs;
774
    $oldVcs =~ s~AUPERASVN02~AUPERASVN01~;
775
    $oldVcs =~ m~(.*)::~;
776
    $oldVcs = $1;
777
 
778
    my $pname = $key;
779
    my $version= $pver;
780
 
781
    print("Extract $pname $version, $oldVcs, $newVcs\n");
782
    my $oldName = join('_', $pname, $version, 'oldTip');
783
    my $newName = join('_', $pname, $version, 'new');
784
 
785
    my $oldView = catdir($dirWork,$oldName );
786
    my $newView = catdir($dirWork,$newName );
787
 
788
 
789
    JatsCmd('-logfile', catfile($dirLog, $oldName.'.log'),'jats_vcsrelease.pl', '-extractfiles', '-noprefix', '-root',$dirWork, '-view', $oldName ,'-label', $oldVcs );
790
    JatsCmd('-logfile', catfile($dirLog, $newName.'.log'),'jats_vcsrelease.pl', '-extractfiles', '-noprefix', '-root',$dirWork, '-view', $newName ,'-label', $newVcs );
791
    my $rv = System('diff', '-rq', $oldView, $newView);
792
    print("TipDiff: $rv\n");
793
    if ($rv == 0) {
794
        $rCode = "S";
795
    } elsif ($rv == 1) {
796
        my $rv = System('diff', '-rq', '--exclude=build.pl', $oldView, $newView);
797
        print("TipBuildDiff: $rv\n");
798
        if ($rv == 0) {
799
            $rCode = 'd';
800
        } else {
801
            $rCode = 'D';
802
        }
803
    }
804
    RmDirTree($oldView);
805
    RmDirTree($newView);
806
 
807
    $testPackageTip{$key}{$pver} = $rCode;
808
    saveLocalData();
809
    return $rCode;
810
}
811
 
812
 
813
#-------------------------------------------------------------------------------
814
# Function        : testPackage 
815
#
816
# Description     : Test a package to see how different it is between the two
817
#                   repositories 
818
#
819
# Inputs          : $key (pname + proj)
820
#                   $pver - version to test 
821
#
822
# Returns         : 
823
#
824
sub testPackage
825
{
826
    my ($key, $pver) = @_;
827
 
828
    if (-f 'stopfile') {
829
        Error('StopFile detected');
830
    }
831
 
832
    my ($newPvid, $newVcs, $newPname, $newProj) = split($;, $new{$key}{$pver} );
833
    my ($oldPvid, $oldVcs, $oldPname, $oldProj) = split($;, $old{$key}{$pver} );
834
 
835
    testPackagesCore($key,$pver,$oldVcs, $newVcs);
836
}
837
 
838
 
839
#-------------------------------------------------------------------------------
840
# Function        : testPackagesCore  
841
#
842
# Description     : Core of the package testing rmMerge_process
843
#
844
# Inputs          : $pname
845
#                   $pver
846
#                   $oldvcs
847
#                   $newvcs
848
#
849
# Returns         : 
850
#
851
 
852
sub testPackagesCore
853
{
854
    my ($pname, $version, $oldvcs, $newvcs ) = @_;
855
    if (isSame($pname, $version) || isDiff($pname, $version) || isBuildDiff($pname, $version) || isSkip($pname, $version) || isBroken($pname, $version)) 
856
    {
857
        Verbose ("Skipping: $pname, $version : " . getState($pname,$version));
858
        return;
859
    }
860
 
861
    if (-f 'stopfile') {
862
        Error('StopFile detected');
863
    }
864
 
865
 
866
    print("Extract $pname $version, $oldvcs, $newvcs\n");
867
    my $oldName = join('_', $pname, $version, 'old');
868
    my $newName = join('_', $pname, $version, 'new');
869
 
870
    my $oldView = catdir($dirWork,$oldName );
871
    my $newView = catdir($dirWork,$newName );
872
 
873
 
874
    JatsCmd('-logfile', catfile($dirLog, $oldName.'.log'),'jats_vcsrelease.pl', '-extractfiles', '-noprefix', '-root',$dirWork, '-view', $oldName ,'-label', $oldvcs );
875
    JatsCmd('-logfile', catfile($dirLog, $newName.'.log'),'jats_vcsrelease.pl', '-extractfiles', '-noprefix', '-root',$dirWork, '-view', $newName ,'-label', $newvcs );
876
    my $rv = System('diff', '-rq', $oldView, $newView);
877
    print("Diff: $rv\n");
878
    if ($rv == 0) {
879
        markSame($pname, $version);
880
    } elsif ($rv == 1) {
881
        my $rv = System('diff', '-rq', '--exclude=build.pl', $oldView, $newView);
882
        print("BuildDiff: $rv\n");
883
        if ($rv == 0) {
884
            markBuildDiff($pname, $version, $oldView, $newView);
885
        } else {
886
            markDiff($pname, $version, $oldView, $newView);
887
        }
888
    } else {
889
        markBroken($pname, $version);
890
    }
891
    RmDirTree($oldView);
892
    RmDirTree($newView);
893
}
894
 
895
#-------------------------------------------------------------------------------
896
# Function        : isSame 
897
#
898
# Description     : known to be good
899
#
900
# Inputs          : 
901
#
902
# Returns         : 
903
#
904
sub isSame
905
{
906
    my ($pname, $pver) = @_;
907
    my $file = catdir($dirSame, join('__', $pname, $pver));
908
    mkdir $dirSame || Error ("Cannot create $dirSame");
909
    return (-f $file);
910
}
911
sub isDiff
912
{
913
    my ($pname, $pver) = @_;
914
    my $file = catdir($dirDiff, join('__', $pname, $pver));
915
    mkdir $dirDiff || Error ("Cannot create $dirSame");
916
    return (-f $file);
917
}
918
sub isSkip
919
{
920
    my ($pname, $pver) = @_;
921
    my $file = catdir($dirSkip, join('__', $pname, $pver));
922
    mkdir $dirSkip || Error ("Cannot create $dirSame");
923
    return (-f $file);
924
}
925
 
926
sub isBroken
927
{
928
    my ($pname, $pver) = @_;
929
    my $file = catdir($dirBroken, join('__', $pname, $pver));
930
    mkdir $dirBroken || Error ("Cannot create $dirSame");
931
    return (-f $file);
932
}
933
sub isBuildDiff
934
{
935
    my ($pname, $pver) = @_;
936
    my $file = catdir($dirBuildDiff, join('__', $pname, $pver));
937
    mkdir $dirBuildDiff || Error ("Cannot create $dirSame");
938
    return (-f $file);
939
}
940
 
941
sub getState
942
{
943
    my ($pname, $pver) = @_;
944
    return 'G' if isSame($pname,$pver);
945
    return 'K' if isSkip($pname,$pver);
946
    return 'd' if isBuildDiff($pname,$pver);
947
    return 'D' if isDiff($pname,$pver);
948
    return 'B' if isBroken($pname,$pver);
949
    return '?';
950
 
951
}
952
#-------------------------------------------------------------------------------
953
# Function        : markSame 
954
#
955
# Description     : Mark known to be the same
956
#
957
# Inputs          : 
958
#
959
# Returns         : 
960
#
961
sub markSame
962
{
963
    my ($pname, $pver) = @_;
964
    my $file = catdir($dirSame, join('__', $pname, $pver));
965
    mkdir $dirSame || Error ("Cannot create $dirSame");
966
    TouchFile($file);
967
}
968
 
969
sub markBroken
970
{
971
    my ($pname, $pver) = @_;
972
    my $file = catdir($dirBroken, join('__', $pname, $pver));
973
    mkdir $dirBroken || Error ("Cannot create $dirSame");
974
    TouchFile($file);
975
}
976
 
977
#-------------------------------------------------------------------------------
978
# Function        : markDiff 
979
#
980
# Description     : Mark known to be the same
981
#
982
# Inputs          : 
983
#
984
# Returns         : 
985
#
986
sub markDiff
987
{
988
    my ($pname, $pver, $dold, $dnew) = @_;
989
    my $file = catdir($dirDiff, join('__', $pname, $pver));
990
    mkdir $dirDiff || Error ("Cannot create $dirDiff");
991
    TouchFile($file);
992
    my $told = catdir($dirDiff,StripDir($dold)); 
993
    my $tnew = catdir($dirDiff,StripDir($dnew)); 
994
 
995
    RmDirTree($told);
996
    RmDirTree($tnew);
997
    move($dold, $told ) || Warning("Cannot move $dold, $dirSame");
998
    move($dnew, $tnew) || Warning("Cannot move $dnew, $dirSame");
999
}
1000
sub markBuildDiff
1001
{
1002
    my ($pname, $pver, $dold, $dnew) = @_;
1003
    my $file = catdir($dirBuildDiff, join('__', $pname, $pver));
1004
    mkdir $dirBuildDiff || Error ("Cannot create $dirDiff");
1005
    TouchFile($file);
1006
    my $told = catdir($dirBuildDiff,StripDir($dold)); 
1007
    my $tnew = catdir($dirBuildDiff,StripDir($dnew)); 
1008
 
1009
    RmDirTree($told);
1010
    RmDirTree($tnew);
1011
    move($dold, $told ) || Warning("Cannot move $dold, $dirSame");
1012
    move($dnew, $tnew) || Warning("Cannot move $dnew, $dirSame");
1013
}
1014
 
1015
 
1016
 
1017
#-------------------------------------------------------------------------------
1018
# Function        : GetDataFromRM 
1019
#
1020
# Description     : Get Data from RM 
1021
#
1022
# Inputs          : $oref - Ref to output hash
1023
#                   $credentials - to use to access RM 
1024
#
1025
# Returns         : 
1026
#
1027
sub GetDataFromRM
1028
{
1029
    my ($oref, $startPvid, $id, $url, $name, $passwd) = @_;
1030
 
1031
    my (@row);
1032
    my $fh;
1033
 
1034
    Message ("Extract data for: $oref");
1035
    open ($fh, '>' , $oref) || Error ("Cant write to $oref");
1036
 
1037
    $ENV{GBE_RM_LOCATION} = $url;
1038
    $ENV{GBE_RM_USERNAME} = $name;
1039
    $ENV{GBE_RM_PASSWORD} = $passwd;
1040
 
1041
    connectRM(\$RM_DB) unless ( $RM_DB );
1042
 
1043
    # First get details from pv_id
1044
    my $m_sqlstr = <<"END_SQL";
1045
        SELECT pv.pv_id, p.pkg_name, pv.pkg_version,release_manager.PK_RMAPI.return_vcs_tag(PV_ID), NVL(pv.PKG_IDEXT,'-') 
1046
        FROM RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES p
1047
        WHERE pv.PKG_ID = p.PKG_ID AND pv.PV_ID > $startPvid ORDER by UPPER(p.pkg_name) DESC
1048
END_SQL
1049
 
1050
    my $sth = $RM_DB->prepare($m_sqlstr);
1051
    if ( defined($sth) )
1052
    {
1053
        if ( $sth->execute( ) )
1054
        {
1055
            if ( $sth->rows )
1056
            {
1057
                while ( @row = $sth->fetchrow_array )
1058
                {
1059
                    print $fh join(' ', @row), "\n";
1060
                }
1061
            }
1062
            $sth->finish();
1063
        }
1064
        else
1065
        {
1066
            Error("Execute failure: $m_sqlstr", $sth->errstr() );
1067
        }
1068
    }
1069
    else
1070
    {
1071
        Error("Prepare failure" );
1072
    }
1073
 
1074
    disconnectRM(\$RM_DB);
1075
    close($fh);
1076
}
1077
 
1078
 
1079
#-------------------------------------------------------------------------------
1080
# Function        : saveLocalData 
1081
#
1082
# Description     : Saves a hash of data to disk 
1083
#
1084
# Inputs          : 
1085
#
1086
# Returns         : 
1087
#
1088
sub saveLocalData
1089
{
1090
    #
1091
    #   Dump out the configuration information
1092
    #
1093
    my $fh = ConfigurationFile::New( $localDataStore);
1094
 
1095
    $fh->DumpData( "\n# testPackageTip\n#\n", "testPackageTip", \%testPackageTip );
1096
    $fh->DumpData( "\n# basePackageVersions\n#\n", "basePackageVersions", \%basePackageVersions );
1097
    $fh->DumpData( "\n# usedBy\n#\n", "usedBy", \%usedBy );
1098
 
1099
    $fh->Close();
1100
}
1101
 
1102
#-------------------------------------------------------------------------------
1103
# Function        : restoreLocalData 
1104
#
1105
# Description     : Read in the locally preserved data 
1106
#
1107
# Inputs          : 
1108
#
1109
# Returns         : 
1110
#
1111
sub restoreLocalData
1112
{
1113
    if (-f $localDataStore) {
1114
        require ( $localDataStore );
1115
    }
1116
}
1117
 
1118
#-------------------------------------------------------------------------------
1119
#   Documentation
1120
#
1121
 
1122
=pod
1123
 
1124
=for htmltoc    GENERAL::ClearCase::
1125
 
1126
=head1 NAME
1127
 
1128
rmMerge_process - Process data for Release Manager Merge
1129
 
1130
=head1 SYNOPSIS
1131
 
1132
jats rmMerge_spit [options] PackageName PackageVersion
1133
 
1134
 Options:
1135
    -help              - brief help message
1136
    -help -help        - Detailed help message
1137
    -man               - Full documentation
1138
    -[no]reuse         - Reuse exsiting rmData (default)
1139
    -refresh           - Refresh data - don't get new package versions
1140
    -order=n           - Only displlay packes with rmMerge_processing order <= n
1141
    -type=nnn          - Only display type nnn
1142
 
1143
=head1 OPTIONS
1144
 
1145
=over 8
1146
 
1147
=item B<-help>
1148
 
1149
Print a brief help message and exits.
1150
 
1151
=item B<-help -help>
1152
 
1153
Print a detailed help message with an explanation for each option.
1154
 
1155
=back
1156
 
1157
=head2 OPTIONS
1158
 
1159
=over
1160
 
1161
=item -[no]reuse
1162
 
1163
The default option is 'reuse'. The 'noreuse' option will cause the program to extract a lot of
1164
data from the two Release Manager databases. This is time consuming.
1165
 
1166
=item -order=n
1167
 
1168
The option will cause the final display to be filtered such that only packages with an insertion
1169
order of less than or equal to that specified will be displayed.
1170
 
1171
=back
1172
 
1173
=head1 EXAMPLE
1174
 
1175
jats eprog rmMerge_process
1176
 
1177
=cut
1178