Subversion Repositories DevTools

Rev

Rev 5710 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
392 dpurdie 1
########################################################################
6177 dpurdie 2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
392 dpurdie 3
#
4
# Module name   : jats.sh
5
# Module type   : Makefile system
6
# Compiler(s)   : n/a
7
# Environment(s): jats
8
#
9
# Description   : For a given Package + Version display the complete upward (used-by)
10
#                 dependancy tree
11
#
12
#                 Currently hard coded to a Release
13
#
14
#                 Creates .dot files to display the dependancy tree
15
#
16
# Usage         :   Package_name/Version pairs
17
#                   The first one is usd as the base
18
#                   Others name/version pairs onthe command line will also be
19
#                   added to the picture
20
#
21
#......................................................................#
22
 
23
require 5.006_001;
24
use strict;
25
use warnings;
26
 
27
use Pod::Usage;
28
use Getopt::Long;
29
 
30
use JatsError;
31
use JatsVersionUtils;
32
use JatsRmApi;
33
 
34
#use Data::Dumper;
35
use DBI;
36
use Cwd;
37
 
38
my $GBE_PERL     = $ENV{'GBE_PERL'};        # Essential ENV variables
39
my $GBE_CORE     = $ENV{'GBE_CORE'};
40
 
41
my %ReleasePackages;            # Packages in the release
42
my %BuildPackages;              # Packages for this build
43
my %Depends;
44
my %UsedBy;
45
my %Packages;
46
my $RM_DB;
47
my %GDATA;
48
my %GINDEX;
49
my $PNAME;
50
my $PVER;
51
my @ROOT_PVIDS;
52
 
53
#
54
#   Options
55
#
56
my $opt_help = 0;
57
my $opt_verbose = 0;
58
my $opt_rtagid;
59
my $opt_show_extract = 0;
60
 
61
my $result = GetOptions (
62
                "help|h:+"          => \$opt_help,
63
                "manual:3"          => \$opt_help,
64
                "verbose:+"         => \$opt_verbose,       # flag or number
65
                "rtagid|rtag_id=s"  => \$opt_rtagid,
66
                "show:+"            => \$opt_show_extract,
67
                );
68
 
69
#
70
#   Process help and manual options
71
#
72
pod2usage(-verbose => 0)  if ($opt_help == 1  || ! $result);
73
pod2usage(-verbose => 1)  if ($opt_help == 2);
74
pod2usage(-verbose => 2)  if ($opt_help > 2);
75
 
76
#-------------------------------------------------------------------------------
77
# Function        : getPkgDetailsByRTAG_ID
78
#
79
# Description     : Given an rtag_id, get details on all packages in the release
80
#
81
# Inputs          : rtag_id
82
#
83
# Returns         : 
84
#
85
 
86
sub getPkgDetailsByRTAG_ID
87
{
88
    my ($RTAG_ID) = @_;
89
    my $foundDetails = 0;
90
    my (@row);
91
 
92
    # if we are not or cannot connect then return 0 as we have not found anything
93
    connectRM(\$RM_DB) unless ( $RM_DB );
94
 
95
    # First get details from pv_id
96
 
97
    my $m_sqlstr = "SELECT pv.PV_ID, pkg.PKG_NAME, pv.PKG_VERSION, pv.PKG_LABEL, pv.SRC_PATH, pv.BUILD_TYPE" .
98
                    " FROM RELEASE_MANAGER.RELEASE_CONTENT rc, RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg" .
99
                    " WHERE rc.RTAG_ID = $RTAG_ID AND rc.PV_ID = pv.PV_ID AND pv.PKG_ID = pkg.PKG_ID";
100
    my $sth = $RM_DB->prepare($m_sqlstr);
101
    if ( defined($sth) )
102
    {
103
        if ( $sth->execute( ) )
104
        {
105
            if ( $sth->rows )
106
            {
107
                while ( @row = $sth->fetchrow_array )
108
                {
109
                    my %DATA;
110
                    my $pvid = $DATA{pv_id}  = $row[0];
111
                    my $name = $DATA{name}   = $row[1];
112
                    my $ver = $DATA{version} = $row[2];
113
                    my $label = $DATA{label} = $row[3] || '';
114
                    my $path = $DATA{path}   = $row[4] || '';
115
                    $path =~ tr~\\/~/~s;
116
#print "$row[5] --";
117
#printf ( "%40s %15s %50s %s\n",  $name, $ver, $label, $path);
118
 
119
                    $GDATA{$pvid} = (\%DATA);
120
                    my ( $pn, $pv, $pp ) = SplitPackage( $name, $ver );
121
                    $GINDEX{"$pn.$pp"} = $pvid;
122
                }
123
            }
124
            $sth->finish();
125
        }
126
        else
127
        {
128
            Error("Execute failure");
129
        }
130
    }
131
    else
132
    {
133
        Error("Prepare failure" );
134
    }
135
}
136
 
137
#-------------------------------------------------------------------------------
138
# Function        : GetDepends
139
#
140
# Description     : Given an pv_id
141
#
142
# Inputs          : pv_id
143
#                   pkg_name
144
#                   pkg_ver
145
#
146
# Returns         :
147
#
148
sub GetDepends_pvid
149
{
150
    my (@row);
151
    my ($pv_id, $name, $version) = @_;
152
 
153
    my ( $pn, $pv, $pp ) = SplitPackage( $name, $version );
154
    my $ukey = "$pn.$pp";
155
 
156
 
157
    $ReleasePackages{$name}{$version} = $ukey;
158
    $Packages{$ukey} = "$name.$version";
159
 
160
    # if we are not or cannot connect then return 0 as we have not found anything
161
    connectRM(\$RM_DB) unless ( $RM_DB );
162
 
163
    #   Now extract the package dependacies
164
    #
165
    my $m_sqlstr = "SELECT pkg.PKG_NAME, pv.PKG_VERSION, pd.DPV_ID" .
166
                   " FROM RELEASE_MANAGER.PACKAGE_DEPENDENCIES pd, RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg" .
167
                   " WHERE pd.PV_ID = \'$pv_id\' AND pd.DPV_ID = pv.PV_ID AND pv.PKG_ID = pkg.PKG_ID";
168
    my $sth = $RM_DB->prepare($m_sqlstr);
169
    if ( defined($sth) )
170
    {
171
        if ( $sth->execute( ) )
172
        {
173
            if ( $sth->rows )
174
            {
175
                while ( @row = $sth->fetchrow_array )
176
                {
177
#print ( "DATA: " . join(',', @row) . "\n");
178
                    my $dpv_id = $row[2];
179
                    my ( $pn, $pv, $pp ) = SplitPackage( $row[0], $row[1] );
180
 
181
                    my $key = "$pn.$pp";
182
                    my @data = ( $key, $dpv_id, $pn, "$pv.$pp" );
183
                    push @{$Depends{$ukey}}, \@data;
184
                    push @{$UsedBy{$key}}, $ukey;
185
 
186
#                    print  ' ' x 4, "$pn $pv $pp";
187
#                    if ( $rp ne $pv )
188
#                    {
189
#                        print "  ----- Package not in release. Needs $rp";
190
#                    }
191
#                    print "\n";
192
                }
193
            }
194
            $sth->finish();
195
        }
196
    }
197
    else
198
    {
199
        Error("GetDepends:Prepare failure" );
200
    }
201
}
202
 
203
#-------------------------------------------------------------------------------
204
# Function        : getPkgDetailsByName
205
#
206
# Description     : Determine the PVID for a given package name and version
207
#
208
# Inputs          : $pname          - Package name
209
#                   $pver           - Package Version
210
#
211
# Returns         : PV_ID
212
#
213
 
214
sub getPkgDetailsByName
215
{
216
    my ($pname, $pver) = @_;
217
    my $pv_id;
218
    my (@row);
219
 
220
    connectRM(\$RM_DB) unless ($RM_DB);
221
 
222
    # First get details for a given package version
223
 
224
    my $m_sqlstr = "SELECT pv.PV_ID, pkg.PKG_NAME, pv.PKG_VERSION" .
225
                    " FROM RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg" .
226
                    " WHERE pkg.PKG_NAME = \'$pname\' AND pv.PKG_VERSION = \'$pver\' AND pv.PKG_ID = pkg.PKG_ID";
227
    my $sth = $RM_DB->prepare($m_sqlstr);
228
    if ( defined($sth) )
229
    {
230
        if ( $sth->execute( ) )
231
        {
232
            if ( $sth->rows )
233
            {
234
                while ( @row = $sth->fetchrow_array )
235
                {
236
                    $pv_id = $row[0];
237
                    my $name = $row[1];
238
                    my $ver = $row[2];
239
                    Verbose( "getPkgDetailsByName :PV_ID= $pv_id");
240
                }
241
            }
242
            $sth->finish();
243
        }
244
    }
245
    else
246
    {
247
        Error("Prepare failure" );
248
    }
249
    return $pv_id;
250
}
251
 
252
 
253
#-------------------------------------------------------------------------------
254
# Function        : AddUsedBy
255
#
256
# Description     : 
257
#
258
# Inputs          : 
259
#
260
# Returns         : 
261
#
262
 
263
my %AllUsedBy;
264
sub AddUsedBy
265
{
266
    my ($ref) = @_;
267
    foreach my $entry ( @$ref )
268
    {
269
#print "Adding: $entry\n";
270
        if ( ! exists($AllUsedBy{$entry}) )
271
        {
272
#print "     New Adding: $entry\n";
273
            $AllUsedBy{$entry} = 1;
274
#DebugDumpData ("UsedBy", \$UsedBy{$entry} );
275
            AddUsedBy( $UsedBy{$entry} );
276
        }
277
    }
278
}
279
#-------------------------------------------------------------------------------
280
# Function        : Main
281
#
282
# Description     :
283
#
284
# Inputs          :
285
#
286
# Returns         :
287
#
288
 
289
ErrorConfig( 'name'    =>'ExtractUses',
290
             'verbose' => $opt_verbose );
291
 
292
#
293
#
294
#
295
unless ( $opt_rtagid )
296
{
297
    Error ("Must supply -rtag_id, Try -rtag_id=16243");
298
}
299
 
300
#
301
#   Determine root package
302
#
303
unless ( $ARGV[0] && $ARGV[1] )
304
{
305
    print "Specify a package as 'name' 'version'\n";
306
    exit;
307
}
308
$PNAME = $ARGV[0];
309
$PVER = $ARGV[1];
310
 
311
#getPkgDetailsByRTAG_ID(2301);           # 2301 : Seattle I7
312
#getPkgDetailsByRTAG_ID(2362);           # 2362 : Syd Release 1
313
#getPkgDetailsByRTAG_ID(1861);           # 1861 : Syd Release Legacy
314
#getPkgDetailsByRTAG_ID(3462);           # 3462 : Beijing Release 1
315
#getPkgDetailsByRTAG_ID(5162);           # 5162 : NZS TP5600
316
#getPkgDetailsByRTAG_ID(16243);          # 16243 : VTK
317
getPkgDetailsByRTAG_ID($opt_rtagid);
318
 
319
#DebugDumpData("GDATA", \%GDATA);
320
 
321
foreach my $pv_id ( keys %GDATA )
322
{
323
    my $pkg = \%{$GDATA{$pv_id}};
324
#    print "Processing: $pkg->{'name'}\n";
325
    GetDepends_pvid( $pv_id, $pkg->{'name'}, $pkg->{'version'} );
326
}
327
 
328
#DebugDumpData ("BuildPackages", \%BuildPackages );
329
#DebugDumpData ("ReleasePackages", \%ReleasePackages );
330
#DebugDumpData ("Depends", \%Depends );
331
#DebugDumpData ("UsedBy", \%UsedBy );
332
 
333
while ( $#ARGV >= 1 )
334
{
335
    #DebugDumpData( "START", \$ReleasePackages{$ARGV[0] });
336
    my $pv_id = $ReleasePackages{$ARGV[0]}{$ARGV[1]};
337
    Error ("Package not found: $ARGV[0] $ARGV[1]") unless ( $pv_id );
338
    #DebugDumpData ("UsedBy:$pv_id", \$UsedBy{$pv_id} ); exit(1);
339
 
340
    push @ROOT_PVIDS, $pv_id;
341
    $AllUsedBy{$pv_id} = 1;
342
    AddUsedBy( $UsedBy{$pv_id} );
343
 
344
    shift @ARGV;
345
    shift @ARGV;
346
}
347
 
348
if ( $#ARGV >= 0 )
349
{
350
    Error("Args shoud be name-version pairs. Appears to be a one short");
351
}
352
 
353
 
354
#DebugDumpData ("AllUsedBy", \%AllUsedBy );
355
 
356
 
357
my $filebase = "${PNAME}_${PVER}_usedby";
358
open (FH, ">$filebase.dot" ) or die "Cannot open output";
359
print FH "digraph world {\n";
360
print FH "\trankdir=LR;\n";
361
print FH "\tnode[fontsize=24];\n";
362
print FH "\t{rank=min; ", pentry(@ROOT_PVIDS) , "; }\n";
363
print FH "\t{root=", pentry($ROOT_PVIDS[0]), "; }\n";
364
 
365
 
366
foreach my $entry ( sort keys(%AllUsedBy) )
367
{
368
    my $ref = $UsedBy{$entry};
369
    print FH "\t", pentry($entry)  ," -> { ", plist ( ' ; ', @{$ref} ), " }\n";
370
}
371
 
372
 
373
print FH "\n};\n";
374
close FH;
375
 
376
#
377
#   Convert DOT to a SVG
378
#
379
system( "dot $filebase.dot -Tjpg -o$filebase.jpg" );
380
system( "dot $filebase.dot -Tsvg -o$filebase.svg" );
381
 
382
print "Generated: $filebase.dot\n";
383
print "Generated: $filebase.jpg\n";
384
print "Generated: $filebase.svg\n";
385
 
386
 
387
#
388
#   Complete used-by tree
389
#
390
##foreach my $entry ( keys(%AllUsedBy) )
391
##{
392
##     my $pvid = $GINDEX{$entry};
393
###     print "$entry, $pvid\n";
394
##    my $pkg = \%{$GDATA{$pvid}};
395
##
396
##    my $label = $pkg->{label};
397
##    my $path = $pkg->{path};
398
##    $path =~ tr~\\/~/~s;
399
###    printf ( "%40s %15s %50s %s\n",  $pkg->{name}, $pkg->{version}, $pkg->{label}, $path);
400
##    print ( "jats extract $label -path=$path\n");
401
##
402
##}
403
 
404
if ( $opt_show_extract )
405
{
406
    my @entries;
407
    #
408
    #   Directly used by
409
    #
410
    #DebugDumpData ("UsedBy:$pv_id", \$UsedBy{$pv_id} ); exit(1);
411
 
412
    if ( $opt_show_extract > 1 )
413
    {
414
        @entries = keys(%AllUsedBy)
415
    }
416
    else
417
    {
418
        my %directly_used;
419
        foreach my $pv_id ( @ROOT_PVIDS )
420
        {
421
            foreach my $entry ( @{$UsedBy{$pv_id}} )
422
            {
423
                $directly_used{$entry} = 1;
424
            }
425
        }
426
        @entries = keys (%directly_used);
427
    }
428
 
429
    foreach my $entry ( @entries )
430
    {
431
         my $pvid = $GINDEX{$entry};
432
    #     print "$entry, $pvid\n";
433
        my $pkg = \%{$GDATA{$pvid}};
434
 
435
        my $label = $pkg->{label};
436
        my $path = $pkg->{path};
437
        $path =~ tr~\\/~/~s;
438
    #    printf ( "%40s %15s %50s %s\n",  $pkg->{name}, $pkg->{version}, $pkg->{label}, $path);
439
        print ( "jats extract $label -path=$path\n");
440
    }
441
}
442
 
443
exit;
444
 
445
 
446
#-------------------------------------------------------------------------------
447
# Function        : plist
448
#
449
# Description     : Generate an entry list as text
450
#                   Replace "." with "_" since DOT doesn't like .'s
451
#                   Seperate the arguments
452
#
453
# Inputs          : $pref       - Prefix string
454
#                   @_          - An array of entries to process
455
#
456
# Returns         : A string
457
#
458
sub plist
459
{
460
    my $pref = shift;
461
    my $result = "";
462
    foreach  ( @_ )
463
    {
464
        my $x = $_;
465
        $x =~ s~\.~_~g;
466
        $result .= '"' . $x . '"' . $pref;
467
    }
468
    return $result;
469
}
470
 
471
sub pentry
472
{
473
 
474
    my $result = "";
475
    foreach  ( @_ )
476
    {
477
        my $x = $_;
478
        $x =~ s~\.~_~g;
479
        $result .= '"' . $x . '"'
480
    }
481
    return $result;
482
}
483
 
484
#-------------------------------------------------------------------------------
485
#   Documentation
486
#
487
 
488
=pod
489
 
490
=head1 NAME
491
 
492
jats etool extract_uses - Graph build dependencies
493
 
494
=head1 SYNOPSIS
495
 
496
  jats etool extract_uses [options] PackageName/Version Pairs
497
 
498
 Options:
499
    -help               - brief help message
500
    -help -help         - Detailed help message
501
    -man                - Full documentation
502
    -verbose            - Verbose operation
503
    -rtag=nnn           - Release Tag
504
    -show               - Show 'jats extract' commands
505
 
506
=head1 OPTIONS
507
 
508
=over 8
509
 
510
=item B<-help>
511
 
512
Print a brief help message and exits.
513
 
514
=item B<-help -help>
515
 
516
Print a detailed help message with an explanation for each option.
517
 
518
=item B<-man>
519
 
520
Prints the manual page and exits.
521
 
522
=item B<-verbose>
523
 
524
Increases program output. This option may be specified multiple times
525
 
526
 
527
This option specifies the Release, within the Release Manager Database, that will
528
be used to update the build dependency file.
529
 
530
The Release Tag is provided by the Release Manager Web Page, or by the -Show option
531
of this utility.
532
 
533
=back
534
 
535
=head1 DESCRIPTION
536
 
537
This utilty will display the dependency tree for packages used by the specified
538
packages.
539
 
540
=cut
541