Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
227 dpurdie 1
########################################################################
7300 dpurdie 2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
227 dpurdie 3
#
263 dpurdie 4
# Module name   : jats_sandbox.pl
5
# Module type   : JATS Utility
6
# Compiler(s)   : Perl
7
# Environment(s): JATS
227 dpurdie 8
#
9
# Description   : A script to build a collection of packages in the
10
#                 same sandbox. This script will:
11
#
12
#                   Determine the packages in the sandbox
13
#                   Determine the build order of the packages
14
#                   Build the packages in the correct order
15
#                   Make the packages in the correct order
16
#
17
#                 The script will allow for:
18
#                   The creation of a sandbox
19
#                   The addition of packages to the sandbox
20
#                   Removal of packages from the sandbox
21
#
22
#
23
#                 Command syntax (basic)
24
#                   jats sandbox <command> (options | actions)@
25
#
26
#                 Commands include:
27
#                   create              - Create a sandbox
28
#                   delete              - Delete a sandbox
337 dpurdie 29
#                   info                - Show sandbox info
227 dpurdie 30
#
31
#                   build               - Build all packages in the sandbox
32
#                   make                - make all packages in the sandbox
33
#
34
#......................................................................#
35
 
263 dpurdie 36
require 5.008_002;
227 dpurdie 37
use strict;
38
use warnings;
39
use JatsError;
40
use JatsSystem;
41
use FileUtils;
245 dpurdie 42
use JatsBuildFiles;
227 dpurdie 43
use JatsVersionUtils;
4197 dpurdie 44
use ArrayHashUtils;
6133 dpurdie 45
use ToolsetFiles;
7320 dpurdie 46
use ReadBuildConfig;
227 dpurdie 47
 
48
use Pod::Usage;                             # required for help support
49
use Getopt::Long qw(:config require_order); # Stop on non-option
6133 dpurdie 50
use Digest;
7319 dpurdie 51
use JSON;
6133 dpurdie 52
 
227 dpurdie 53
my $VERSION = "1.0.0";                      # Update this
7306 dpurdie 54
my $SCANDEPTH = 3;                          # Almost a constant
227 dpurdie 55
 
56
#
57
#   Options
58
#
59
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
60
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
359 dpurdie 61
my $opt_help = 0;                           # Help level
1329 dpurdie 62
my $opt_toPackage;                          # Control recursion
63
my $opt_fromPackage;                        # Control recursion
64
my @opt_justPackage;                        # Control recursion
65
my @opt_ignorePackage;                      # Control recursion
6133 dpurdie 66
my $opt_allSandbox;                         # Extend scope to entire sandbox
67
my $opt_processUsedBy;                      # Process dependants(consumers) not dependents(children)
68
my $opt_keepgoing;                          # Ignore errors
69
my $opt_reScan;                             # Rescan for buildfiles
7307 dpurdie 70
my $opt_multiBuilders = 0;                  # How handle packages with multiple bulders: 0:Error, 1:Report, 2:Ignore
7319 dpurdie 71
my $opt_onlyLevel = 0;                      # Single level processing
227 dpurdie 72
 
73
#
74
#   Globals - Provided by the JATS environment
75
#
4688 dpurdie 76
my $USER            = $ENV{'USER'};
77
my $UNIX            = $ENV{'GBE_UNIX'};
78
my $HOME            = $ENV{'HOME'};
7320 dpurdie 79
my $GBE_ABT         = $ENV{'GBE_ABT'};
4688 dpurdie 80
my $GBE_SANDBOX     = $ENV{'GBE_SANDBOX'};
81
my $GBE_DPKG_SBOX   = $ENV{'GBE_DPKG_SBOX'};
82
my $GBE_MACHTYPE    = $ENV{'GBE_MACHTYPE'};
3559 dpurdie 83
my $GBE_BUILDFILTER = $ENV{'GBE_BUILDFILTER'};
335 dpurdie 84
 
4688 dpurdie 85
my $GBE_DPKG_LOCAL      = $ENV{'GBE_DPKG_LOCAL'};
86
my $GBE_DPKG_CACHE      = $ENV{'GBE_DPKG_CACHE'};
87
my $GBE_DPKG            = $ENV{'GBE_DPKG'};
88
my $GBE_DPLY            = $ENV{'GBE_DPLY'};
89
my $GBE_DPKG_STORE      = $ENV{'GBE_DPKG_STORE'};
90
my $GBE_DPKG_REPLICA    = $ENV{'GBE_DPKG_REPLICA'};
7319 dpurdie 91
my $GBE_DPKG_ESCROW     = $ENV{'GBE_DPKG_ESCROW'};
4688 dpurdie 92
 
227 dpurdie 93
#
94
#   Globals
95
#
7306 dpurdie 96
my @stopped = ();                               # Stopped entries
7323 dpurdie 97
my @build_order = ();                           # Build Ordered list of entries
98
my %extern_deps;                                # Hash of external dependencies
7319 dpurdie 99
my %packages;                                   # Hash of packages
7451 dpurdie 100
my $currentPkgTag;                              # Tag of the current package - if any
7306 dpurdie 101
my $scanDepth;                                  # Depth for build file scan
7307 dpurdie 102
my $maxDname = 0;                               # Pretty display
227 dpurdie 103
 
7306 dpurdie 104
#
105
#   Known files
106
#
7319 dpurdie 107
$GBE_DPKG_SBOX = '' unless defined $GBE_DPKG_SBOX;
7306 dpurdie 108
my $cacheFile  = $GBE_DPKG_SBOX . '/location_cache';
109
my $depthFile  = $GBE_DPKG_SBOX . '/scanDepth';
7307 dpurdie 110
my $filterFile = $GBE_DPKG_SBOX . '/buildfilter';
7306 dpurdie 111
 
227 dpurdie 112
#-------------------------------------------------------------------------------
113
# Function        : Mainline Entry Point
114
#
115
# Description     :
116
#
117
# Inputs          :
118
#
119
 
120
#
121
#   Process help and manual options
122
#
1329 dpurdie 123
my $result = getOptionsFromArray ( \@ARGV );
227 dpurdie 124
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
125
pod2usage(-verbose => 1)  if ($opt_help == 2 );
299 dpurdie 126
pod2usage(-verbose => 2)  if ($opt_help > 2 );
227 dpurdie 127
 
128
#
129
#   Configure the error reporting process now that we have the user options
130
#
131
ErrorConfig( 'name'    => 'SANDBOX',
132
             'verbose' => $opt_verbose );
7320 dpurdie 133
InitFileUtils();
227 dpurdie 134
 
135
#
359 dpurdie 136
#   Reconfigure the options parser to allow subcommands to parse options
227 dpurdie 137
#
359 dpurdie 138
Getopt::Long::Configure('permute');
227 dpurdie 139
 
7323 dpurdie 140
#   Flag to subcommands that the build is occuring within a SANDBOX
141
#   Example usage: Prevent gradle subproject inclusion
142
$ENV{'GBE_SANDBOX_BUILD'} = 1;
143
 
227 dpurdie 144
#
145
#   Parse the user command and decide what to do
146
#
359 dpurdie 147
#   Remove user command from the command line. This will leave command options
148
#   in @ARGV so that they can be parsed by the subcommand.
227 dpurdie 149
#
150
my $cmd = shift @ARGV || "";
151
help(1)                                 if ( $cmd =~ m/^help$/ || $cmd eq "" );
359 dpurdie 152
buildcmd($cmd, @ARGV )                  if ( $cmd =~ m/(^all$)|(^build$)/  );
153
cache(@ARGV)                            if ( $cmd =~ m/^cache$/  );
154
clean($cmd, @ARGV)                      if ( $cmd =~ m/(^clobber$)|(^clean$)/  );
155
cmd('make', $cmd, @ARGV )               if ( $cmd =~ m/(^make$)/  );
156
cmd('cmd', @ARGV)                       if ( $cmd =~ m/^cmd$/ );
157
create_sandbox()                        if ( $cmd =~ m/^create$/ );
299 dpurdie 158
delete_sandbox()                        if ( $cmd =~ m/^delete$/ );
227 dpurdie 159
info(@ARGV)                             if ( $cmd =~ m/^info$/ );
359 dpurdie 160
populate(@ARGV)                         if ( $cmd =~ m/^populate$/  );
4197 dpurdie 161
buildfilter(@ARGV)                      if ( $cmd =~ m/^buildfilter$/  );
6133 dpurdie 162
skipBuild(0, @ARGV)                     if ( $cmd =~ m/^skip$/  );
163
skipBuild(1, @ARGV)                     if ( $cmd =~ m/^unskip$/  );
7319 dpurdie 164
errorBuild(0, @ARGV)                    if ( $cmd =~ m/^error$/  );
165
errorBuild(1, @ARGV)                    if ( $cmd =~ m/^unerror$/  );
6133 dpurdie 166
fingerPrintPkg(@ARGV)                   if ( $cmd =~ m/^finger/i );
7304 dpurdie 167
testLinks(@ARGV)                        if ( $cmd =~ m/^testlinks/i );
7306 dpurdie 168
setScanDepth(@ARGV)                     if ( $cmd =~ m/^scandepth/i );
7319 dpurdie 169
writeBuildData(@ARGV)                   if ( $cmd =~ m/^writeBuildData/i );
7320 dpurdie 170
generatepkgSignatures(@ARGV)            if ( $cmd =~ m/^genPkgSigs/i );
171
setAbtMarker(@ARGV)                     if ( $cmd =~ m/^setAbtMarker/i );
227 dpurdie 172
 
173
Error ("Unknown sandbox command: $cmd");
174
exit 1;
175
 
176
 
177
#-------------------------------------------------------------------------------
178
#
179
#   Give the user a clue
180
#
181
sub help
182
{
183
    my ($level) = @_;
184
    $level = $opt_help unless ( $level );
185
 
186
    pod2usage(-verbose => 0, -message => "Version: ". $VERSION)  if ($level == 1 );
187
    pod2usage(-verbose => $level -1 );
188
}
189
 
190
#-------------------------------------------------------------------------------
191
# Function        : create_sandbox
192
#
193
# Description     : create a sandbox in the current current directory
194
#
195
# Inputs          : None
196
#
197
#
198
sub create_sandbox
199
{
7322 dpurdie 200
    my  $opt_force;
359 dpurdie 201
    GetOptions (
202
                "help:+"        => \$opt_help,
203
                "manual:3"      => \$opt_help,
7322 dpurdie 204
                "force!"        => \$opt_force,
359 dpurdie 205
                ) || Error ("Invalid command line" );
206
 
207
    SubCommandHelp( $opt_help, "Create Sandbox") if ($opt_help || $#ARGV >= 0 );
208
 
227 dpurdie 209
    Error ("Cannot create a sandbox within a sandbox",
7322 dpurdie 210
           "Sandbox base is: $GBE_SANDBOX" ) if ( $GBE_SANDBOX && !$opt_force );
359 dpurdie 211
 
227 dpurdie 212
    mkdir ('sandbox_dpkg_archive') || Error ("Cannot create the directory: sandbox_dpkg_archive") ;
359 dpurdie 213
 
7301 dpurdie 214
    Message ('Sandbox created');
227 dpurdie 215
    exit  0;
216
}
217
 
218
#-------------------------------------------------------------------------------
299 dpurdie 219
# Function        : delete_sandbox
220
#
221
# Description     : Delete a sandbox
222
#                   Its up to the user the delete the components in the sandbox
223
#
224
# Inputs          : None
225
#
361 dpurdie 226
# Returns         :
299 dpurdie 227
#
228
sub delete_sandbox
229
{
359 dpurdie 230
    GetOptions (
231
                "help:+"        => \$opt_help,
232
                "manual:3"      => \$opt_help,
233
                ) || Error ("Invalid command line" );
234
 
235
    SubCommandHelp( $opt_help, "Delete Sandbox") if ($opt_help || $#ARGV >= 0 );
236
 
299 dpurdie 237
    unless ( $GBE_SANDBOX )
238
    {
239
        Warning("No sandbox found to delete");
240
    }
241
    else
242
    {
365 dpurdie 243
        Error ("Sandbox directory not completely removed")
361 dpurdie 244
            if RmDirTree( "$GBE_SANDBOX/sandbox_dpkg_archive" );
299 dpurdie 245
 
246
        Message("Sandbox information deleted",
247
                "Sandbox components must be manually deleted");
248
    }
249
    exit 0;
250
}
251
 
252
#-------------------------------------------------------------------------------
6133 dpurdie 253
# Function        : skipBuild 
254
#
255
# Description     : Mark the building of a package for skipping
256
#
257
# Inputs          : Mode -: Skip, 1:Unskip
258
#                   User commaand line 
259
#
260
# Returns         : Nothing
261
#
262
sub skipBuild
263
{
264
    my ($mode, @cmd_opts ) = @_;
265
    my $machine;
266
 
267
    Getopt::Long::Configure('pass_through');
268
    getOptionsFromArray ( \@cmd_opts,
269
                        'machine!' => \$machine,
270
                        ) || Error ("Invalid command line" );
271
 
272
    SubCommandHelp( $opt_help, "Skip Build") if ($opt_help );
273
    Error ("Command must be executed from within a Sandbox") unless ( $GBE_SANDBOX );
274
 
275
    #
276
    #   Determine Sandbox information
277
    #   Populate global variables
278
    #
279
    calc_sandbox_info(1);
280
 
281
    #
282
    #   Display only
283
    #   
284
    unless( @cmd_opts)
285
    {
286
        foreach my $pkg (keys %packages)
287
        {
288
            my $fe = $packages{$pkg};
289
            next unless $fe->{buildSkip};
290
 
291
            my $skipMsg = ($fe->{buildSkip}) ? ' (Build Skipped)' : ' (Build Suppressed)';
292
            if ($fe->{buildCurrent}) {
293
                $skipMsg .= ' (Current Package)';
294
            }
295
 
296
            Message( ' Name: ' . $fe->{dname} . $skipMsg );
297
 
298
        }
299
        exit 0;
300
    }
301
 
302
    foreach ( @cmd_opts )
303
    {
304
        #
305
        #   Locate the package
306
        #
307
        my $pe;
308
        if ($currentPkgTag && ($_ eq '.'))
309
        {
310
            if (exists $packages{$currentPkgTag})
311
            {
312
                $pe = $packages{$currentPkgTag}; 
313
            }
314
        }
315
        unless ($pe) {
316
            foreach my $pkg (keys %packages)
317
            {
318
                my $entry = $packages{$pkg};
319
                if ($entry->{dname} eq $_ || $entry->{fname} eq $_ )
320
                {
321
                    $pe = $entry;
322
                    last;
323
                }
324
            }
325
        }
326
 
327
        unless ($pe) {
328
            Warning("No package found matching: $_");
329
            next;
330
        }
331
 
332
        my $skipFile;
333
        if ($machine) {
334
            $skipFile = catdir($GBE_SANDBOX, 'sandbox_dpkg_archive', '_skip.' . $GBE_MACHTYPE . '.' . $pe->{dname});
335
        } else {
336
            $skipFile = catdir($GBE_SANDBOX, 'sandbox_dpkg_archive', '_skip.'. $pe->{dname});
337
        }
338
        Verbose("SkipFile: $skipFile");
339
        if ($mode)
340
        {
341
            unlink $skipFile;
342
        }
343
        else
344
        {
345
            TouchFile($skipFile);
346
        }
347
    }
348
    exit 0;
349
}
350
 
351
#-------------------------------------------------------------------------------
7319 dpurdie 352
# Function        : errorBuild 
353
#
354
# Description     : Mark the package as having a build error
7323 dpurdie 355
#                   This information will be used in determining build info
7319 dpurdie 356
#
357
# Inputs          : Mode -: Error, 1:UnError
358
#                   User commaand line 
359
#
360
# Returns         : Nothing
361
#
362
sub errorBuild
363
{
364
    my ($mode, @cmd_opts ) = @_;
365
    my $machine;
7320 dpurdie 366
    my $opt_removeAll;
7319 dpurdie 367
 
368
    Getopt::Long::Configure('pass_through');
369
    getOptionsFromArray ( \@cmd_opts,
7320 dpurdie 370
                          'machine!' => \$machine,
371
                          'removeAll!' => \$opt_removeAll,
7319 dpurdie 372
                        ) || Error ("Invalid command line" );
373
 
374
    SubCommandHelp( $opt_help, "Error Build") if ($opt_help );
375
    Error ("Command must be executed from within a Sandbox") unless ( $GBE_SANDBOX );
376
 
377
    #
7320 dpurdie 378
    #   Remove all - applies to error and unerror
379
    #
380
    if ($opt_removeAll) {
381
        my @deleteList = glob (CatPaths($GBE_SANDBOX, 'sandbox_dpkg_archive', '_error.*'));
382
        foreach my $file (@deleteList)
383
        {
384
            Message ("UnError: $file");
385
            unlink $file;
386
        }
387
    }
388
 
389
    #
7319 dpurdie 390
    #   Determine Sandbox information
391
    #   Populate global variables
392
    #
393
    calc_sandbox_info(1);
394
 
395
    #
396
    #   Display only
397
    #   
7320 dpurdie 398
    unless( @cmd_opts )
7319 dpurdie 399
    {
400
        foreach my $pkg (keys %packages)
401
        {
402
            my $fe = $packages{$pkg};
403
            next unless $fe->{buildError};
404
 
405
            my $errMsg = ' (Build Error)';
406
            if ($fe->{buildCurrent}) {
407
                $errMsg .= ' (Current Package)';
408
            }
409
 
410
            Message( ' Name: ' . $fe->{dname} . $errMsg );
411
 
412
        }
413
        exit 0;
414
    }
415
 
416
    foreach ( @cmd_opts )
417
    {
418
        #
419
        #   Locate the package
420
        #
421
        my $pe;
422
        if ($currentPkgTag && ($_ eq '.'))
423
        {
424
            if (exists $packages{$currentPkgTag})
425
            {
426
                $pe = $packages{$currentPkgTag}; 
427
            }
428
        }
429
        unless ($pe) {
430
            foreach my $pkg (keys %packages)
431
            {
432
                my $entry = $packages{$pkg};
433
                if ($entry->{dname} eq $_ || $entry->{fname} eq $_ )
434
                {
435
                    $pe = $entry;
436
                    last;
437
                }
438
            }
439
        }
440
 
441
        unless ($pe) {
442
            Warning("No package found matching: $_");
443
            next;
444
        }
445
 
446
        my $errorFile;
447
        if ($machine) {
448
            $errorFile = catdir($GBE_SANDBOX, 'sandbox_dpkg_archive', '_error.' . $GBE_MACHTYPE . '.' . $pe->{dname});
449
        } else {
450
            $errorFile = catdir($GBE_SANDBOX, 'sandbox_dpkg_archive', '_error.'. $pe->{dname});
451
        }
452
        Verbose("ErrorFile: $errorFile");
453
        if ($mode)
454
        {
455
            unlink $errorFile;
456
        }
457
        else
458
        {
459
            TouchFile($errorFile);
460
        }
461
    }
462
    exit 0;
463
}
464
 
465
#-------------------------------------------------------------------------------
227 dpurdie 466
# Function        : info
467
#
468
# Description     : Display Sandbox information
469
#
470
# Inputs          : Command line args
471
#                   -v  - Be more verbose
472
#
473
# Returns         : Will exit
474
#
475
sub info
476
{
1329 dpurdie 477
    my (@cmd_opts ) = @_;
478
    my $show = 0;
6133 dpurdie 479
    my $showUsage = 0;
480
    my $showFingerPrint = 0;
7306 dpurdie 481
    my $showDependencies = 1;
482
    my $showOrder = 1;
7307 dpurdie 483
    my $showPath = 0;
227 dpurdie 484
 
1329 dpurdie 485
    Getopt::Long::Configure('pass_through');
486
    getOptionsFromArray ( \@cmd_opts,
7306 dpurdie 487
                          'verbose:+'       => \$show,
488
                          'usedby'          => \$showUsage,
489
                          'fingerprint!'    => \$showFingerPrint,
490
                          'dependencies!'   => \$showDependencies,
491
                          'buildorder!'     => \$showOrder,
7307 dpurdie 492
                          'path!'           => \$showPath,
1329 dpurdie 493
                        ) || Error ("Invalid command line" );
494
    SubCommandHelp( $opt_help, "Sandbox Information") if ($opt_help || $#cmd_opts >=0 );
6133 dpurdie 495
    $showUsage = 1 if ($show >= 2);
361 dpurdie 496
 
227 dpurdie 497
    #
498
    #   Determine Sandbox information
499
    #   Populate global variables
500
    #
6133 dpurdie 501
    calc_sandbox_info();
227 dpurdie 502
 
503
    #
504
    #   Display information
505
    #
6133 dpurdie 506
    Message ("Scope      : " . ($opt_allSandbox ? 'Entire Sandbox' : $packages{$currentPkgTag}{dname} ));
3559 dpurdie 507
    Message ("Base       : $GBE_SANDBOX");
508
    Message ("Archive    : $GBE_DPKG_SBOX");
7306 dpurdie 509
    Message ("BuildFilter: $GBE_BUILDFILTER" . ( (-f $filterFile)  ? ' - Local to sandbox' : ''));
7320 dpurdie 510
    Message ("Type       : Auto Build Tool" ) if (defined $GBE_ABT);
227 dpurdie 511
 
7306 dpurdie 512
    if ($showOrder)
1329 dpurdie 513
    {
7306 dpurdie 514
        Message ("Build Order");
7307 dpurdie 515
        foreach my $pname ( @stopped ) {
7319 dpurdie 516
            Message( "    Level:" . "--"  . " [----] Name: " . $pname . ' (Stopped)');
7306 dpurdie 517
        }
7307 dpurdie 518
 
7306 dpurdie 519
        foreach my $fe ( @build_order )
520
        {
7307 dpurdie 521
            displayHeader($fe, { indent => '    ', testFingerPrint =>  $showFingerPrint, showSimplePath => $showPath });
227 dpurdie 522
 
7306 dpurdie 523
            if ( $show )
227 dpurdie 524
            {
7306 dpurdie 525
                Message( DisplayPath ("        Path: $fe->{dir}" ));
526
                foreach my $idep ( sort values %{$fe->{'ideps'}} )
527
                {
528
                    Message ("        I:$idep");
529
                }
227 dpurdie 530
 
7306 dpurdie 531
                foreach my $edep ( sort keys %{$fe->{'edeps'}} )
532
                {
533
                    my ($ppn,$ppv) = split( $; , $edep);
534
                    Message ("        E:$ppn $ppv");
535
                }
227 dpurdie 536
            }
361 dpurdie 537
 
7306 dpurdie 538
            if ($showUsage && exists($fe->{'usedBy'}))
6133 dpurdie 539
            {
7306 dpurdie 540
                foreach my $edep ( sort {uc($a) cmp uc($b)} @{$fe->{'usedBy'}} )
541
                {
542
                    Message ("        U:$packages{$edep}{dname}");
543
                }
6133 dpurdie 544
            }
227 dpurdie 545
        }
546
    }
547
 
359 dpurdie 548
    #
549
    #   External dependencies flags
550
    #       * - Package does not exist in dpkg_archive
551
    #       + - Multiple versions of this package are used
552
 
7306 dpurdie 553
    if ($showDependencies)
227 dpurdie 554
    {
7306 dpurdie 555
        Message("External Dependencies");
556
        foreach my $de ( sort {uc($a) cmp uc($b)} keys %extern_deps )
227 dpurdie 557
        {
7306 dpurdie 558
            my @vlist = keys %{$extern_deps{$de}};
559
            my $flag = $#vlist ? '+' : '';
560
            foreach my $pve ( sort {uc($a) cmp uc($b)} @vlist )
227 dpurdie 561
            {
7306 dpurdie 562
                my ($pn,$pv) = split( $; , $pve );
563
                my $exists = check_package_existance($pn,$pv  ) ? '' : '*';
564
                my $flags = sprintf ("%4.4s", $flag . $exists);
565
                Message ("${flags}${pn} ${pv}");
566
                if ( $show || $showUsage )
227 dpurdie 567
                {
7306 dpurdie 568
                    foreach my $pkg ( sort {uc($a) cmp uc($b)} @{$extern_deps{$de}{$pve}} )
569
                    {
570
                        my $ppn = join ('.', split( $; , $pkg));
571
                        Message ("        U:$ppn");
572
                    }
227 dpurdie 573
                }
7306 dpurdie 574
 
227 dpurdie 575
            }
576
        }
577
    }
578
 
1329 dpurdie 579
    if ( $show > 2 || $opt_verbose > 2 )
227 dpurdie 580
    {
581
        DebugDumpData( "extern_deps", \%extern_deps);
582
        DebugDumpData( "build_order", \@build_order);
583
        DebugDumpData( "packages", \%packages);
584
    }
585
    exit (0);
586
}
587
 
588
#-------------------------------------------------------------------------------
6133 dpurdie 589
# Function        : fingerPrintPkg 
590
#
591
# Description     : Various finger print operations on the current package
592
#
593
# Inputs          : @ARGV   - Arguments
594
#
595
# Returns         : WIll not return
596
#
597
sub fingerPrintPkg
598
{
599
    my ( @cmd_opts ) = @_;
600
    my $opt_generate;
601
    my $opt_delete;
602
 
603
    Getopt::Long::Configure('pass_through');
604
    getOptionsFromArray ( \@cmd_opts,
605
                          'generate!' => \$opt_generate,
606
                          'delete!'   => \$opt_delete,
607
                        ) || Error ("Invalid command line" );
608
 
609
    SubCommandHelp( $opt_help, "Sandbox Finger Print") if ($opt_help );
610
    Error ("Command must be executed from within a Sandbox") unless ( $GBE_SANDBOX );
611
 
612
    #
613
    #   Determine Sandbox information
614
    #   Populate global variables
615
    #
616
    calc_sandbox_info(1);
617
 
618
    #
619
    #   Determine the named packages, or use the current package
620
    #
621
    my @pkgList;
622
    if (@cmd_opts)
623
    {
624
        @pkgList = @cmd_opts;
625
    }
626
    else
627
    {
628
        if ( $currentPkgTag )
629
        {
630
            if (exists $packages{$currentPkgTag})
631
            {
632
                push @pkgList, $packages{$currentPkgTag}{fname};
633
            }
634
        }
635
    }
636
    Error ("Command must be used within a package, or with named packages.") 
637
        unless @pkgList;
638
 
639
 
640
    #
641
    #   Process all required packages
642
    #
643
    foreach my $pkgName ( @pkgList)
644
    {
645
        #
646
        #   Locate the package
647
        #
648
        my $pe;
649
        foreach my $pkg (keys %packages)
650
        {
651
            my $entry = $packages{$pkg};
652
            if ($entry->{dname} eq $pkgName || $entry->{fname} eq $pkgName )
653
            {
654
                $pe = $entry;
655
                last;
656
            }
657
        }
658
 
659
        unless ( $pe ) {
660
            Warning ("Cannot locate package: $pkgName");
661
            next;
662
        }
663
 
664
        #
665
        #   Recalculate finger print
666
        #
667
        my $tagFile = getPkgFingerPrintFile($pe);
668
        if ($opt_generate)
669
        {
670
            my $ifaceDir = getpkgInterface($pe);
671
            if ($ifaceDir)
672
            {
673
                Message ("Generate Fingerprint");
7307 dpurdie 674
                Verbose ("Fingerprint file: $tagFile");
6133 dpurdie 675
                FileCreate( $tagFile, genPkgFingerPrint($pe,'Generation') );
676
            }
677
            else
678
            {
679
                Warning("Package has not been built. Cannot generate fingerprint: $pkgName");
680
            }
681
        }
682
        elsif ($opt_delete)
683
        {
684
            unlink $tagFile;
685
            Message ("Fingerprint file removed");
686
        }
687
        else
688
        {
689
            #
690
            #   Test the finger print on the current package
691
            #
692
            if ( -e $tagFile )
693
            {
694
                if ( TagFileMatch($tagFile, genPkgFingerPrint($pe, 'Test')) )
695
                {
696
                    Message ("Fingerprint match");
697
                }
698
                else
699
                {
700
                    Message("Fingerprint missmatch");
701
                }
702
            }
703
            else
704
            {
705
                Message ("Package does not have a fingerprint file");
706
            }
707
        }
708
    }
709
 
710
    exit (0);
711
}
712
 
7304 dpurdie 713
#-------------------------------------------------------------------------------
714
# Function        : testLinks 
715
#
716
# Description     : Test the lnk files in the sandbox directory
717
#                   These may be stake after packages are deleted
718
#
719
# Inputs          : 
720
#
7306 dpurdie 721
# Returns         : This function will not return
7304 dpurdie 722
#
723
sub testLinks
724
{
725
    my ( @cmd_opts ) = @_;
726
    my $opt_delete;
6133 dpurdie 727
 
7304 dpurdie 728
    GetOptions (
729
                "help:+"        => \$opt_help,
730
                "manual:3"      => \$opt_help,
731
                'delete!'       => \$opt_delete,
732
                ) || Error ("Invalid command line" );
733
 
7306 dpurdie 734
    SubCommandHelp( $opt_help, "Sandbox Test Links") if ($opt_help || ($#ARGV >= 0) );
7304 dpurdie 735
    Error ("Command must be executed from within a Sandbox") unless ( $GBE_SANDBOX );
736
 
737
    #
738
    #   Process all packages in the sandbox
739
    #
740
    foreach my $linkFile ( glob "$GBE_DPKG_SBOX/*/*.lnk")
741
    {
7319 dpurdie 742
        my $pkg = getPackageLink( TagFileRead($linkFile) );
7304 dpurdie 743
        unless ( -d $pkg )
744
        {
745
            if ($opt_delete)
746
            {
747
                Message ("Delete: $linkFile");
748
                unlink $linkFile;
749
            } 
750
            else
751
            {
752
                Message ("Broken link: $pkg", "Source link: $linkFile" );
753
            }
754
        }
755
 
756
    }
757
 
758
    exit (0);
759
}
760
 
7306 dpurdie 761
#-------------------------------------------------------------------------------
7319 dpurdie 762
# Function        : getPackageLink 
763
#
764
# Description     : Read a package link file and process the data to generate 
765
#                   the link to the package
766
#
767
# Inputs          : $linkFile   - File that contains the link
768
#
769
# Returns         : The resolved link
770
#
771
sub getPackageLink
772
{
773
    my ($linkFile) = @_;
774
    my $pkg = TagFileRead($linkFile);
775
    $pkg =~ s~\\~/~g;
776
    if ($pkg =~ s~^GBE_SANDBOX/~$GBE_SANDBOX/~)
777
    {
778
            # If the target sandbox is in the 'deploymode' then the package
779
            # will not be in the expected location. It will be in a 'build/deploy'
780
            # subdir. Remove the pkg/name dir to get to the root of the package
781
            my @dirs = File::Spec->splitdir( $pkg );
782
            splice(@dirs, -2);
783
            my $deployBox = catdir(@dirs, 'build', 'deploy');
784
            $pkg = $deployBox if ( -d $deployBox);
785
    }
786
 
787
    return $pkg;
788
}
789
 
790
 
791
#-------------------------------------------------------------------------------
7306 dpurdie 792
# Function        : setScanDepth 
793
#
794
# Description     : Set the depth of the build file scan usd in this sandbox 
795
#
796
# Inputs          : Command line arguments
797
#
798
# Returns         : This function will not return
799
#
800
sub setScanDepth
801
{
802
    my ( @cmd_opts ) = @_;
803
    GetOptions (
804
                "help:+"        => \$opt_help,
805
                "manual:3"      => \$opt_help,
806
                ) || Error ("Invalid command line" );
7304 dpurdie 807
 
7306 dpurdie 808
    SubCommandHelp( $opt_help, "Sandbox Scan Depth") if ($opt_help || ($#ARGV > 0 ));
809
    Error ("Command must be executed from within a Sandbox") unless ( $GBE_SANDBOX );
810
 
811
    if (defined $ARGV[0])
812
    {
813
        FileCreate($depthFile, $ARGV[0]);
814
 
815
        #
816
        #   Force a rescan of the cached information
817
        #
818
        unlink $cacheFile;
819
        exit 0;
820
    }
821
 
822
    #
823
    #   Report the current scan depth
824
    #
825
    getScanDepth();
826
    Information ("Build File scan depth: ". $scanDepth);
827
    exit (0);
828
 
829
}
830
 
6133 dpurdie 831
#-------------------------------------------------------------------------------
7306 dpurdie 832
# Function        : getScanDepth  
833
#
834
# Description     : Determine the build file scan depth for the current sandbox
835
#                   Non-default data is maintained in a data file    
836
#
837
# Inputs          : None
838
#
839
# Returns         : Nothing
840
#
841
 
842
sub getScanDepth
843
{
844
    my $depth = $SCANDEPTH;
845
    if ( -f $depthFile)
846
    {
847
        $depth = TagFileRead($depthFile);
848
        my $invalid = 0;
849
        if ($depth !~ m~^\d+$~) {
850
            $invalid = 1;
851
        } elsif ( $depth lt 0) {
852
            $invalid = 1;
853
        }
854
 
855
        if ($invalid)
856
        {
857
            unlink $depthFile;
858
            Warning ("Invalid scandepth file. File deleted.");
859
            $depth = $SCANDEPTH;
860
        }
861
    }
862
    $scanDepth = $depth;
863
}
864
 
865
 
866
#-------------------------------------------------------------------------------
335 dpurdie 867
# Function        : check_package_existance
868
#
869
# Description     : Determine if a given package-version exists
870
#
871
# Inputs          : $name           - Package Name
872
#                   $ver            - Package Version
873
#
874
# Returns         : true            - Package exists
875
#
876
sub check_package_existance
877
{
878
    my ($name, $ver) = @_;
879
    #
880
    #   Look in each package archive directory
881
    #
882
    foreach my $dpkg ( $GBE_DPKG_SBOX,
883
                       $GBE_DPKG_LOCAL,
884
                       $GBE_DPKG_CACHE,
7319 dpurdie 885
                       $GBE_DPKG_ESCROW,
886
                       '--NotEscrow',
4688 dpurdie 887
                       $GBE_DPKG_REPLICA,
335 dpurdie 888
                       $GBE_DPKG,
889
                       $GBE_DPLY,
890
                       $GBE_DPKG_STORE )
891
    {
892
        next unless ( $dpkg );
7319 dpurdie 893
        if ( $dpkg eq '--NotEscrow' )
335 dpurdie 894
        {
7319 dpurdie 895
            last if ($GBE_DPKG_ESCROW);
896
            next;
335 dpurdie 897
        }
898
    }
899
   return 0;
900
}
901
 
6133 dpurdie 902
#-------------------------------------------------------------------------------
7301 dpurdie 903
# Function        : locatePreBuiltPackage 
904
#
905
# Description     : Locate a prebuilt package
906
#                   Skip the make process if a package with a matching signature 
907
#                   can be found. ie: We have a pre-built version
908
#                   
909
# Inputs          : $fe     - Package Entry
910
#
7319 dpurdie 911
# Returns         : Two items
912
#                   Found       - True - Prebuilt package found
913
#                               - False - Prebuild package not found
914
#                   Signature   - Package Signature
915
#                                 Undef if not found     
7301 dpurdie 916
#
917
sub locatePreBuiltPackage
918
{
919
    my ($fe) = @_;
7320 dpurdie 920
    my $inSandbox = 1;
7301 dpurdie 921
 
922
    #
923
    #   Get the package signature
924
    #
7319 dpurdie 925
    my $pkgSig = getPackageSignature($fe);
926
    return (0, undef) unless $pkgSig;
7301 dpurdie 927
 
928
    #
929
    #   Look in each package archive directory
930
    #   
931
    foreach my $dpkg ( $GBE_DPKG_SBOX,
7320 dpurdie 932
                       '--EndSandbox',
7301 dpurdie 933
                       $GBE_DPKG_LOCAL,
934
                       $GBE_DPKG_CACHE,
935
                       $GBE_DPKG_REPLICA,
936
                       $GBE_DPKG,
937
                       $GBE_DPLY,
938
                       $GBE_DPKG_STORE )
939
    {
7320 dpurdie 940
        if ($dpkg && $dpkg eq '--EndSandbox') {
941
            $inSandbox = 0;
942
            next;
943
        }
944
 
945
        #
946
        #   Don't attempt to locate prebuilt packages in a build system sandbox
947
        #   as the packages may be partially formed. The packages MUST be found in
948
        #   a regular package store
949
        #   
950
        if ( $inSandbox && defined($GBE_ABT) )
951
        {
952
            next;
953
        }
954
 
7301 dpurdie 955
        my $pkgDir = catdir( $dpkg, $fe->{mname}, $pkgSig);
956
        if (-d $pkgDir )
957
        {
958
            Debug("Prebuilt Package found: $pkgSig");
7319 dpurdie 959
            return (1, $pkgSig);
7301 dpurdie 960
        }
961
    }
7319 dpurdie 962
    return (0, $pkgSig);
7301 dpurdie 963
}
964
 
7319 dpurdie 965
 
7301 dpurdie 966
#-------------------------------------------------------------------------------
7319 dpurdie 967
# Function        : getPackageSignature
968
#
969
# Description     : Determine if we have calculated the package signature
970
#                   
971
# Inputs          : $fe     - Package Entry
972
#
973
# Returns         : Package signature
974
#                   undef if not found
975
#
976
sub getPackageSignature
977
{
978
    my ($fe) = @_;
979
 
980
    #
981
    #   Get the package signature
982
    #   This is held in the packages interface directory
983
    #
984
    my $ifaceDir = getpkgInterface($fe);
985
    return 0 unless $ifaceDir;
986
 
987
    my $sigFile = catdir($ifaceDir, 'Package.sig');
988
    return 0 unless -f $sigFile;
989
 
990
    return TagFileRead($sigFile);
991
 
992
}
993
 
994
#-------------------------------------------------------------------------------
6133 dpurdie 995
# Function        : getpkgInterface 
996
#
997
# Description     : Locate the packages interface directory 
998
#
999
# Inputs          : $fe     - Package Entry 
1000
#
1001
# Returns         : Undef if not found
1002
#                   Path to the packages interface directory
1003
#
1004
sub getpkgInterface
1005
{
1006
    my ($fe) = @_;
335 dpurdie 1007
 
6133 dpurdie 1008
    #
1009
    #   Determine the packages 'interface' directory
1010
    #
1011
    my $pSuffix = ($fe->{prj}) ? ( '.' . $fe->{prj}) : '';
1012
    my $ifaceDir = catdir($GBE_SANDBOX, 'sandbox_dpkg_archive', $fe->{name}, 'sandbox' . $pSuffix . '.int');
1013
    return unless -f $ifaceDir; 
1014
    $ifaceDir = TagFileRead($ifaceDir);
1015
    $ifaceDir =~ s~\\~/~g;
1016
    $ifaceDir =~ s~GBE_SANDBOX/~$GBE_SANDBOX/~;
1017
    return $ifaceDir; 
1018
}
1019
 
1020
 
335 dpurdie 1021
#-------------------------------------------------------------------------------
227 dpurdie 1022
# Function        : calc_sandbox_info
1023
#
1024
# Description     : Examine the sandbox and determine all the important
1025
#                   information
1026
#
1329 dpurdie 1027
#                   Operation will be modified by
1028
#                       $opt_toPackage
1029
#                       $opt_fromPackage
1030
#                       @opt_justPackage
1031
#                       @opt_ignorePackage
7319 dpurdie 1032
#                       $opt_onlyLevel
227 dpurdie 1033
#
6133 dpurdie 1034
# Inputs          : quiet       undef - noisy
1035
#                               1 - quiet           
1329 dpurdie 1036
#
227 dpurdie 1037
# Returns         : Will exit if not in a sandbox
1038
#                   Populates global variables
1039
#                       @build_order - build ordered array of build entries
1040
#
1041
sub calc_sandbox_info
1042
{
6133 dpurdie 1043
    my ($quiet) = @_;
7306 dpurdie 1044
    my $buildFileDepth = 0;
1045
    getScanDepth();
1046
 
227 dpurdie 1047
    #
1048
    #   Start from the root of the sandbox
1049
    #
1050
    Error ("Command must be executed from within a Sandbox") unless ( $GBE_SANDBOX );
6133 dpurdie 1051
    my $startDir = Getcwd();
227 dpurdie 1052
    chdir ($GBE_SANDBOX) || Error ("Cannot chdir to $GBE_SANDBOX");
1053
 
1054
    #
6133 dpurdie 1055
    #   Retain subdir so we can figure out a starting package
1056
    # 
1057
    $startDir = '' unless ($startDir =~ s~^$GBE_SANDBOX/~~);
1058
 
1059
    #
227 dpurdie 1060
    #   Locate all packages within the sandbox
1061
    #   These will be top-level directories - one per package
1062
    #
1063
    my @build_list;
6133 dpurdie 1064
    my $currentRootFingerPrint = calc_rootFingerPrint();
1065
 
1066
    if (-f $cacheFile && !$opt_reScan) 
227 dpurdie 1067
    {
6133 dpurdie 1068
        #
1069
        #   Read in the location cache
1070
        #   Greatly speeds up the location process
1071
        #
1072
        open( my $lf, '<', $cacheFile) || Error ("Read error: $cacheFile. $!");
275 dpurdie 1073
 
6133 dpurdie 1074
        #
1075
        #   Check root directory signature
1076
        #       Has the user added or removed packages from the sandbox
1077
        #
1078
        my $rootFingerPrint = <$lf>;
1079
        $rootFingerPrint =~ s~\s*$~~;
1080
 
1081
        if ($rootFingerPrint eq $currentRootFingerPrint )
275 dpurdie 1082
        {
6133 dpurdie 1083
            while (<$lf>)
1084
            {
7306 dpurdie 1085
                s~\s+$~~;
6133 dpurdie 1086
                my @locationEntry = split($;, $_);
1087
                my $pname = $locationEntry[0];
7306 dpurdie 1088
                if ($locationEntry[1] eq ':STOP:') {
1089
                    push @stopped, $pname;
1090
                    Verbose("Package contains stop file: $pname");
1091
                    next;
1092
                }
6133 dpurdie 1093
 
1094
                #
1095
                #   Locate the build files in each package
1096
                #   Scan the build files and extract dependancy information
1097
                #
1098
                my $bscanner = BuildFileScanner( $pname, 'build.pl',
1099
                                                         '--LocateAll',
7306 dpurdie 1100
                                                         '--LimitDepth=' . $scanDepth,
7323 dpurdie 1101
                                                         '--ScanDependencies', 
1102
                                                         '--Stop' );
6133 dpurdie 1103
                unless ($bscanner->setLocation($_)) {
1104
                    Verbose("Build file missing: Force full scan");
1105
                    @build_list = ();
1106
                    last;
1107
                }
1108
                $bscanner->scan();
1109
                my @blist = $bscanner->getInfo();
1110
                unless ($quiet) {
1111
                    Warning ("Package does not have build files: $pname") unless ( @blist );
1112
                    Warning ("Package has multiple build files: $pname") if ( $#blist > 0 );
1113
                }
1114
                push @build_list, @blist;
1115
            }
275 dpurdie 1116
        }
6133 dpurdie 1117
        close $lf;
1118
    }
275 dpurdie 1119
 
6133 dpurdie 1120
    unless (@build_list)
1121
    {
1122
        Message ("Scanning sandbox for build files");
1123
        FileCreate($cacheFile, $currentRootFingerPrint );
227 dpurdie 1124
 
6133 dpurdie 1125
        my @locationData;
1126
        foreach my $pname ( glob("*") )
1127
        {
1128
            next if ( $pname =~ m~^\.~ );
1129
            next if ( $pname =~ m~dpkg_archive$~ );
7300 dpurdie 1130
            next if ( $pname eq 'CSV' );
1131
            next if ( $pname eq 'lost+found' );
6133 dpurdie 1132
            next unless ( -d $pname );
7310 dpurdie 1133
            if ( -d $pname . '/sandbox_dpkg_archive' ) {
1134
                Warning("Nested sandbox ignored: $pname");
1135
                next ;
1136
            }
6133 dpurdie 1137
            Verbose ("Package discovered: $pname");
1138
 
1139
            if ( -f "$pname/stop" || -f "$pname/stop.$GBE_MACHTYPE" )
1140
            {
1141
                push @stopped, $pname;
1142
                Warning("Package contains stop file: $pname");
7306 dpurdie 1143
                push @locationData, join($;, $pname, ':STOP:');
6133 dpurdie 1144
                next;
1145
            }
1146
 
1147
            #
1148
            #   Locate the build files in each package
1149
            #   Scan the build files and extract dependancy information
1150
            #
1151
            my $bscanner = BuildFileScanner( $pname, 'build.pl',
1152
                                                     '--LocateAll',
7306 dpurdie 1153
                                                     '--LimitDepth=' . $scanDepth,
7323 dpurdie 1154
                                                     '--ScanDependencies',
1155
                                                     '--Stop' );
6133 dpurdie 1156
            $bscanner->scan();
1157
            my @blist = $bscanner->getInfo();
1158
            unless ($quiet) {
1159
                Warning ("Package does not have build files: $pname") unless ( @blist );
1160
                Warning ("Package has multiple build files: $pname") if ( $#blist > 0 );
1161
            }
1162
            push @build_list, @blist;
1163
            push @locationData, $bscanner->getLocation();
7306 dpurdie 1164
 
1165
            #
1166
            #   Determine max build file depth - just to show user
1167
            #
1168
            foreach ( @blist)
1169
            {
1170
                my $count = () = $_->{dir} =~ m~/~g;
1171
                $buildFileDepth = $count if ($count > $buildFileDepth)
1172
            }
1173
 
1174
 
6133 dpurdie 1175
        }
7306 dpurdie 1176
        Message ("Max Build File Depth : " . ($buildFileDepth + 1));
1177
        Message ("Build File Scan Depth: ". $scanDepth) if ($SCANDEPTH ne $scanDepth);
6133 dpurdie 1178
 
7306 dpurdie 1179
 
227 dpurdie 1180
        #
6133 dpurdie 1181
        #   Save (cache) location information
227 dpurdie 1182
        #
6133 dpurdie 1183
        FileAppend($cacheFile, @locationData);
227 dpurdie 1184
    }
1185
 
1186
    #
1187
    #   Process each build file and extract
1188
    #       Name of the Package
1189
    #       Dependency list
1190
    #   Build up a hash of dependence information
1191
    #
1192
 
1193
    my %depends;
299 dpurdie 1194
    my %multi;
245 dpurdie 1195
    foreach my $be ( @build_list )
227 dpurdie 1196
    {
245 dpurdie 1197
        Verbose( DisplayPath ("Build file: " . $be->{dir} . " Name: " . $be->{file} ));
359 dpurdie 1198
        #
7301 dpurdie 1199
        #   Sandbox 
359 dpurdie 1200
        #       Set a suitable display name
1201
        #       Set a suitable tag
1202
        #
7301 dpurdie 1203
        $be->{dname} = $be->{mname};
1204
        $be->{tag}   = $be->{package};
4184 dpurdie 1205
        $be->{fname} = join ('_', $be->{name}, $be->{version});
7307 dpurdie 1206
        if (length ($be->{dname}) > $maxDname ) {
1207
             $maxDname = length ($be->{dname});
1208
        }
359 dpurdie 1209
 
245 dpurdie 1210
#        DebugDumpData ("be", $be );
227 dpurdie 1211
 
1212
        #
299 dpurdie 1213
        #   Catch multiple builds for the same package
1214
        #   Report later - when we have all
1215
        #
359 dpurdie 1216
        next unless ( $be->{dname} );
7307 dpurdie 1217
        push @{$multi{$be->{dname}}},$be;
227 dpurdie 1218
    }
1219
 
7307 dpurdie 1220
    #
1221
    #   Detect, process and report packages that have multiple builders
1222
    #       An error that can be ignored
1223
    #
359 dpurdie 1224
    foreach my $dname ( sort keys %multi )
299 dpurdie 1225
    {
7307 dpurdie 1226
        my $errFn = $opt_multiBuilders ? \&Warning : \&ReportError;
1227
        if ( scalar @{$multi{$dname}} > 1 )
1228
        {
1229
            my @dirList;
1230
            foreach my $be (@{$multi{$dname}}) {
1231
                push @dirList, $be->{dir};
1232
            }           
1233
            &$errFn("Multiple builders for : $dname", @dirList ) unless $opt_multiBuilders > 1;
1234
        }
1235
        else
1236
        {
1237
            #
1238
            #   Add into dependency struct
1239
            #
1240
            foreach my $be (@{$multi{$dname}}) {
1241
                $depends{$be->{tag}} = $be;
1242
            }
1243
        }
299 dpurdie 1244
    }
7307 dpurdie 1245
    %multi = ();
299 dpurdie 1246
    ErrorDoExit();
1247
 
245 dpurdie 1248
#DebugDumpData ("depends", \%depends );
1249
 
227 dpurdie 1250
    #
255 dpurdie 1251
    #   Remove any dependencies to 'external' packages
227 dpurdie 1252
    #   These will not be met internally and can be regarded as constant
1253
    #
1329 dpurdie 1254
    #   Split 'depends' into internal (ideps) and external (edeps)
1255
    #       edeps : External Dependencies
1256
    #               Key:        Name;Version
1257
    #               Value:      'tag' - index into packages
1258
    #       ideps : Internal Dependencies
1259
    #               Key:        'tag'   - Index into packages
1260
    #               Value:      'dname' - Display Name
1261
    #
227 dpurdie 1262
    foreach my $key ( keys %depends )
1263
    {
1264
        foreach my $build ( keys( %{$depends{$key}{depends}} ))
1265
        {
1266
            unless (exists $depends{$build})
1267
            {
1329 dpurdie 1268
                $depends{$key}{'edeps'}{$depends{$key}{depends}{$build}} = $build;
227 dpurdie 1269
                delete ($depends{$key}{depends}{$build}) ;
1270
                Verbose2( "Not in set: $build");
1271
            }
1272
            else
1273
            {
1329 dpurdie 1274
                $depends{$key}{'ideps'}{$build} = $depends{$build}{dname};
227 dpurdie 1275
            }
1276
        }
1277
    }
359 dpurdie 1278
 
1279
#DebugDumpData ("depends", \%depends );
1280
 
1281
    #
1282
    #   Determine package build order
1283
    #       Scan the list of packages in the build set and determine
1284
    #       those with no dependencies. These can be built.
1285
    #       Remove those packages as dependents from all packages
1286
    #       Repeat.
1287
    #
6133 dpurdie 1288
    #
1289
    #   Determine the build order
1290
    #
1291
    @build_order = ();
1292
    my $more = 1;
1293
    my $level = 0;
1329 dpurdie 1294
    my %found    = map { $_ => 1 } @opt_ignorePackage;
1295
    my %notFound = map { $_ => 1 } @opt_justPackage;
1296
    my $scan_start = 0;
1297
    my $scan_stop = 0;
1298
    my $scan_active = ($opt_fromPackage) ? 0 : 1;
1299
    $scan_active = 0 if ( !$opt_fromPackage && !$opt_fromPackage && !@opt_ignorePackage && @opt_justPackage );
1300
 
227 dpurdie 1301
    while ( $more )
1302
    {
1303
        $more = 0;
1304
        $level++;
1305
        my @build;
1306
 
1307
        #
1308
        #   Locate packages with no dependencies
1309
        #
6133 dpurdie 1310
        foreach my $key ( sort {lc($a) cmp lc($b)} keys %depends )
227 dpurdie 1311
        {
1312
            next if ( keys( %{$depends{$key}{depends}} ) );
1313
            push @build, $key;
1314
        }
1315
 
1316
        foreach my $build ( @build )
1317
        {
1318
            $more = 1;
1329 dpurdie 1319
            my $fe = $depends{$build};
1320
            my $scan_add = $scan_active ? 1 : 0;
1321
 
4184 dpurdie 1322
            if ( $opt_fromPackage && (($fe->{mname} eq $opt_fromPackage) || ($fe->{name} eq $opt_fromPackage) || ($fe->{fname} eq $opt_fromPackage)))
1329 dpurdie 1323
            {
1324
                $scan_add = 1;
1325
                $scan_active = 1;
1326
                $scan_start = 1;
1327
            }
1328
 
4184 dpurdie 1329
            if ( $opt_toPackage && (($fe->{mname} eq $opt_toPackage) || ($fe->{name} eq $opt_toPackage) || ($fe->{fname} eq $opt_toPackage)))
1329 dpurdie 1330
            {
1331
                $scan_add = 0;
1332
                $scan_active = 0;
1333
                $scan_stop = 1;
1334
            }
1335
 
1336
            if ( @opt_justPackage )
1337
            {
1338
                foreach my $pname ( @opt_justPackage )
1339
                {
4184 dpurdie 1340
                    if ( (($fe->{mname} eq $pname) || ($fe->{name} eq $pname) || ($fe->{fname} eq $pname)))
1329 dpurdie 1341
                    {
1342
                        $scan_add = 1;
1343
                        delete $notFound{$pname};
1344
                    }
1345
                }
1346
            }
1347
 
1348
            if ( @opt_ignorePackage )
1349
            {
1350
                foreach my $pname ( @opt_ignorePackage )
1351
                {
4184 dpurdie 1352
                    if ( (($fe->{mname} eq $pname) || ($fe->{name} eq $pname) || ($fe->{fname} eq $pname)))
1329 dpurdie 1353
                    {
1354
                        $scan_add = 0;
1355
                        delete $found{$pname};
1356
                    }
1357
                }
1358
            }
1359
 
6133 dpurdie 1360
            #
1361
            #   Test for a skip marker
1362
            #
1363
            my $skipFile = catdir($GBE_SANDBOX, 'sandbox_dpkg_archive', '_skip.'. $fe->{dname});
1364
            my $skipMachFile = catdir($GBE_SANDBOX, 'sandbox_dpkg_archive', '_skip.' . $GBE_MACHTYPE . '.' . $fe->{dname});
1365
            if ( -f $skipFile || -f $skipMachFile )
1366
            {
1367
                Warning("Package marked for skip: $fe->{dname}, $fe->{dir}") unless $quiet;
1368
                $scan_add = 0;
1369
                $fe->{buildSkip} = 1;
1370
            }
1371
 
7319 dpurdie 1372
            #
1373
            #   Test for a build error marker
1374
            #
1375
            my $errorFile = catdir($GBE_SANDBOX, 'sandbox_dpkg_archive', '_error.'. $fe->{dname});
1376
            my $errorMachFile = catdir($GBE_SANDBOX, 'sandbox_dpkg_archive', '_error.' . $GBE_MACHTYPE . '.' . $fe->{dname});
1377
            if ( -f $errorFile || -f $errorMachFile )
1378
            {
1379
                Warning("Package marked as error: $fe->{dname}, $fe->{dir}") unless $quiet;
1380
                $fe->{buildError} = 1;
1381
            }
1382
 
1383
            #
1384
            #   Select one level
1385
            #
1386
            if ($opt_onlyLevel && $opt_onlyLevel != $level) {
1387
                $scan_add = 0;
1388
            }
1389
 
227 dpurdie 1390
            $fe->{level} = $level;
1329 dpurdie 1391
            $fe->{buildActive} = $scan_add;
227 dpurdie 1392
            $packages{$build} = $fe;
6133 dpurdie 1393
            push (@build_order, $fe);
227 dpurdie 1394
            delete $depends{$build};
1395
            delete $fe->{depends};                          # remove now its not needed
1396
        }
1397
 
1398
        foreach my $key ( keys %depends )
1399
        {
1400
            foreach my $build ( @build )
1401
            {
1402
                delete $depends{$key}{depends}{$build};
1403
            }
1404
        }
1405
    }
1406
 
1407
    #
1329 dpurdie 1408
    #   Detect bad user specifications
1409
    #
1410
    ReportError ("Specified FromPackage not found: $opt_fromPackage") if ( $opt_fromPackage && !$scan_start );
1411
    ReportError ("Specified ToPackage not found: $opt_toPackage") if ( $opt_toPackage && !$scan_stop );
1412
    ReportError ("Specified ExactPackages not found: ", keys( %notFound) ) if ( %notFound );
1413
    ReportError ("Specified IgnorePackages not found: ", keys( %found) ) if ( %found );
1414
    ErrorDoExit();
1415
 
1416
    #
6133 dpurdie 1417
    #   Just to be sure to be sure
1418
    #
1419
    if ( keys %depends )
1420
    {
1421
        #DebugDumpData ("depends", \%depends );
1422
        Error( "Internal algorithm error: Bad dependancy walk",
1423
               "Possible circular dependency");
1424
    }
1425
 
1426
    #
1427
    #   Determine FULL internal dependency list for each package
1428
    #       Walk packages in build order so that we can leverage the calculations
1429
    #       already done.
1430
    # 
1431
    foreach my $fe ( @build_order )
1432
    {
1433
        my @pkgBuildOrder;
1434
        my %pkgSeen;
1435
        my $key = $fe->{tag};
1436
        if (exists $packages{$key}{'ideps'})
1437
        {
1438
            foreach ( keys %{$packages{$key}{'ideps'}} )
1439
            {
1440
                foreach my $ikey (@{$packages{$_}{'AllIdepsOrder'}})
1441
                {
1442
                    push @pkgBuildOrder, $ikey unless $pkgSeen{$ikey};
1443
                    $pkgSeen{$ikey} = 1;
1444
                }
1445
            }
1446
        }
1447
        push @pkgBuildOrder, $key;
1448
        $fe->{'AllIdepsOrder'} = \@pkgBuildOrder;
1449
 
1450
        #
1451
        #   Is this package in the current directory
1452
        #
1453
        if ($startDir)
1454
        {
1455
            my $matchBase = $startDir . '/'; 
1456
            if ($matchBase =~ m~^$fe->{dir}/~)
1457
            {
1458
                $fe->{buildCurrent} = 1;
1459
                $currentPkgTag = $key;
1460
            }
1461
        }
1462
    }
1463
 
1464
    #
1465
    #   Now that we have a full dependency list for each package we can calculate a full
1466
    #   usage list. This is a complete list of all package that depend on a package both directly 
1467
    #   and inderectly. Useful for regression testing
1468
    #   
1469
    foreach my $fe ( @build_order )
1470
    {
1471
        foreach my $itag (@{$fe->{'AllIdepsOrder'}})
1472
        {
1473
            next if ($itag eq $fe->{tag});
1474
            push @{$packages{$itag}{usedBy}}, $fe->{tag};
1475
        }
1476
    }
1477
 
1478
    #
7319 dpurdie 1479
    #   Now have a full dependency list AND full usage list
1480
    #   Locate packages that have a buildError and mark the consumers
1481
    #   as have a dependency on an package in error
1482
    #
1483
    foreach my $fe ( @build_order )
1484
    {
1485
        if ($fe->{buildError} && exists($fe->{'usedBy'}))
1486
        {
1487
            foreach my $entry (@{$fe->{'usedBy'}}) {
1488
                push @{$packages{$entry}{buildExclude}}, $fe->{tag};
1489
            }
1490
        }
1491
    }
1492
 
1493
    #
6133 dpurdie 1494
    #   If the CWD is within a package then limit the build to that package and
1495
    #   its dependents, unless user specifies entire sandbox.
1496
    #   
1497
    if ($currentPkgTag && ! $opt_allSandbox )
1498
    {
1499
        if (!$opt_processUsedBy )
1500
        {
1501
            #
1502
            #   Reform the build_order to reflect the current sandbox
1503
            #   The @build_order is an array of package entries
1504
            #   The per-package build order is an array of keys
1505
            #
1506
            my @pkgOrder;
1507
            foreach ( @{$packages{$currentPkgTag}{AllIdepsOrder}})
1508
            {
1509
                push @pkgOrder,  $packages{$_} ;
1510
            }
1511
 
1512
            # Reform the build order based on original level
1513
            #   Simply done to look pretty - and be consistient when compared with the entire sandbox
1514
            @build_order = sort {$a->{level} <=> $b->{level}} @pkgOrder;
1515
 
1516
        }
1517
        else
1518
        {
1519
            #
1520
            #   Reform the build order to reflect the consumers of the current package
1521
            #   This does not include the current package. The assumption is that the package
1522
            #   has been built. 
1523
            #
1524
            #   The @build_order is an array of package entries
1525
            #   The per-package build order is an array of keys
1526
            #
1527
            my @pkgOrder;
1528
            foreach ( @{$packages{$currentPkgTag}{'usedBy'}})
1529
            {
1530
                push @pkgOrder,  $packages{$_} ;
1531
            }
1532
 
1533
            # Reform the build order based on original level
1534
            #   Simply done to look pretty - and be consistient when compared with the entire sandbox
1535
            @build_order = sort {$a->{level} <=> $b->{level}} @pkgOrder;
1536
        }
1537
    }
1538
    else
1539
    {
1540
        $opt_allSandbox = 1;
1541
    }
1542
 
1543
    #
1329 dpurdie 1544
    #   Calculate the external dependencies
1545
    #       Only process packages that are a part of the build
1546
    #
1547
    #   extern_deps structure
1548
    #       Hash key: 'tag'   - Index into packages
1549
    #          Value: Hash of:
1550
    #                 Key  : Name;Version
1551
    #                 Value: Array of: 'tags' (Index into packages)
1552
    #                                   of packages that use the external
1553
    #                                   component.
1554
    {
6133 dpurdie 1555
        Verbose ("Calculate external dependencies on packages in build");
1329 dpurdie 1556
        %extern_deps = ();
1557
 
6133 dpurdie 1558
        foreach my $pe (@build_order)
1329 dpurdie 1559
        {
6133 dpurdie 1560
                next unless ( $pe->{buildActive} );
1561
                next unless ( $pe->{'edeps'} );
1562
                foreach ( keys %{$pe->{'edeps'}} )
1329 dpurdie 1563
                {
6133 dpurdie 1564
                    push @{$extern_deps{$pe->{'edeps'}{$_}} {$_} }, $pe->{tag};
1329 dpurdie 1565
                }
1566
        }
1567
    }
1568
 
227 dpurdie 1569
 
1329 dpurdie 1570
#   DebugDumpData("Packages", \%packages);
359 dpurdie 1571
#   DebugDumpData ("Order", \@build_order);
1572
#   DebugDumpData("External Depends", \%extern_deps );
227 dpurdie 1573
}
1574
 
1575
#-------------------------------------------------------------------------------
7319 dpurdie 1576
# Function        : writeBuildData 
1577
#
1578
# Description     : 
1579
#
1580
# Inputs          : Command line arguments 
1581
#
1582
# Returns         : 
1583
#
1584
sub writeBuildData
1585
{
1586
    my (@cmd_opts ) = @_;
1587
    my $opt_outfile;
7321 dpurdie 1588
    my $opt_fullData;
7319 dpurdie 1589
 
1590
    Getopt::Long::Configure('pass_through');
1591
    getOptionsFromArray ( \@cmd_opts,
7320 dpurdie 1592
                          'outfile=s'   => \$opt_outfile,
7321 dpurdie 1593
                          'fullData!'   => \$opt_fullData,
7319 dpurdie 1594
                          ) || Error ("Invalid command line" );
1595
    SubCommandHelp( $opt_help, 'Write Build Data') if ($opt_help  );
1596
 
1597
    #
1598
    #   Calculate sandbox info
1599
    #   All data written will be based on this information
1600
    #
1601
    calc_sandbox_info(1);
1602
    calc_signature_info();
1603
 
1604
    #
1605
    #   Generate build data
1606
    #   Consists of a few sections
1607
    #       BuildPlan   - Package names to be built, in order
1608
    #                     In practice only the first can be built
1609
    #                     the others can be used as an indication of builds to be performed
1610
    #                     
1611
    #   
1612
    my %BuildData;
1613
    my @BuildPlan = ();
1614
    my @BuildEntry;
7320 dpurdie 1615
    my @PkgData;
7319 dpurdie 1616
 
7321 dpurdie 1617
    #
1618
    #   Generate data on all known package
1619
    #
7319 dpurdie 1620
    foreach my $fe ( @build_order ) {
7320 dpurdie 1621
        my $data;
1622
        $data->{name} = $fe->{dname};
1623
        $data->{signature} = $fe->{signature};
1624
        $data->{error} = $fe->{buildError} ? 1 : 0;
1625
        $data->{excluded} = $fe->{buildExclude} ? 1 : 0;
1626
        $data->{prebuilt} = $fe->{si} eq 1? 1 : 0;
7321 dpurdie 1627
        if ($opt_fullData)
1628
        {
1629
            foreach my $idep ( keys %{$fe->{'ideps'}} ) {
1630
                push @{$data->{dependencies}}, $fe->{'ideps'}{$idep};
1631
            }
1632
        }
7320 dpurdie 1633
        push @PkgData, $data;
1634
    }
1635
 
7321 dpurdie 1636
    #
1637
    #   Generate the build plan and locate the next package to build
1638
    #
7320 dpurdie 1639
    foreach my $fe ( @build_order ) {
7319 dpurdie 1640
        next if $fe->{buildError};
1641
        next if $fe->{buildExclude};
1642
        next if $fe->{buildSkip};
1643
        next unless $fe->{buildActive};
1644
        next if $fe->{si} eq 1;
1645
 
7321 dpurdie 1646
        push @BuildPlan, $fe->{dname};
7319 dpurdie 1647
        push @BuildEntry, $fe;
1648
    }
1649
 
1650
    push @{$BuildData{BuildPlan}}, @BuildPlan;
1651
 
1652
    #
1653
    #   Add information on the first item
1654
    #   This is the package that will be built so we need more information
1655
    #
1656
    my $BuildPkg = $BuildEntry[0];
1657
    my $pkgData;
1658
    if ($BuildPkg)
1659
    {
1660
        $pkgData->{fname} = $BuildPkg->{fname};
1661
        $pkgData->{dname} = $BuildPkg->{dname};
1662
        $pkgData->{dir} = $BuildPkg->{dir};
1663
        $pkgData->{name} = $BuildPkg->{name};
1664
        $pkgData->{version} = $BuildPkg->{version};
1665
        $pkgData->{prj} = $BuildPkg->{prj};
7320 dpurdie 1666
 
1667
        if ($BuildPkg->{si} eq 3)
1668
        {
1669
            $pkgData->{error} = 1;
1670
            $pkgData->{signature} = "MSG: Cannot create";
1671
            $pkgData->{generic} = 0;
1672
        }
1673
        else
1674
        {
7321 dpurdie 1675
            $pkgData->{error} = 0;
7320 dpurdie 1676
            $pkgData->{signature} = $BuildPkg->{signature};
1677
 
1678
            #
1679
            #   Determine if the package is 'GENERIC'
1680
            #   Read in the build.cfg file
1681
            #
1682
            my $pkgInterface = getpkgInterface($BuildPkg);
1683
            ReadBuildConfig( $pkgInterface, '', '--NoError' );
1684
            $pkgData->{generic} = ReadBuildConfig::isGenericBuild();
1685
        }
7321 dpurdie 1686
 
1687
        #
1688
        #   Add dependency information
1689
        #
1690
        foreach my $idep ( keys %{$BuildPkg->{'ideps'}} )
1691
        {
1692
            $pkgData->{dependencies}{$BuildPkg->{'ideps'}{$idep}} = $packages{$idep}->{signature};
1693
        }
7319 dpurdie 1694
    }
1695
 
1696
    $BuildData{BuildPkgData} = $pkgData;
7320 dpurdie 1697
    $BuildData{PkgData} = \@PkgData;
7319 dpurdie 1698
 
1699
#DebugDumpData("data", $BuildPkg);
1700
 
7320 dpurdie 1701
    if ($opt_outfile) {
7321 dpurdie 1702
        FileCreate($opt_outfile, to_json( \%BuildData, { ascii => 1, pretty => 1, canonical => 1 }));
7320 dpurdie 1703
    } else {
7321 dpurdie 1704
        print( to_json( \%BuildData, { ascii => 1, pretty => 1, canonical => 1 }) . "\n");
7320 dpurdie 1705
    }
7319 dpurdie 1706
#    DebugDumpData("BuildData",\%BuildData);
7321 dpurdie 1707
#DebugDumpData("Packages", \%packages);
7319 dpurdie 1708
    #
1709
    #   All done
1710
    #
1711
    exit(0);
1712
}
1713
 
1714
#-------------------------------------------------------------------------------
7320 dpurdie 1715
# Function        : setAbtMarker 
1716
#
1717
# Description     : Set a marker file in the sandbox such that JATS will recognise
1718
#                   the sandbox as being a special ABT enabled sandbox
1719
#
1720
# Inputs          : None    
1721
#
1722
# Returns         : Does not return 
1723
#
1724
sub setAbtMarker
1725
{
1726
    my (@cmd_opts ) = @_;
1727
 
1728
    Getopt::Long::Configure('pass_through');
1729
    getOptionsFromArray ( \@cmd_opts,
1730
                          ) || Error ("Invalid command line" );
1731
    SubCommandHelp( $opt_help, 'Set Abt Marker') if ($opt_help  );
1732
 
1733
    Message ("Setting ABT marker file");
1734
    TouchFile( CatPaths($GBE_DPKG_SBOX, 'abtMarker'));
1735
    $GBE_ABT = 1;
1736
 
1737
    #
1738
    #   All done
1739
    #
1740
    exit(0);
1741
}
1742
 
1743
#-------------------------------------------------------------------------------
1744
# Function        : generatepkgSignatures 
1745
#
1746
# Description     : Generate package signatures for dependent packages
1747
#                   Intended to be used by build systems 
1748
#
1749
# Inputs          : 
1750
#
1751
# Returns         : 
1752
#
1753
sub generatepkgSignatures
1754
{
1755
    my (@cmd_opts ) = @_;
1756
 
1757
    Getopt::Long::Configure('pass_through');
1758
    getOptionsFromArray ( \@cmd_opts,
1759
                          ) || Error ("Invalid command line" );
1760
    SubCommandHelp( $opt_help, 'Generate Package Signatures') if ($opt_help  );
1761
 
1762
    #
1763
    #   Calculate sandbox info
1764
    #   All data written will be based on this information
1765
    #
1766
    Message ("Generating Package Signatures");
1767
    calc_sandbox_info();
1768
    calc_signature_info();
1769
 
1770
    #
1771
    #   All done
1772
    #
1773
    exit(0);
1774
}
1775
 
1776
#-------------------------------------------------------------------------------
7319 dpurdie 1777
# Function        : calc_signature_info 
1778
#
1779
# Description     : Calculate signature information for all packages in the sandbox
1780
#                   Used to create build system information 
1781
#
1782
# Inputs          : Nothing 
1783
#
1784
# Returns         : Updates global data structures
1785
#                   The %packages item {si} will be set to one of:
1786
#                       1 - Have a prebuild package
1787
#                       2 - Have generated a signature, but do not have a prebuilt package
1788
#                       3 - Error generating the signature
1789
#                       4 - Excluded - Dependent package has no signature
1790
#                       5 - Excluded - Packages skipped or not active 
1791
#
1792
sub calc_signature_info
1793
{
7320 dpurdie 1794
    Debug("calc_signature_info");
1795
    SystemConfig(ExitOnError => 0);
7319 dpurdie 1796
    foreach my $fe ( @build_order )
1797
    {
7320 dpurdie 1798
        if (exists $fe->{si}) {
1799
            Debug("calc_signature_info. Exists $fe->{dname}, $fe->{si}");
1800
            next;
1801
        }
7319 dpurdie 1802
        if ( !$fe->{buildActive} || $fe->{buildSkip} ) {
1803
            $fe->{si} = 5;
7320 dpurdie 1804
            Debug("calc_signature_info. Skip $fe->{dname}");
7319 dpurdie 1805
            next;
1806
        }
1807
 
1808
        #
1809
        #   If this package has a signature file then we don't need to re-create it
1810
        #
1811
        my $result = 0;
1812
        my ($preBuilt, $haveSignature) = locatePreBuiltPackage($fe);
1813
        unless ($haveSignature) {
1814
            my $dir = $fe->{dir};
1815
            $result = JatsCmd( "-cd=$dir", 'build', 'signature');
7320 dpurdie 1816
            Debug("calc_signature_info. $fe->{dname} Build Signature. $result");
7319 dpurdie 1817
            }
1818
 
1819
        unless ($result) {
1820
            #
1821
            #   Signature generated OK
1822
            #
1823
            ($preBuilt, $haveSignature) = locatePreBuiltPackage($fe);
7320 dpurdie 1824
            Debug("calc_signature_info. $fe->{dname} Examine: $preBuilt, $haveSignature");
7319 dpurdie 1825
            if ($preBuilt) {
1826
                $fe->{si} = 1;
1827
                $fe->{signature} = $haveSignature;
1828
            } elsif ($haveSignature) {
1829
                $fe->{si} = 2;
1830
                $fe->{signature} = $haveSignature;
1831
            } else {
1832
                $result = 1;
1833
            }
1834
        }
1835
 
1836
        #
1837
        #   Error creating the signature
1838
        #   Mark this package and all those that depend on it
1839
        #   
1840
        if ($result) {
7320 dpurdie 1841
            Debug("calc_signature_info. Error $fe->{dname}");
7319 dpurdie 1842
            $fe->{si} = 3;
1843
            if ( exists($fe->{'usedBy'}))
1844
            {
1845
                foreach my $entry (@{$fe->{'usedBy'}}) {
1846
                    my $pe = $packages{$entry};
1847
                    $pe->{si} = 4; 
1848
                }
1849
            }
1850
        }
1851
    }
1852
}
1853
 
1854
#-------------------------------------------------------------------------------
6133 dpurdie 1855
# Function        : calc_rootFingerPrint 
1856
#
1857
# Description     : Calculate a finger print of all the directories in the
1858
#                   sandbox root.
1859
#                   
1860
#                   Used to determine if the user has added or remove a package
1861
#                   from the sandbox
1862
#
1863
# Inputs          : None
1864
#
1865
# Returns         : SHA1 hash
1866
#
1867
sub calc_rootFingerPrint
1868
{
1869
    my $fpSha1 = Digest->new("SHA-1");
1870
 
1871
    foreach my $pname ( glob("*") )
1872
    {
1873
        next if ( $pname =~ m~^\.~ );
1874
        next if ( $pname =~ m~dpkg_archive$~ );
1875
        next if ( $pname =~ m~^CVS$~ );
1876
        next unless ( -d $pname );
1877
 
1878
        $fpSha1->add($pname);
1879
 
1880
        #
1881
        #   Include stop files in fingerprint too
1882
        #
1883
        $fpSha1->add("$pname/stop" ) if ( -f "$pname/stop" ); 
1884
        $fpSha1->add("$pname/stop.$GBE_MACHTYPE" ) if ( -f "$pname/stop.$GBE_MACHTYPE" ); 
1885
 
1886
    }
1887
    return $fpSha1->hexdigest;
1888
}
1889
 
1890
#-------------------------------------------------------------------------------
227 dpurdie 1891
# Function        : cmd
1892
#
1893
# Description     : Execute a command in all the sandboxes
1894
#                       Locate the base of the sandbox
1895
#                       Locate all packages in the sandbox
1896
#                       Locate all build files in each sandbox
1897
#                       Determine build order
1898
#                       Issue commands for each sandbox in order
1899
#
255 dpurdie 1900
# Inputs          : Arguments passed to jats build
227 dpurdie 1901
#
1902
# Returns         : Will exit
1903
#
1904
sub cmd
1905
{
1329 dpurdie 1906
    my ($hcmd, @cmd_opts ) = @_;
7308 dpurdie 1907
    my $opt_reverse;
359 dpurdie 1908
 
1909
    Getopt::Long::Configure('pass_through');
7308 dpurdie 1910
    getOptionsFromArray ( \@cmd_opts,
1911
                          'reverse!' => \$opt_reverse,
1912
                          ) || Error ("Invalid command line" );
359 dpurdie 1913
    SubCommandHelp( $opt_help, $hcmd) if ($opt_help  );
1914
 
227 dpurdie 1915
    #
1916
    #   Determine Sandbox information
1917
    #   Populate global variables
1918
    #
1919
    calc_sandbox_info();
7308 dpurdie 1920
    if ($opt_reverse) {
1921
        @build_order = reverse @build_order;
1922
    }
227 dpurdie 1923
    foreach my $fe ( @build_order )
1924
    {
6133 dpurdie 1925
        my $active = displayHeader($fe, { showPath => 1 });
227 dpurdie 1926
 
6133 dpurdie 1927
        if ($active)
1928
        {
1929
            my $dir = $fe->{dir};
1930
            my $result = JatsCmd( "-cd=$dir", @cmd_opts);
1931
            if ( $result ) {
1932
                if ( $opt_keepgoing ) {
1933
                    Warning ("Cmd failure");
1934
                } else {
1935
                    Error   ("Cmd failure");
1936
                }
2054 dpurdie 1937
            }
1938
        }
227 dpurdie 1939
    }
1940
 
1941
    exit 0;
1942
}
1943
 
1944
#-------------------------------------------------------------------------------
331 dpurdie 1945
# Function        : buildcmd
1946
#
1947
# Description     : Build the entire sandbox
1948
#                   The all and the build are similar.
1949
#                   Its not really useful to do a build without a make
1950
#                   so we don't try
1951
#
1952
# Inputs          : Arguments passed to jats make
1953
#
1954
#
1955
# Returns         : Will exit
1956
#
1957
 
1958
sub buildcmd
1959
{
337 dpurdie 1960
    my ($cmd, @cmd_opts) = @_;
331 dpurdie 1961
    my @build_opts;
337 dpurdie 1962
    my @make_opts;
6133 dpurdie 1963
    my $opt_skip = 1;
1964
    my $opt_clean = 0;
331 dpurdie 1965
 
1966
    #
359 dpurdie 1967
    #   Extract and options
1968
    #
1969
    Getopt::Long::Configure('pass_through');
6133 dpurdie 1970
    getOptionsFromArray ( \@cmd_opts,
1971
                          'skip!' => \$opt_skip,
1972
                          'clean!' => \$opt_clean,
1973
    ) || Error ("Invalid command line" );
359 dpurdie 1974
    SubCommandHelp( $opt_help, "Command $cmd") if ($opt_help );
361 dpurdie 1975
 
359 dpurdie 1976
    #
331 dpurdie 1977
    #   Insert default options
1978
    #
1979
    push @build_opts, '-noforce' if ( $cmd eq 'all' );
6133 dpurdie 1980
    push @build_opts, '-force'   if ( $cmd ne 'all' );
331 dpurdie 1981
 
337 dpurdie 1982
    #
1983
    #   Attempt to split the options into build and make options
1984
    #   Only handle the often used options to build.
1985
    #
1986
    foreach  ( @cmd_opts )
1987
    {
1988
        if ( m/^-cache/ || m/^-package/ || m/^-forcebuildpkg/ || m/-expert/) {
1989
            push @build_opts, $_;
1990
        } else {
1991
            push @make_opts, $_;
1992
        }
1993
    }
1994
 
6133 dpurdie 1995
    push @make_opts, 'all'  unless ( @make_opts );
331 dpurdie 1996
 
1997
    #
1998
    #   Determine Sandbox information
1999
    #   Populate global variables
2000
    #
2001
    calc_sandbox_info();
2002
    foreach my $fe ( @build_order )
2003
    {
6133 dpurdie 2004
        my $active = displayHeader($fe, { showPath => 1 });
2005
        if ($active) {
331 dpurdie 2006
 
6133 dpurdie 2007
            #
2008
            #   Determine build success tag file
7319 dpurdie 2009
            #   If the tag file exists, then see if any files in the package source are more
6133 dpurdie 2010
            #   recent than the tag file
2011
            #
2012
            my $mustBuild = 1;
2013
            my $sigMatch = 0;
2014
            my $tagFile = getPkgFingerPrintFile($fe);
2015
 
2016
            if ( -e $tagFile ) {
2017
                if ( TagFileMatch($tagFile, genPkgFingerPrint($fe, 'Test')) ) {
2018
                    $sigMatch = 1;
2019
                    if ($opt_skip) {
2020
                        $mustBuild = 0;
2021
                    } else {
2022
                        $mustBuild = 2;
2023
                    }
2024
                } else {
2025
                }
2026
            } else {
2027
                    $mustBuild = 2;
2028
                    $sigMatch = -1;
2029
            }
2030
 
7301 dpurdie 2031
Debug0("Skip: $opt_skip, sigMatch: $sigMatch, Build: $mustBuild, Opts: @make_opts",);
6133 dpurdie 2032
            if ($mustBuild)
2033
            {
2034
                if (1)
2035
                {
2036
                    unlink $tagFile;
2037
                    my $dir = $fe->{dir};
2038
                    my $result;
2039
 
2040
                    $result = JatsCmd( "-cd=$dir", 'build', @build_opts);
2041
                    if ($result)
2042
                    {
2043
                        if ($opt_keepgoing)
2044
                        {
2045
                            Warning( "Build Cmd failure - Keep going");
2046
                            next;
2047
                        }
7307 dpurdie 2048
                        Error ("Build Cmd failure: $dir");
6133 dpurdie 2049
                    }
2050
 
2051
                    #
2052
                    #   Skip make if we have a prebuilt package
2053
                    #
2054
                    my $mustMake = 1;
7301 dpurdie 2055
                    if ($mustBuild == 2)
2056
                    {
2057
                        my $pbFound = locatePreBuiltPackage($fe);
2058
                        Debug0("Prebuilt: $pbFound");
2059
                        $mustMake = 0 if $pbFound;
2060
                    }
6133 dpurdie 2061
 
2062
                    if ($mustMake)
2063
                    {
2064
                        JatsCmd( "-cd=$dir", 'make', 'clean') if $opt_clean;
2065
                        $result = JatsCmd( "-cd=$dir", 'make',  @make_opts);
2066
                        if ($result)
2067
                        {
2068
                            if ($opt_keepgoing)
2069
                            {
2070
                                Warning( "Make Cmd failure - Keep going");
2071
                                next;
2072
                            }
7307 dpurdie 2073
                            Error ("Make Cmd failure: $dir");
6133 dpurdie 2074
                        }
2075
                    }
2076
                }
2077
 
7307 dpurdie 2078
                Verbose ("Save fingerprint: $tagFile");
6133 dpurdie 2079
                FileCreate( $tagFile, genPkgFingerPrint($fe,'Generation') );
2080
            }
2081
            else
2082
            {
2083
                Message ("No file changes since last build. Skipping")
2084
            }
2085
        }
331 dpurdie 2086
    }
2087
 
2088
    exit 0;
2089
}
2090
 
2091
#-------------------------------------------------------------------------------
273 dpurdie 2092
# Function        : clean
2093
#
2094
# Description     : Execute a command in all the sandboxes
2095
#                       Locate the base of the sandbox
2096
#                       Locate all packages in the sandbox
2097
#                       Locate all build files in each sandbox
2098
#                       Determine build order
2099
#                       Issue commands for each sandbox in order
2100
#
2101
# Inputs          : Arguments passed to jats build
2102
#
2103
# Returns         : Will exit
2104
#
2105
sub clean
2106
{
1329 dpurdie 2107
    my ($mode, @cmd_opts ) = @_;
359 dpurdie 2108
 
273 dpurdie 2109
    #
359 dpurdie 2110
    #   Extract and options
2111
    #
2112
    Getopt::Long::Configure('pass_through');
1329 dpurdie 2113
    getOptionsFromArray ( \@cmd_opts ) || Error ("Invalid command line" );
359 dpurdie 2114
    SubCommandHelp( $opt_help, "Clean") if ($opt_help );
2115
 
2116
    #
273 dpurdie 2117
    #   Determine Sandbox information
2118
    #   Populate global variables
2119
    #
2120
    calc_sandbox_info();
2121
 
2122
    my @cmd = $mode eq 'clobber' ? ('clobber') : ('make', 'clean' );
2123
 
2124
    #
2125
    #   Clobber and clean need to be done in the reverse order
2126
    #
2127
    foreach my $fe ( reverse @build_order )
2128
    {
6133 dpurdie 2129
        my $active = displayHeader($fe, { showPath => 1 });
2130
        if ($active)
2131
        {
2132
            my $dir = $fe->{dir};
2133
            my $result = JatsCmd( "-cd=$dir", @cmd, @cmd_opts);
2134
            if ($result)
2135
            {
2136
                if ($opt_keepgoing)
2137
                {
2138
                    Warning("Command Failure");
2139
                }
2140
                else
2141
                {
2142
                    Error ("Cmd failure") if ( $result );
2143
                }
2144
            }
2145
        }
273 dpurdie 2146
    }
2147
 
2148
    exit 0;
2149
}
2150
 
2151
 
2152
#-------------------------------------------------------------------------------
337 dpurdie 2153
# Function        : cache
2154
#
2155
# Description     : Cache external packages into the sandbox
2156
#
2157
# Inputs          : @opts                   - User options
2158
#
2159
# Returns         : Nothing
2160
#
2161
sub cache
2162
{
1329 dpurdie 2163
    my (@cmd_opts) = @_;
337 dpurdie 2164
 
1329 dpurdie 2165
    getOptionsFromArray ( \@cmd_opts ) || Error ("Invalid command line" );
2166
    SubCommandHelp( $opt_help, "Cache") if ($opt_help || $#cmd_opts >= 0 );
359 dpurdie 2167
 
337 dpurdie 2168
    #
2169
    #   Determine Sandbox information
2170
    #   Populate global variables
2171
    #
2172
    Message("Cache External Dependencies");
6133 dpurdie 2173
    Error ("GBE_DPKG_CACHE not defined") unless $GBE_DPKG_CACHE;
337 dpurdie 2174
    calc_sandbox_info();
2175
 
6133 dpurdie 2176
    JatsTool ('cache_dpkg', "core_devl/jats2_current" );
2177
 
337 dpurdie 2178
    #
1329 dpurdie 2179
    #   Walk the list of external dependencies and cache each one
337 dpurdie 2180
    #
2181
    foreach my $de ( sort keys %extern_deps )
2182
    {
2183
        my @vlist = keys %{$extern_deps{$de}};
359 dpurdie 2184
        foreach my $pve ( @vlist )
337 dpurdie 2185
        {
359 dpurdie 2186
            my ($pn,$pv) = split( $; , $pve );
2187
            Message ("Cache ${pn} ${pv}");
2188
            JatsTool ('cache_dpkg', "${pn}/${pv}" );
337 dpurdie 2189
        }
2190
    }
361 dpurdie 2191
 
337 dpurdie 2192
    exit 0;
361 dpurdie 2193
 
337 dpurdie 2194
}
2195
 
359 dpurdie 2196
#-------------------------------------------------------------------------------
2197
# Function        : populate
2198
#
2199
# Description     : Populate the sandbox with package versions
2200
#
2201
#
2202
# Inputs          : commands            - Array of command line arguments
2203
#                   Mode-0:
2204
#
2205
#                       pkg_name pkg_version        - Import files for named package
2206
#                       options:
2207
#                           -recurse                - Import dependent packages too
2208
#                           -missing                - Import dependencies not in dpkg_archive
2209
#                           -test                   - Show what would be done
2210
#                           -extractfiles           - Extract file, no view
2211
#
2212
#
2213
#
2214
#
2215
# Returns         : Does not return
2216
#
2217
use JatsRmApi;
2218
use DBI;
337 dpurdie 2219
 
359 dpurdie 2220
#
2221
#   Data Base Interface
2222
#
2223
my $RM_DB;
2224
my $PopLevel = 0;
2225
my %PopPackage;
2226
my @StrayPackages;
2227
my @PopBase;
2228
 
2229
sub populate
2230
{
1329 dpurdie 2231
    my (@cmd_opts ) = @_;
359 dpurdie 2232
    my $opt_missing = 0;
2233
    my $opt_recurse = 0;
2234
    my $opt_test = 0;
1329 dpurdie 2235
    my $opt_show = 0;
359 dpurdie 2236
    my $opt_extractfiles;
2237
    my @opt_extract = qw(-extract);
2238
    my @opt_fnames;
1329 dpurdie 2239
    my @opt_exclude;
2240
    my $opt_all;
359 dpurdie 2241
 
1329 dpurdie 2242
 
359 dpurdie 2243
    Getopt::Long::Configure('pass_through');
1329 dpurdie 2244
    getOptionsFromArray ( \@cmd_opts,
2245
                "all"               => \$opt_all,
2246
                "missing"           => \$opt_missing,
2247
                "test"              => \$opt_test,
2248
                "show"              => \$opt_show,
2249
                "recurse:100"       => \$opt_recurse,
2250
                'excludePackage:s'  => sub{ opts_add2List( \@opt_exclude, @_ )},
359 dpurdie 2251
                ) || Error ("Invalid command line" );
2252
 
2253
    SubCommandHelp( $opt_help, "Populate Sandbox") if ($opt_help );
2254
 
2255
    #
1329 dpurdie 2256
    #   Sanity tests
2257
    #
2258
    Error ("Populate: -missing and -all options are mutually exclusive")
2259
        if ( $opt_missing && $opt_all );
2260
 
2261
    #
359 dpurdie 2262
    #   Extract options for the jats extract utility
2263
    #
1329 dpurdie 2264
    foreach ( @cmd_opts )
359 dpurdie 2265
    {
2266
        if ( m~^-~ ) {
2267
            push ( @opt_extract, $_);
2268
        } else {
2269
            push ( @opt_fnames, $_);
2270
        }
2271
    }
2272
 
2273
    #
2274
    #   Allow exactly zero or two 'bare' arguments
2275
    #   Create an array of package-versions to be processed.
2276
    #
2277
    if ( $#opt_fnames >= 0 )
2278
    {
365 dpurdie 2279
        Error ("Populate: Must specify both a package name and version")
359 dpurdie 2280
            if ( $#opt_fnames != 1 );
2281
        push @PopBase, join( $;, @opt_fnames );
2282
    }
1329 dpurdie 2283
    elsif ( $opt_missing || $opt_all )
359 dpurdie 2284
    {
2285
        #
2286
        #   User has not provided a package name to extract
1329 dpurdie 2287
        #   Assume that the user will want all or missing dependencies
359 dpurdie 2288
        #
2289
        #   Determine packages that are not present
2290
        #
2291
        calc_sandbox_info();
2292
 
2293
        #
2294
        # Scan for missing dependencies
2295
        #
2296
        foreach my $de ( sort keys %extern_deps )
2297
        {
2298
            my @vlist = keys %{$extern_deps{$de}};
2299
            foreach my $pve ( @vlist )
2300
            {
2301
                my ($pn,$pv) = split( $; , $pve );
1329 dpurdie 2302
                unless ($opt_missing && check_package_existance( $pn, $pv ))
359 dpurdie 2303
                {
2304
                    push @PopBase, join( $;, $pn , $pv );
2305
                }
2306
            }
2307
        }
2308
    }
2309
    else
2310
    {
2311
        Error ("No command or option specified. See help for command usage");
2312
    }
2313
 
2314
    #
2315
    #   Process the list of package-versions
2316
    #   These are top level packages. Get details from Release Manager
2317
    #
2318
    #DebugDumpData("Data", \@PopBase );
2319
    $PopLevel = 0;
2320
    foreach my $entry ( @PopBase )
2321
    {
2322
        my ($pname, $pver ) = split( $; , $entry);
2323
 
2324
        my $pv_id = getPkgDetailsByName($pname, $pver);
2325
        Error ("populate: $pname, $pver not found in Release Manager" )
2326
            unless ( $pv_id );
2327
        getPkgDetailsByPV_ID($pv_id);
2328
    }
2329
    #
2330
    #   If recursing then process packages that have yet to
2331
    #   be processed. At the start there will be the initial user specified
2332
    #   packages on the list. Place a marker at the end so that we can
2333
    #   determine how far we are recursing down the dependency tree.
2334
    #
1329 dpurdie 2335
    $opt_recurse = ($opt_all ? 100 : $opt_recurse);
359 dpurdie 2336
    if ( $opt_recurse )
2337
    {
2338
        my $marker = join($; , '_NEXT_LEVEL_', 0, 0 );
2339
        push @StrayPackages, $marker;
2340
        $PopLevel++;
2341
 
2342
        while ( $#StrayPackages >= 0 )
2343
        {
2344
            my ($name, $ver, $pv_id) = split($;, shift @StrayPackages);
2345
 
2346
            #
2347
            #   Marker.
2348
            #   Increment the level of recursion
2349
            #   Detect end conditions
2350
            #
2351
            if ( $name eq '_NEXT_LEVEL_' )
2352
            {
2353
                last unless ($#StrayPackages >= 0 );
2354
                $PopLevel++;
2355
                last if ( $PopLevel > $opt_recurse );
2356
                push @StrayPackages, $marker;
2357
                next;
2358
            }
2359
 
2360
            next if ( exists $PopPackage{$name}{$ver}{done} );
2361
            getPkgDetailsByPV_ID ( $pv_id );
2362
            #print "Stray: $pv_id, $name, $ver\n";
2363
        }
2364
    }
2365
    #DebugDumpData("Data", \%PopPackage );
2366
 
2367
    #
2368
    #   Determine packages that need to be extracted
1329 dpurdie 2369
    #   Sort alphabetically - case insensitive
359 dpurdie 2370
    #
1329 dpurdie 2371
    foreach my $pname ( sort {lc($a) cmp lc($b)} keys %PopPackage )
359 dpurdie 2372
    {
1329 dpurdie 2373
        pkgscan:
359 dpurdie 2374
        foreach my $pver ( sort keys %{$PopPackage{$pname}} )
2375
        {
2376
            #
2377
            #   Create a nice view name for the extraction
365 dpurdie 2378
            #   Will also be used to test for package existence
359 dpurdie 2379
            #
2380
            my $vname = "$pname $pver";
2381
            $vname =~ s~ ~_~g;
2382
            $vname =~ s~__~~g;
2383
 
2384
            if ( -d "$GBE_SANDBOX/$vname" )
2385
            {
2386
                Warning("Package already in sandbox: $pname, $pver");
2387
                next;
2388
            }
2389
 
2390
            #
2391
            #   If scanning for missing packages, then examine archives
2392
            #   for the packages existence. Don't do this on level-0 packages
2393
            #   These have been user specified.
2394
            #
2395
            if ( $opt_missing && $PopPackage{$pname}{$pver}{level}  )
2396
            {
2397
                my $found = check_package_existance( $pname, $pver );
2398
                if ( $found )
2399
                {
2400
                    Verbose ("Package found in archive - skipped: $pname, $pver");
2401
                    next;
2402
                }
2403
            }
2404
 
2405
            #
1329 dpurdie 2406
            #   Has the user specifically excluded this package
2407
            #   Allow three forms
2408
            #       packageName
2409
            #       packageName_Version
2410
            #       packageName.projectName
2411
            #
2412
            my $excluded;
2413
            foreach my $ename ( @opt_exclude )
2414
            {
2415
                if ( $ename eq $pname ) {
2416
                    $excluded = 1;
2417
                } elsif ($ename eq $pname .'_' . $pver ) {
2418
                    $excluded = 1;
2419
                } else {
2420
                    if ( $pver =~ m~(\.[a-z]{2,4})$~ )
2421
                    {
2422
                        $excluded = ($ename eq $pname . $1 );
2423
                    }
2424
                }
2425
 
2426
                if ( $excluded )
2427
                {
2428
                    Message ("Package excluded by user - skipped: $pname, $pver");
2429
                    next pkgscan;
2430
                }
2431
            }
2432
 
2433
            #
359 dpurdie 2434
            #   Generate commands to extract the package
2435
            #
2436
            my $vcstag = $PopPackage{$pname}{$pver}{vcstag};
2437
            my @cmd = qw(jats_vcsrelease);
2438
            push @cmd, "-view=$vname", "-label=$vcstag", @opt_extract;
1329 dpurdie 2439
            if ( $opt_show )
359 dpurdie 2440
            {
1329 dpurdie 2441
                Message ("$pname $pver");
2442
            }
2443
            elsif ( $opt_test )
2444
            {
359 dpurdie 2445
                Message "jats " . QuoteCommand (@cmd );
2446
            }
2447
            else
2448
            {
2449
                Message "Extracting: $pname $pver";
2450
                my $rv = JatsCmd (@cmd);
2451
                Error ("Package version not extracted")
2452
                    if ( $rv );
2453
            }
2454
        }
2455
    }
2456
 
2457
    #
2458
    # This command does not return
2459
    #
2460
    exit (0);
2461
}
2462
 
337 dpurdie 2463
#-------------------------------------------------------------------------------
4197 dpurdie 2464
# Function        : buildfilter 
2465
#
2466
# Description     : Manipulate the sandbox build filter
2467
#
2468
# Inputs          : Optional filter names
2469
#                       +NAME - will add filter
2470
#                       -NAME will remove it
2471
#                       NAME will set it
2472
#                   No args will just display the build filter
2473
#
2474
# Returns         : Does not return
2475
#
2476
sub buildfilter
2477
{
2478
    my (@cmd_opts ) = @_;
2479
    my @filter_list;
2480
    my $first_arg = 1;
2481
    my $modified;
2482
 
2483
    Getopt::Long::Configure('pass_through');
2484
    getOptionsFromArray ( \@cmd_opts ) || Error ("Invalid command line" );
2485
 
2486
    SubCommandHelp( $opt_help, "Buildfilter") if ($opt_help );
2487
 
2488
    #
2489
    #   Set the initial filter list
2490
    #   This will have been parsed by JATS before we get here
2491
    #
7323 dpurdie 2492
    UniquePush (\@filter_list, split( /[,\s]+/, join(',', $GBE_BUILDFILTER)));
4197 dpurdie 2493
 
2494
    #
2495
    #   Extract options for the jats extract utility
2496
    #
2497
    foreach ( @cmd_opts )
2498
    {
2499
        if (m~^\+(.*)~)
2500
        {
2501
            UniquePush( \@filter_list, $1);
2502
        }
2503
        elsif (m~^\-(.*)~)
2504
        {
2505
            ArrayDelete( \@filter_list, $1);
2506
        }
2507
        else
2508
        {
2509
            @filter_list = () if ($first_arg);
2510
            UniquePush( \@filter_list, $_);
2511
        }
2512
        $first_arg = 0;
2513
        $modified = 1;
2514
    }
2515
 
2516
    #
2517
    #   Display the results to the user
2518
    #
7323 dpurdie 2519
    @filter_list = sort @filter_list;
4197 dpurdie 2520
    Message('BuildFilter:', @filter_list);
2521
 
2522
    #
2523
    #   Write out a new file
2524
    #
2525
    if ($modified)
2526
    {
7323 dpurdie 2527
        Error ("Command must be executed from within a Sandbox") unless ( $GBE_SANDBOX );
7306 dpurdie 2528
        FileCreate($filterFile, @filter_list);
4197 dpurdie 2529
    }
2530
 
2531
    #
2532
    # This command does not return
2533
    #
2534
    exit (0);
2535
}
2536
 
2537
 
2538
#-------------------------------------------------------------------------------
359 dpurdie 2539
# Function        : getPkgDetailsByName
2540
#
2541
# Description     : Determine the PVID for a given package name and version
2542
#
2543
# Inputs          : $pname          - Package name
2544
#                   $pver           - Package Version
2545
#
361 dpurdie 2546
# Returns         :
359 dpurdie 2547
#
2548
 
2549
sub getPkgDetailsByName
2550
{
2551
    my ($pname, $pver) = @_;
2552
    my $pv_id;
2553
    my (@row);
2554
 
2555
    connectRM(\$RM_DB) unless ($RM_DB);
2556
 
2557
    # First get details for a given package version
2558
 
2559
    my $m_sqlstr = "SELECT pv.PV_ID, pkg.PKG_NAME, pv.PKG_VERSION" .
2560
                    " FROM RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg" .
2561
                    " WHERE pkg.PKG_NAME = \'$pname\' AND pv.PKG_VERSION = \'$pver\' AND pv.PKG_ID = pkg.PKG_ID";
2562
    my $sth = $RM_DB->prepare($m_sqlstr);
2563
    if ( defined($sth) )
2564
    {
2565
        if ( $sth->execute( ) )
2566
        {
2567
            if ( $sth->rows )
2568
            {
2569
                while ( @row = $sth->fetchrow_array )
2570
                {
2571
                    $pv_id = $row[0];
2572
                    my $name = $row[1];
2573
                    my $ver = $row[2];
2574
                    Verbose( "getPkgDetailsByName :PV_ID= $pv_id");
2575
                }
2576
            }
2577
            $sth->finish();
2578
        }
2579
    }
2580
    else
2581
    {
2582
        Error("Prepare failure" );
2583
    }
2584
    return $pv_id;
2585
}
2586
 
2587
#-------------------------------------------------------------------------------
2588
# Function        : getPkgDetailsByPV_ID
2589
#
2590
# Description     : Populate the Packages structure given a PV_ID
2591
#                   Called for each package in the SBOM
2592
#
2593
# Inputs          : PV_ID           - Package Unique Identifier
2594
#
2595
# Returns         : Populates Package
2596
#
2597
sub getPkgDetailsByPV_ID
2598
{
2599
    my ($PV_ID) = @_;
2600
    my $foundDetails = 0;
2601
    my (@row);
2602
 
2603
    connectRM(\$RM_DB) unless ($RM_DB);
2604
 
2605
    # First get details from pv_id
2606
 
2607
    my $m_sqlstr = "SELECT pv.PV_ID, pkg.PKG_NAME, pv.PKG_VERSION, release_manager.PK_RMAPI.return_vcs_tag($PV_ID)" .
2608
                    " FROM RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg " .
2609
                    " WHERE pv.PV_ID = \'$PV_ID\' AND pv.PKG_ID = pkg.PKG_ID";
2610
 
2611
    my $sth = $RM_DB->prepare($m_sqlstr);
2612
    if ( defined($sth) )
2613
    {
2614
        if ( $sth->execute( ) )
2615
        {
2616
            if ( $sth->rows )
2617
            {
2618
                while ( @row = $sth->fetchrow_array )
2619
                {
2620
                    my $pv_id       = $row[0];
2621
                    my $name        = $row[1];
2622
                    my $ver         = $row[2];
2623
                    my $vcstag      = $row[3] || '';
2624
 
2625
                    $vcstag =~ tr~\\/~/~;
2626
                    Verbose ("getPkgDetailsByPV_ID: $PV_ID, $name, $ver, $vcstag");
2627
 
2628
                    $PopPackage{$name}{$ver}{pvid} = $PV_ID;
2629
                    $PopPackage{$name}{$ver}{done} = 1;
2630
                    $PopPackage{$name}{$ver}{vcstag} = $vcstag;
2631
                    $PopPackage{$name}{$ver}{level} = $PopLevel;
2632
                    getDependsByPV_ID( $pv_id, $name, $ver );
2633
                }
2634
            }
2635
            else
2636
            {
2637
                Warning ("No Package details for: PVID: $PV_ID");
2638
            }
2639
            $sth->finish();
2640
        }
2641
        else
2642
        {
2643
            Error("getPkgDetailsByPV_ID: Execute failure", $m_sqlstr );
2644
        }
2645
    }
2646
    else
2647
    {
2648
        Error("Prepare failure" );
2649
    }
2650
}
2651
 
2652
#-------------------------------------------------------------------------------
2653
# Function        : getDependsByPV_ID
2654
#
2655
# Description     : Extract the dependancies for a given package version
2656
#
2657
# Inputs          : $pvid
2658
#
2659
# Returns         :
2660
#
2661
sub getDependsByPV_ID
2662
{
2663
    my ($pv_id, $pname, $pver) = @_;
2664
 
2665
    connectRM(\$RM_DB) unless ($RM_DB);
2666
 
2667
    #
365 dpurdie 2668
    #   Now extract the package dependencies
359 dpurdie 2669
    #
2670
    my $m_sqlstr = "SELECT pkg.PKG_NAME, pv.PKG_VERSION, pd.DPV_ID" .
2671
                   " FROM RELEASE_MANAGER.PACKAGE_DEPENDENCIES pd, RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg" .
2672
                   " WHERE pd.PV_ID = \'$pv_id\' AND pd.DPV_ID = pv.PV_ID AND pv.PKG_ID = pkg.PKG_ID";
2673
    my $sth = $RM_DB->prepare($m_sqlstr);
2674
    if ( defined($sth) )
2675
    {
2676
        if ( $sth->execute( ) )
2677
        {
2678
            if ( $sth->rows )
2679
            {
2680
                while ( my @row = $sth->fetchrow_array )
2681
                {
2682
                    my $name = $row[0];
2683
                    my $ver = $row[1];
2684
 
2685
                    Verbose2( "       Depends: $name, $ver");
2686
                    unless ( exists $PopPackage{$name} && exists $PopPackage{$name}{$ver} && exists $PopPackage{$name}{$ver}{done} )
2687
                    {
2688
                        push @StrayPackages, join($;, $name, $ver, $row[2] );
2689
                    }
2690
                }
2691
            }
2692
            $sth->finish();
2693
        }
2694
    }
2695
    else
2696
    {
2697
        Error("GetDepends:Prepare failure" );
2698
    }
2699
}
2700
 
2701
#-------------------------------------------------------------------------------
1329 dpurdie 2702
# Function        : getOptionsFromArray
2703
#
2704
# Description     : Like getOptions, but handles an array
2705
#                   Provided as the version of Perl used does not have one
2706
#
2707
# Inputs          : pArray                  - Ref to array
2708
#                   ....                    - GetOptions arguments
2709
#
2710
# Returns         : 
2711
#
2712
sub getOptionsFromArray
2713
{
2714
    my ($pArray, %args) = @_;
2715
 
2716
    #
7307 dpurdie 2717
    #   Helper to parse --multiBuilders
2718
    #
2719
    my $parseMulti = sub {
2720
        my ($ref, $value) = @_;
2721
        $value = 'error' unless length($value);
2722
        my %valid = (error => 0, report => 1, ignore => 2);
2723
        unless (exists $valid{lc $value}) {
2724
            die ("Invalid option for  --$ref->{name}\n");
2725
        };
2726
        $opt_multiBuilders = $valid{lc $value};
2727
    };
2728
 
2729
 
2730
    #
1329 dpurdie 2731
    #   Common arguments
2732
    #
2733
    my %commonOptions = (
2734
        'help|h:+'          => \$opt_help,
2735
        'manual:3'          => \$opt_help,
2736
        'verbose:+'         => \$opt_verbose,
2737
        'topackage:s'       => \$opt_toPackage,
2738
        'frompackage:s'     => \$opt_fromPackage,
2739
        'justpackage:s'     => sub{ opts_add2List( \@opt_justPackage, @_ )},
2740
        'ignorepackage:s'   => sub{ opts_add2List( \@opt_ignorePackage, @_ )},
6133 dpurdie 2741
        'entireSandBox!'    => \$opt_allSandbox,
2742
        'users!'            => \$opt_processUsedBy,
2743
        'keepgoing!'        => \$opt_keepgoing,
2744
        'rescan!'           => \$opt_reScan,
7307 dpurdie 2745
        'multiBuilders:s'   => $parseMulti, 
7319 dpurdie 2746
        'onlylevel:i'       => \$opt_onlyLevel,
1329 dpurdie 2747
        );
2748
 
2749
    #
2750
    #   Merge in the user options
2751
    #
2752
    @commonOptions{keys %args} = values %args;
2753
 
2754
    local ( @ARGV );
2755
    @ARGV = @$pArray;
2756
    my $rv = GetOptions ( %commonOptions );
2757
    @$pArray = @ARGV;
2758
 
2759
    ErrorConfig('verbose' => $opt_verbose );
2760
    return $rv;
2761
}
2762
 
2763
#-------------------------------------------------------------------------------
6133 dpurdie 2764
# Function        : displayHeader 
2765
#
7307 dpurdie 2766
# Description     : Display a build header, if the entry is active
2767
#                   ie: Between a --From and --To
6133 dpurdie 2768
#
2769
# Inputs          : $fe             - Build entry
7307 dpurdie 2770
#                   Hash of options
2771
#                       indent          => Text       - Indent text
2772
#                       showPath        => Bool
2773
#                       showSimplePath  => Bool
2774
#                       testFingerPrint => Bool
6133 dpurdie 2775
#
2776
# Returns         : True if this entry is to be fully process
7319 dpurdie 2777
#                   False if its being skipped
2778
#                   
2779
#                   The entry may be have a buildError or a buildExclude
2780
#                   and still be active
6133 dpurdie 2781
#
2782
sub displayHeader
2783
{
2784
    my $fe = shift @_;
7307 dpurdie 2785
    if ($fe->{buildActive} || $fe->{buildSkip})
2786
    {
2787
        my $args = pop @_ if (@_ > 0 and UNIVERSAL::isa($_[-1],'HASH'));
2788
        #    my ($fe, %args) = @_;
6133 dpurdie 2789
 
7307 dpurdie 2790
        my $indent = $args->{indent} || '';
2791
        my $showPath = $args->{showPath};
2792
        my $showSimplePath = $args->{showSimplePath};
6133 dpurdie 2793
 
7307 dpurdie 2794
        my ($status, $estatus) = addBuildInfo($fe, $args);
2795
        $estatus = '' if $showSimplePath;
2796
 
2797
        my $msg1 = $indent . sprintf('Level:%02d [%s] Name: %s', $fe->{level}, $status, $fe->{dname} . $estatus );
2798
        if ($showSimplePath) {
2799
            my $msg1Len = length($msg1);
2800
            $msg1 = sprintf("%-*s Path: %s", 26 + $maxDname ,$msg1, $fe->{dir}); 
6133 dpurdie 2801
        }
7307 dpurdie 2802
        if ( $showPath) {
2803
            my $msg1Len = length($msg1);
2804
            if ($msg1Len < 80) {
2805
                $msg1 .= ' ' . '=' x (79 - $msg1Len);
2806
            }
2807
        }
2808
        Message( $msg1 ,  $showPath ? DisplayPath ("        Path: $fe->{dir}" ) : undef);
6133 dpurdie 2809
    }
2810
 
2811
   return $fe->{buildActive};
2812
}
2813
 
2814
#-------------------------------------------------------------------------------
2815
# Function        : addBuildInfo 
2816
#
2817
# Description     : Add some build info status
2818
#                   It will have a .sig file if its been sucessfully built
7319 dpurdie 2819
#                   
2820
#                   StatusFlags
2821
#                   Position 1: S - Build Skipped, s - Build Suppressed
2822
#                   Position 2: Blank - Not processed  , - = NoBuild, B - Built * - Current package
2823
#                   Position 3: P - Prebuilt, L - Local, M - Both local and prebuilt
2824
#                   Position 4: G - Good Fingerprint, b - Bad Fingerprint
6133 dpurdie 2825
#
2826
# Inputs          : $fe     - Package info 
2827
#
7319 dpurdie 2828
# Returns         : StatusFlags
2829
#                   StatusText
6133 dpurdie 2830
#
2831
sub addBuildInfo
2832
{
2833
    my ($fe, $args) = @_;
2834
    my $txt = '';
7319 dpurdie 2835
    my $statusS = ' ';
6133 dpurdie 2836
    my $statusB = ' ';
7319 dpurdie 2837
    my $statusP = ' ';
6133 dpurdie 2838
    my $statusF = ' ';
2839
 
2840
    unless ($fe->{buildActive}) {
2841
        $txt .= ($fe->{buildSkip}) ? ' (Build Skipped)' : ' (Build Suppressed)';
2842
        $statusS = ($fe->{buildSkip}) ? 'S' : 's';
2843
    }
2844
 
7319 dpurdie 2845
    if ($fe->{buildError} || $fe->{buildExclude} ) {
2846
        $txt .= ($fe->{buildError})   ? ' (Build Error)' : '';
2847
        $txt .= ($fe->{buildExclude}) ? ' (Build Excluded)' : '';
2848
        $statusS = ($fe->{buildError}) ? 'E' : 'e';
2849
    }
2850
 
2851
 
6133 dpurdie 2852
    if ($fe->{buildCurrent})
2853
    {
2854
        $statusB = '*';
2855
        $txt .= ' (Current Package)';
2856
    }
2857
 
7319 dpurdie 2858
    my $fpFile = getPkgFingerPrintFile($fe);
2859
    if (-f $fpFile)
6133 dpurdie 2860
    {
7319 dpurdie 2861
        my $nobFile = $fpFile;
7312 dpurdie 2862
        $nobFile =~ s~ffp$~nob~;
2863
        if (-f $nobFile) {
6133 dpurdie 2864
            $txt .= ' [NoBuild]';
2865
            $statusB = '-';
2866
        } else {
2867
            $txt .= ' [Built]';
2868
            $statusB = 'B';
2869
        }
7319 dpurdie 2870
    }
6133 dpurdie 2871
 
7319 dpurdie 2872
    if ($args->{testFingerPrint})
2873
    {
2874
        if ( TagFileMatch($fpFile, genPkgFingerPrint($fe, 'Test')) )
6133 dpurdie 2875
        {
7319 dpurdie 2876
            $txt .= ' [GoodFinger]';
2877
            $statusF = 'G';
2878
        } else {
2879
            $txt .= ' [BadFinger]';
2880
            $statusF = 'b';
6133 dpurdie 2881
        }
2882
    }
2883
 
7319 dpurdie 2884
    my ($preBuilt, $haveSignature) = locatePreBuiltPackage($fe);
2885
    if ($haveSignature) {
2886
        $txt .= ' [SigCalc]';
2887
        $statusP = 's';
2888
    }
7312 dpurdie 2889
    if ($preBuilt) {
2890
        $txt .= ' [PreBuilt]';
2891
        $statusP = 'P';
7319 dpurdie 2892
    }
2893
 
7320 dpurdie 2894
    unless ($GBE_ABT) {
2895
        my $plink = catdir( $GBE_DPKG_SBOX, $fe->{name}, 'sandbox.' . $fe->{prj} . '.lnk' );
2896
        my $linkTarget = getPackageLink ($plink);
2897
        Verbose ("Sandbox link: $plink -> $linkTarget");
2898
        if (-d $linkTarget) {
2899
            $txt .= ' [Local]';
2900
            if ($preBuilt) {
2901
                $statusP = 'M';
2902
            } else {
2903
                $statusP = 'L';
2904
            }
7319 dpurdie 2905
        }
2906
    }
7312 dpurdie 2907
 
2908
    return "$statusS$statusB$statusP$statusF", $txt ;
6133 dpurdie 2909
}
2910
 
2911
#-------------------------------------------------------------------------------
1329 dpurdie 2912
# Function        : opts_add2List
2913
#
2914
# Description     : Option processing helper
2915
#                   Add comma separated options to an array
2916
#                   User can then add items one at a time, or several at once
2917
#
2918
# Inputs          : aref        - Ref to an array to extent
2919
#                   arg2        - Option name
2920
#                   arg3        - Option value
2921
#
2922
# Returns         : 
2923
#
2924
sub opts_add2List
2925
{
2926
    my( $ref, $name, $value) = @_;
2927
    if ( $value )
2928
    {
2929
        foreach ( split(/\s*,\s*/,$value) )
2930
        {
2931
            push @{$ref}, $_;
2932
        }
2933
    }
2934
}
2935
 
2936
#-------------------------------------------------------------------------------
6133 dpurdie 2937
# Function        : genPkgFingerPrint 
2938
#
2939
# Description     : Generate a fingerprint over all files in the packages tree as
2940
#                   well as the package dependencies
2941
# 
2942
#                   Only used to detect changes to files in the subdir
2943
# 
2944
#                   This version does not actually generate a fingerprint over
2945
#                   the data file, rather the metadata of the file. This is much (much)
2946
#                   faster as there is no file i/o.
2947
#                   
2948
#                   It does assume that the file metadata will change if the file is changed
2949
#                   Will also detect the addition / deletion of files
2950
#                   
7312 dpurdie 2951
#                   Note: This signature is not machine - type safe
6133 dpurdie 2952
#                         It will vary between machines (windows/Linux/...)
7312 dpurdie 2953
#                         At the moment the Sandbox is really a single machine tool
6133 dpurdie 2954
#
2955
# Inputs          : $fe            - Package entry of the package to process
2956
#                   $mode          - Diagnostic: mode
2957
#
2958
# Returns         : A SHA1 hash over all the files
2959
#                   
2960
#
2961
sub genPkgFingerPrint
2962
{
2963
    my ($fe, $mode) = @_;
2964
    my $genPkgFingerPrintSha1;
2965
    my $genPkgFingerPrintCount;
2966
    my @fpdata;
2967
 
2968
    #
2969
    #   Get the package GbeFiles.cfg file
2970
    #       This is held in the interface directory and is created during the build
2971
    #       Since the fingerprint is only genertated AFTER a successful build the file will always
2972
    #       be available
2973
    #       
2974
    #       All we need from this file is a list of Src directories that were discovered during
2975
    #       the build. Unfortuanatley they are not always below the root of the package.
2976
    #
2977
    my $ifaceDir = getpkgInterface($fe);
2978
    return 0 unless defined $ifaceDir;
2979
    return 0 unless ToolsetFiles::GetDataFile($ifaceDir); 
2980
 
2981
    #
2982
    #   Generate a list of directories in the package
2983
    #   This is the root directory and all other Src directories discovered
2984
    #
2985
    my @dirList = ToolsetFiles::GetSubTrees($ifaceDir);
2986
    Error ("Internal:ToolsetFiles::GetDirList for $fe->{dname} not populated" ) unless @dirList;
2987
 
2988
    #
7312 dpurdie 2989
    #   Generate a hash of toolset files and toolset-internal directories
2990
    #       These won't be included in the finger print as they are subject
2991
    #       to change by a 'build'.
2992
    #
2993
    my %toolsetFiles = map { $_ => 1 } ToolsetFiles::GetFiles($ifaceDir, 1);
2994
    my %toolsetDirs  = map { $_ => 1 } ToolsetFiles::GetBuildDirs($ifaceDir);
2995
 
2996
    #
6133 dpurdie 2997
    #   Create the hash
2998
    #
2999
    $genPkgFingerPrintSha1 = Digest->new("SHA-1");
3000
    push @fpdata, $mode;
3001
 
3002
    #
3003
    #   Include all dependent packages in the fingerprint
3004
    #       We are using the sandbox fingerprint of dependent packages
3005
    #       This will ensure that a change in a package will ripple through
3006
    #
3007
    foreach my $idep ( sort keys %{$fe->{ideps}})
3008
    {
3009
        my $ipkg = $packages{$idep};
3010
        my $tagFile = getPkgFingerPrintFile($ipkg); 
3011
        my $tag = TagFileRead($tagFile);
3012
        my $text = "$tagFile: $tag";
3013
        $genPkgFingerPrintSha1->add($text);
3014
#Debug0("genPkgFingerPrint: $text, ", $genPkgFingerPrintSha1->clone->hexdigest() );
3015
        push @fpdata, $text . ':' . $genPkgFingerPrintSha1->clone->hexdigest();
3016
    }
3017
 
3018
    #
3019
    #   Anonymous sub: findFile wanted function
3020
    #   Unlike the generation of the package signature, we don't need to
3021
    #   exclude any files.
3022
    #
3023
    my $wanted = sub {
3024
        my $item = $File::Find::name;
3025
 
3026
        #
3027
        #   Get file info
3028
        #       Kill of the last access time - not useful
3029
        #       
3030
        #       Need to exclude files that change during a null build
3031
        #           /interface/GbeFiles.cfg
3032
        #           /build.log
7312 dpurdie 3033
        #           These files are tracked in GbeBuild.cfg
3034
        #       Need to directories that change during a null build
3035
        #           These files are tracked in GbeBuild.cfg
6133 dpurdie 3036
        #           
3037
        #       Symlinks present problems.
3038
        #       Some packages generate symlinks as they create file system images. The
3039
        #       links are not designed to be interpreted in the context of the current
3040
        #       computer. As a result.
3041
        #           Some may be broken - on the current machine
3042
        #           Some may address files that change - ie: /proc, /var, /dev
3043
        #           Some may address files that such as /afc, /root
3044
        #       Don't want to discard all symlinks. Many of them will address package
3045
        #       dependencies and we do want to detect changes, but those changes will
3046
        #       be picked up by the packages fingerprint.
3047
        #       
3048
        #       Directories also appear to be a problem
3049
        #       The created and modified date-times appear to be modified for no good reason
3050
        #       
3051
        #       Current solution: Do not include 'stat' data for ANY symlink or directory
3052
        #
3053
        my @data = stat($item);
3054
        my $text;
7312 dpurdie 3055
 
3056
        if ( exists $toolsetFiles{$item}) {
6133 dpurdie 3057
            $text = "$item : SKIPPED FILE : ";
3058
 
3059
        }  elsif (-d $item ) {
7312 dpurdie 3060
            $text = "$item : DIRECTORY";
3061
            if ( exists $toolsetDirs{$item}) {
3062
                $File::Find::prune = 1;
3063
                $text = "$item : SKIP INTERNAL DIRECTORY";
3064
            }
3065
 
6133 dpurdie 3066
        }  elsif (-l $item ) {
3067
            if ( ! @data) {
3068
                $text = "$item : BROKEN SYMLINK : ";
3069
            } else {
3070
                my $linkTarget = readlink($item) || 'Read Error';
3071
                $text = "$item :SYMLINK: $linkTarget";
3072
            }
3073
 
3074
        } else {
3075
            $data[8] = 0;               # atime - will change
3076
            $data[12] = '-';            # blocks - seen to change for unknown reasons
7323 dpurdie 3077
            for my $ii ( 0 .. $#data) {
3078
                unless (defined $data[$ii]) {
3079
                    $data[$ii] = 'xx';
3080
                }
3081
            }
6133 dpurdie 3082
            $text = "$item : @data";
3083
        }
3084
        $genPkgFingerPrintCount++;
3085
        $genPkgFingerPrintSha1->add($text);
3086
#Debug0("genPkgFingerPrint: $text, ", $genPkgFingerPrintSha1->clone->hexdigest() );
3087
        push @fpdata, $text . ':' . $genPkgFingerPrintSha1->clone->hexdigest();
3088
    };
3089
 
3090
    #
3091
    #   Process all files in the package
3092
    #
3093
    $genPkgFingerPrintCount = 0;
3094
    my $dir = $fe->{dir};
3095
    File::Find::find( { wanted => $wanted , no_chdir => 1}, @dirList );
3096
#Debug0("genPkgFingerPrint: $dir, $genPkgFingerPrintCount, ", $genPkgFingerPrintSha1->clone->hexdigest() );
3097
    push @fpdata, $dir . ':'. $genPkgFingerPrintCount . ':' . $genPkgFingerPrintSha1->clone->hexdigest();
3098
 
3099
    #
3100
    #   Debugging - delete later
3101
    #   Save FP data to a file
3102
    #
7301 dpurdie 3103
    my $fpDebugFile = catdir($GBE_SANDBOX, 'sandbox_dpkg_archive', $fe->{name} . '.' . $fe->{prj} . '_' . time() . '.fpd');
7312 dpurdie 3104
#Debug0("fpDebugFile: $fpDebugFile");
7301 dpurdie 3105
    FileCreate($fpDebugFile, @fpdata);
6133 dpurdie 3106
 
3107
    return $genPkgFingerPrintSha1->hexdigest;
3108
}
3109
 
3110
 
3111
#-------------------------------------------------------------------------------
3112
# Function        : getPkgFingerPrintFile 
3113
#
3114
# Description     : Return the package file that contains the packages Fast Finger Print
3115
#
3116
# Inputs          : $fe     - Package entry 
3117
#
3118
# Returns         : Full path to the packages fingerprint tag file
3119
#
3120
sub getPkgFingerPrintFile
3121
{
3122
    my ($fe) = @_;
3123
    my $tagFile = catdir($GBE_SANDBOX, 'sandbox_dpkg_archive', $fe->{name}, 'sandbox.' . $fe->{prj} . '.ffp');
3124
    return $tagFile;
3125
}
3126
 
3127
 
3128
#-------------------------------------------------------------------------------
359 dpurdie 3129
# Function        : SubCommandHelp
3130
#
3131
# Description     : Provide help on a subcommand
3132
#
3133
# Inputs          : $help_level             - Help Level 1,2,3
3134
#                   $topic                  - Topic Name
3135
#
3136
# Returns         : This function does not return
3137
#
3138
sub SubCommandHelp
3139
{
3140
    my ($help_level, $topic) = @_;
3141
    my @sections;
3142
    #
3143
    #   Spell out the section we want to display
3144
    #
3145
    #   Note:
3146
    #   Due to bug in pod2usage can't use 'head1' by itself
3147
    #   Each one needs a subsection.
3148
    #
3149
    push @sections, qw( NAME SYNOPSIS ) ;
3150
    push @sections, qw( ARGUMENTS OPTIONS )     if ( $help_level > 1 );
3151
    push @sections, qw( DESCRIPTION EXAMPLES )  if ( $help_level > 2 );
3152
 
3153
    #
3154
    #   Extract section from the POD
3155
    #
3156
    pod2usage({-verbose => 99,
3157
               -noperldoc => 1,
3158
               -sections => $topic . '/' . join('|', @sections) } );
3159
}
3160
 
3161
#-------------------------------------------------------------------------------
227 dpurdie 3162
#   Documentation
359 dpurdie 3163
#   NOTE
227 dpurdie 3164
#
359 dpurdie 3165
#   Each subcommand MUST have
3166
#   head1 section as used by the subcommand
3167
#       This should be empty, as the contents will NOT be displayed
3168
#   head2 sections called
3169
#       NAME SYNOPSIS ARGUMENTS OPTIONS DESCRIPTION EXAMPLES
3170
#
3171
#=head1 xxxxxx
3172
#=head2 NAME
3173
#=head2 SYNOPSIS
3174
#=head2 ARGUMENTS
3175
#=head2 OPTIONS
3176
#=head2 DESCRIPTION
3177
#=head2 EXAMPLES
3178
#
227 dpurdie 3179
 
3180
=pod
3181
 
3182
=head1 NAME
3183
 
3184
jats_sandbox - Build in a Development Sandbox
3185
 
3186
=head1 SYNOPSIS
3187
 
361 dpurdie 3188
  jats sandbox [options] command [command options]
227 dpurdie 3189
 
3190
 Options:
1329 dpurdie 3191
    -help[=n]                  - Display help with specified detail
3192
    -help -help                - Detailed help message
3193
    -man                       - Full documentation
227 dpurdie 3194
 
1329 dpurdie 3195
 Options for recursion control:
7319 dpurdie 3196
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 3197
    -toPackage=name            - Stop building after package
3198
    -fromPackage=name          - Start building from package
3199
    -justPackage=name[,name]   - Build named packages
3200
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 3201
    -entireSandbox             - Process the entire sandbox
3202
    -users                     - Process package users, not dependencies
7307 dpurdie 3203
 Options common to all commands:
6133 dpurdie 3204
    -[no]keepgoing             - Ignore errors
3205
    -[no]reScan                - Recalculate and cache sandbox structure
7307 dpurdie 3206
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
1329 dpurdie 3207
 
227 dpurdie 3208
 Commands:
3209
    help                - Same as -help
3210
    create              - Create a sandbox in the current directory
359 dpurdie 3211
    populate            - Populate the sandbox with packages
299 dpurdie 3212
    delete              - Delete the sandbox
255 dpurdie 3213
    info [[-v]-v]       - Sandbox information. -v: Be more verbose
4197 dpurdie 3214
    buildfilter         - Modify and display sandbox buildfilter
6133 dpurdie 3215
    [un]skip            - Mark a package to be skipped during the build
7319 dpurdie 3216
    [un]error           - Mark a package as having build errors
6133 dpurdie 3217
    fingerprint         - Various fingerprint operations
7304 dpurdie 3218
    testlinks           - Test / Delete broken package symlinks
7306 dpurdie 3219
    scandepth           - Set/Display the build file scan depth
227 dpurdie 3220
    cmd                 - Do commands in all sandbox components
1329 dpurdie 3221
    all                 - Do 'build', if required, then a make in all components
331 dpurdie 3222
    build               - Force 'build and make' in all sandbox components
275 dpurdie 3223
    make                - Do 'make' in all sandbox components
273 dpurdie 3224
    clean               - Do 'make clean' in all sandbox components
3225
    clobber             - Do 'build clobber' is all sandbox components
337 dpurdie 3226
    cache               - Cache external dependent packages
7319 dpurdie 3227
    writeBuildData      - Write out build data
7320 dpurdie 3228
    genPkgSigs          - Generate package Signatures
3229
    setAbtMarker        - Set Build System Marker file
227 dpurdie 3230
 
359 dpurdie 3231
 Use the command
3232
    jats sandbox 'command' -h
3233
 for command specific help
361 dpurdie 3234
 
227 dpurdie 3235
=head1 OPTIONS
3236
 
3237
=over 8
3238
 
299 dpurdie 3239
=item B<-help[=n]>
227 dpurdie 3240
 
3241
Print a brief help message and exits.
299 dpurdie 3242
There are three levels of help
227 dpurdie 3243
 
299 dpurdie 3244
=over 8
3245
 
361 dpurdie 3246
=item   1
299 dpurdie 3247
 
361 dpurdie 3248
Brief synopsis
299 dpurdie 3249
 
361 dpurdie 3250
=item   2
299 dpurdie 3251
 
361 dpurdie 3252
Synopsis and option summary
3253
 
3254
=item   3
3255
 
3256
Detailed help in man format
3257
 
299 dpurdie 3258
=back 8
3259
 
227 dpurdie 3260
=item B<-help -help>
3261
 
3262
Print a detailed help message with an explanation for each option.
3263
 
3264
=item B<-man>
3265
 
299 dpurdie 3266
Prints the manual page and exits. This is the same a -help=3
227 dpurdie 3267
 
7319 dpurdie 3268
=item B<-onlyLevel=number>
3269
 
3270
This option is available in all commands that process multiple packages.
3271
Package processing will be limited to the specified level. 
3272
 
3273
This can be used to perform a multi-machine build. Level-1 builds are performed 
3274
on all machines and the results merged into the common package store, then Level-2 builds 
3275
are performed on all machines.
3276
 
3277
Level-1 packages have no dependencies.
3278
 
3279
Level-2 packages only have dependancies on Level-1 packages
3280
 
3281
Level-N packages only have dependancies on packages below Level N-1
3282
 
1329 dpurdie 3283
=item B<-toPackage=name>
3284
 
3285
This option is available in all commands that process multiple packages.
3286
Package processing will stop at the named package.
3287
 
4688 dpurdie 3288
The package name can be specified in one of three forms:
1329 dpurdie 3289
 
4184 dpurdie 3290
=over 8
3291
 
3292
=item 1 
3293
 
3294
Just the package name. ie: MyPackage
3295
 
3296
=item 2 
3297
 
3298
The package name and the project suffix. ie: MyPackage.prj
3299
 
3300
=item 3 
3301
 
3302
The package name and version, joined with an underscore: ie: MyPackage_1.0.0000.prj
3303
 
3304
=back 8
3305
 
1329 dpurdie 3306
=item B<-fromPackage=name>
3307
 
3308
This option is available in all commands that process multiple packages.
3309
Package processing will start at the named package.
3310
 
4688 dpurdie 3311
The package name can be specified in one of the three forms described under the '-toPackage' option.
1329 dpurdie 3312
 
3313
=item B<-justPackage=name[,name]>
3314
 
3315
This option is available in all commands that process multiple packages. The
3316
named packages will be processed in the correct build order. Packages that are
3317
not named will be skipped, unless the package is being processed due to
3318
being in the 'fromPackage' to 'toPackage' range.
3319
 
3320
Multiple packages can be named either by separating names with a comma, or
3321
with multiple options.
3322
 
4688 dpurdie 3323
The package names can be specified as a mix of the three forms described under the '-toPackage' option.
4184 dpurdie 3324
 
1329 dpurdie 3325
=item B<-ignorePackage=name[,name]>
3326
 
3327
This option is available in all commands that process multiple packages. The
3328
named packages will not be processed.
3329
 
3330
Multiple packages can be named either by separating names with a comma, or
3331
with multiple options.
3332
 
3333
The exclusion of a package takes precedence over its inclusion.
3334
 
4688 dpurdie 3335
The package names can be specified as a mix of the three forms described under the '-toPackage' option.
4184 dpurdie 3336
 
6133 dpurdie 3337
=item B<-[no]entireSandbox>
3338
 
7307 dpurdie 3339
This option will override the automatic package localisation that will occur if the user starts the command
3340
within a subdirectory of a package within the sandbox and will process the entire sanbbox.
6133 dpurdie 3341
 
3342
If the user start the command within a subdirectory of a package then the sandbox commands will be localised
3343
to the current package and the dependencies of the package.
3344
 
3345
=item B<-[no]users>
3346
 
3347
This option will completely change the packages considered to be built. The normal operation is to consider
3348
the current package and all packages that it depends upon.
3349
 
3350
This option will consider all packages that 'use' the current package, either directly or indirectly. It does not 
3351
include the 'current' pakage in this list. The assumption is that the current package has been sucessfully built 
3352
and needs to tested.
3353
 
3354
This option will work when they is a current package to be processed and not the entire sandbox.
3355
 
3356
The intended purpose of this option is to simplify regression testing.
3357
 
3358
=item B<-[no]keepgoing>
3359
 
3360
This options controls the behaviour of the command when an error is encountered.
3361
 
3362
The default operation is to terminate the command on the package with the
3363
error. This can be modified so that errors are ignored.
3364
 
3365
=item B<-[no]reScan>
3366
 
3367
This option controls the process of locating build files within the sandbox.
3368
 
3369
The default operation is to scan the sandbox and to cache the location of the build files.
3370
 
3371
If a package is added or removed from the sandbox, then the sandbox will need to be rescanned.
3372
Jats will detect when a package has been added or removed, but if the internal structure of the
3373
packages has changed the cached data may be incorrect. 
3374
 
7307 dpurdie 3375
=item B<-multiBuilders=mode>
3376
 
3377
If a package-name can be built by multiple packages then the sandbox processing will
3378
normally report an error.
3379
 
3380
This option allow the error to be reported as a warning or to be ignored altogether. The named package will be 
3381
excluded from the build set.
3382
 
3383
Valid values for 'mode' are: error, report and ignore.  The default mode is 'error'.
3384
 
7323 dpurdie 3385
One workaround is to use a 'stop' file. Any directory that contains 'stop' file will not be scanned for
3386
build files. If a 'stop' file is added then it may defeat caching of build information. The information will 
3387
need to be refreshed with the '--rescan' option. The 'stop' file should not be version controlled.
3388
 
279 dpurdie 3389
=back
3390
 
227 dpurdie 3391
=head1 DESCRIPTION
3392
 
299 dpurdie 3393
This program is the primary tool for the maintenance of Development Sandboxes.
3394
 
227 dpurdie 3395
More documentation will follow.
3396
 
279 dpurdie 3397
=head2 SANDBOX DIRECTORY
3398
 
299 dpurdie 3399
The sandbox directory is marked as being a sandbox through the use of the
3400
'sandbox create' command. This will create a suitable structure within the
279 dpurdie 3401
current directory.
3402
 
3403
Several JATS commands operate differently within a sandbox. The 'extract' and
365 dpurdie 3404
'release' commands will create static views within the sandbox and not the
279 dpurdie 3405
normal directory. The 'sandbox' sub commands can only be used within a sandbox.
3406
 
3407
The sandbox directory contains sub directories, each should contain a single
359 dpurdie 3408
package. Sub directories may be created with the 'jats extract' command or with the
3409
'jats sandbox populate' command.
279 dpurdie 3410
 
6133 dpurdie 3411
Note: Symbolic links are not supported. They cannot work as the sandbox mechanism
365 dpurdie 3412
requires that all the packages be contained within a sub directory tree so
279 dpurdie 3413
that the root of the sandbox can be located by a simple scan of the directory
3414
tree.
3415
 
325 dpurdie 3416
If a package subdirectory contains a file called 'stop' or 'stop.
3417
<GBE_MACHTYPE>', then that package will not be considered as a part of the
6133 dpurdie 3418
build-set. A 'stop' file will prevent consideration for all build platforms. The 'stop.
325 dpurdie 3419
<GBE_MACHTYPE>' will only prevent consideration if being built on a GBE_MACHTYPE
3420
type of computer.
279 dpurdie 3421
 
3559 dpurdie 3422
If the sandbox contains a file called 'buildfilter', then the contents of the
3423
file will be read and used a buildfilter. The file is processed by reading each
3424
line and:
3425
 
3426
=over 4
3427
 
4184 dpurdie 3428
=item * 
3559 dpurdie 3429
 
4184 dpurdie 3430
Removing white space at both ends of the line
3559 dpurdie 3431
 
4184 dpurdie 3432
=item * 
3559 dpurdie 3433
 
4184 dpurdie 3434
Removing empty lines
3559 dpurdie 3435
 
4184 dpurdie 3436
=item * 
3437
 
3438
Lines that start with a # are comments and are removed
3439
 
3440
=item * 
3441
 
3442
Remaining lines are joined together to form a buildfilter
3443
 
3559 dpurdie 3444
=back
3445
 
7319 dpurdie 3446
=for comment ==================================================================
3447
 
359 dpurdie 3448
=head1 Create Sandbox
299 dpurdie 3449
 
359 dpurdie 3450
=head2 NAME
299 dpurdie 3451
 
359 dpurdie 3452
Create Sandbox
3453
 
3454
=head2 SYNOPSIS
3455
 
1329 dpurdie 3456
jats sandbox create [command options]
359 dpurdie 3457
 
3458
 Command Options
3459
    -help[=n]               - Command specific help, [n=1,2,3]
3460
    -verbose[=n]            - Verbose operation
7322 dpurdie 3461
    -[no]force              - Force creation of nested sandbox
359 dpurdie 3462
 
3463
=head2 OPTIONS
3464
 
7323 dpurdie 3465
The 'create' command takes the following options:
359 dpurdie 3466
 
7322 dpurdie 3467
=item -[no]force
3468
 
3469
Normally a sandbox should not be created within another sandbox. 
3470
 
3471
The use of this option overrides this limitation.
3472
 
3473
A sandbox with a sandbox will be ignored by the parent sandbox.
3474
 
3475
=back
3476
 
359 dpurdie 3477
=head2 DESCRIPTION
3478
 
299 dpurdie 3479
The 'create' command will create a sandbox in the users current directory. It is
3480
not possible to create a sandbox within a sandbox.
3481
 
3482
A sandbox can be created in a directory that contains files and subdirectories.
3483
 
3484
The create command simply places a known directory in the current directory.
359 dpurdie 3485
This directory is used by the sandboxing process. It may be manually deleted, or
299 dpurdie 3486
deleted with the 'delete' command.
3487
 
7319 dpurdie 3488
=for comment ==================================================================
3489
 
359 dpurdie 3490
=head1 Populate Sandbox
3491
 
3492
=head2 NAME
3493
 
3494
Populate a Sandbox
3495
 
3496
=head2 SYNOPSIS
3497
 
1329 dpurdie 3498
jats sandbox populate [command options] [packageName packageVersion]
359 dpurdie 3499
 
7307 dpurdie 3500
 Common Options:
3501
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 3502
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 3503
    -toPackage=name            - Stop building after package
3504
    -fromPackage=name          - Start building from package
3505
    -justPackage=name[,name]   - Build named packages
3506
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 3507
    -entireSandbox             - Process the entire sandbox
3508
    -users                     - Process package users, not dependencies
7307 dpurdie 3509
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
3510
    -[no]keepgoing             - Ignore errors
3511
    -[no]reScan                - Recalculate and cache sandbox structure
3512
 Command Specific Options
1329 dpurdie 3513
    -excludePackage=name[,name]- Do not extract named package
3514
    -recurse[=n]               - Locate dependencies within packages
3515
    -all                       - Populate with all dependencies
3516
    -missing                   - Locate missing packages
3517
    -show                      - Show packages that would be extracted
3518
    -test                      - Do not extract packages
3519
    -<Other>                   - Pass options to jats extract
359 dpurdie 3520
 
3521
=head2 ARGUMENTS
3522
 
3523
The 'populate' command can take a package name and version as arguments. It will
3524
then populate the sandbox with this package. See 'DESCRIPTION' for details.
3525
 
3526
=head2 OPTIONS
3527
 
3528
The 'populate' command takes the following options:
3529
 
3530
=over 4
3531
 
1329 dpurdie 3532
=item -excludePackage=name[,name]
3533
 
3534
This option prevents one, or more, packages from populating the sandbox.
3535
Packages specified with this option will not be extracted from version control
3536
and added to the sandbox.
3537
 
4688 dpurdie 3538
Packages can be identified in three ways:
1329 dpurdie 3539
 
3540
=over 4
3541
 
3542
=item 1. Package Name
3543
 
3544
All package versions matching the named package will be excluded.
3545
 
3546
=item 2. Package Name and Version
3547
 
3548
Only the specified version of the named package will be excluded. The
3549
user specifies the package name and version as a single string separated with
3550
an underscore. ie: core_devl_2.100.5000.cr
3551
 
3552
=item 3. Package Name and Suffix
3553
 
3554
All packages matching the named package and project will be excluded. The
3555
user specifies the package name and project as a single string separated with
3556
a dot. ie: core_devl.cr
3557
 
3558
 
3559
=back
3560
 
359 dpurdie 3561
=item -recurse[=N]
3562
 
3563
This option will modify the operation of the command such that dependencies
3564
of named packages can also be extracted into the sandbox.
3565
 
3566
The default operation is to only extract named packages. If the option is
3567
specified then all dependent packages are processed. An optional numeric argument
3568
can be specified to limit the depth of the recursion.
3569
 
1329 dpurdie 3570
=item -all
3571
 
3572
This option will populate the sandbox will all dependencies of packages that are
3573
currently in the sandbox.
3574
 
3575
The global options that control recursion will affect the packages that are
3576
processed.
3577
 
3578
This option cannot be used with the '-missing' option.
3579
 
359 dpurdie 3580
=item -missing
3581
 
3582
This option will modify the operation of the dependency recursion scanning such
3583
that dependent packages that exist in a package archive will not be extracted.
3584
 
3585
Use of this option allows a sandbox to be populated with packages that are
3586
required by packages in the sandbox, but are not available in a package archive.
3587
 
1329 dpurdie 3588
The global options that control recursion will affect the packages that are
3589
processed.
3590
 
3591
This option cannot be used with the '-all' option.
3592
 
3593
=item -show
3594
 
3595
This option will prevent the command from performing the extraction. It will
3596
simply display the names of the packages that would be extracted.
3597
 
359 dpurdie 3598
=item -test
3599
 
3600
This option will prevent the command from performing the extraction. It will
3601
simply display the JATS commands that can be used to perform the extraction.
3602
 
3603
=item -<Other>
3604
 
3605
Options not understood by the 'populate' sub command will be passed through
3606
the package extraction program. Useful options include:
3607
 
363 dpurdie 3608
=over 4
359 dpurdie 3609
 
361 dpurdie 3610
=item *
359 dpurdie 3611
 
361 dpurdie 3612
-extractfiles
359 dpurdie 3613
 
361 dpurdie 3614
=item *
3615
 
3616
-branch=<branch name>
3617
 
359 dpurdie 3618
=back
3619
 
3620
=back
3621
 
3622
=head2 DESCRIPTION
3623
 
3624
The 'populate' command can be used to assist in populating the sandbox. It has
3625
two modes of operation.
3626
 
363 dpurdie 3627
=over 4
359 dpurdie 3628
 
361 dpurdie 3629
=item 1
359 dpurdie 3630
 
361 dpurdie 3631
Named Package
3632
 
363 dpurdie 3633
If the user specifies both a package name and a package version then the command
359 dpurdie 3634
will populate the sandbox with that package and optionally its dependencies.
3635
 
361 dpurdie 3636
=item 2
359 dpurdie 3637
 
361 dpurdie 3638
Determine missing dependencies
3639
 
359 dpurdie 3640
If the user does not specify a package name and version, but does specify
3641
the '-missing' option,  then the command will examine the current sandbox and
3642
determine missing dependent packages. It will then populate the sandbox with
3643
these packages and optionally there dependencies.
3644
 
3645
=back
3646
 
3647
=head2 EXAMPLES
3648
 
3649
=over 4
3650
 
361 dpurdie 3651
=item *
359 dpurdie 3652
 
361 dpurdie 3653
jats sandbox populate package1 version1
3654
 
359 dpurdie 3655
This command will populate the sandbox with version1 of package1, if it does not
3656
already exist in the sandbox.
3657
 
361 dpurdie 3658
=item *
359 dpurdie 3659
 
361 dpurdie 3660
jats sandbox populate package1 version1 -recurse -missing
3661
 
359 dpurdie 3662
This command will populate the sandbox with version1 of package1, if it does not
3663
already exist in the sandbox, together will all the packages dependencies that
3664
are not available in a package archive.
3665
 
361 dpurdie 3666
=item *
359 dpurdie 3667
 
361 dpurdie 3668
jats sandbox populate -recurse -missing
3669
 
359 dpurdie 3670
This command will examine the current sandbox and populate the sandbox with
3671
packages that are required to build the packages in the sandbox and the
3672
dependencies of these packages, provide the dependent package is not in a
3673
package archive.
3674
 
361 dpurdie 3675
=item *
359 dpurdie 3676
 
361 dpurdie 3677
jats sandbox populate
3678
 
359 dpurdie 3679
This command will examine the current sandbox and populate the sandbox with
3680
packages that are required to build the packages in the sandbox. It will not
3681
examine the dependents of these packages.
3682
 
3683
=back
3684
 
7319 dpurdie 3685
=for comment ==================================================================
3686
 
359 dpurdie 3687
=head1 Delete Sandbox
3688
 
3689
=head2 NAME
3690
 
4688 dpurdie 3691
Delete a sandbox
359 dpurdie 3692
 
3693
=head2 SYNOPSIS
3694
 
3695
jats sandbox [options] delete
3696
 
3697
 Options:
3698
    -help[=n]               - Help message, [n=1,2,3]
3699
    -man                    - Full documentation [-help=3]
3700
    -verbose[=n]            - Verbose command operation
3701
 
3702
=head2 DESCRIPTION
3703
 
299 dpurdie 3704
The 'delete' command will delete the sandbox's marker directory. The command may
3705
be executed anywhere within the sandbox.
3706
 
359 dpurdie 3707
Once the sandbox has been deleted, the user must remove the components within the
299 dpurdie 3708
sandbox.
3709
 
7319 dpurdie 3710
=for comment ==================================================================
3711
 
359 dpurdie 3712
=head1 Sandbox Information
299 dpurdie 3713
 
359 dpurdie 3714
=head2 NAME
3715
 
3716
Display Sandbox Information
3717
 
3718
=head2 SYNOPSIS
3719
 
1329 dpurdie 3720
jats sandbox info [command options]
359 dpurdie 3721
 
7307 dpurdie 3722
 Common Options:
3723
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 3724
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 3725
    -toPackage=name            - Stop building after package
3726
    -fromPackage=name          - Start building from package
3727
    -justPackage=name[,name]   - Build named packages
3728
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 3729
    -entireSandbox             - Process the entire sandbox
3730
    -users                     - Process package users, not dependencies
7307 dpurdie 3731
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
3732
    -[no]keepgoing             - Ignore errors
3733
    -[no]reScan                - Recalculate and cache sandbox structure
3734
 Command Specific Options
3735
    -verbose[=n]               - Display more information
3736
    -usedby                    - Display package usage information
6133 dpurdie 3737
    -fingerprint               - Display fingerprint information
7306 dpurdie 3738
    -[no]dependencies          - Display external dependencies (default)
3739
    -[no]buildorder            - Display build order (default)
7307 dpurdie 3740
    -[no]path                  - Display path to package
361 dpurdie 3741
 
359 dpurdie 3742
=head2 OPTIONS
3743
 
3744
=over
3745
 
3746
=item B<-verbose[=n]>
3747
 
3748
This options will increase the verbosity of the information being displayed.
3749
Values 1 and 2 are described in the detailed 'DESCRIPTION'. Other values are
3750
reserved for diagnostic use.
3751
 
6133 dpurdie 3752
=item B<-usedby>
3753
 
3754
This option will list all packages that use the current package, both directly and
3755
indirectly. These are packages that should be tested whan changes are made to the 
3756
package.
3757
 
3758
=item B<-fingerprint>
3759
 
3760
This option will cause the information display to include that status of each packages fingerprint.
3761
 
3762
This will slow down the display as the calculation can be time consuming.
3763
 
7306 dpurdie 3764
=item B<-[no]dependencies>
3765
 
3766
This option will cause the information display to include all the external dependencies.
3767
 
3768
=item B<-[no]buildorder>
3769
 
3770
This option will cause the information display to include all the build order.
3771
 
7307 dpurdie 3772
=item B<-[no]path>
3773
 
3774
This option will cause the information display to include all the path to the build file
3775
 
359 dpurdie 3776
=back
3777
 
3778
=head2 DESCRIPTION
3779
 
299 dpurdie 3780
The 'info' command will display information about the build order and the
359 dpurdie 3781
dependencies of packages that it finds within the sandbox.
299 dpurdie 3782
 
359 dpurdie 3783
The command works within various levels of verbosity:
299 dpurdie 3784
 
3785
=over 8
3786
 
361 dpurdie 3787
=item *
299 dpurdie 3788
 
361 dpurdie 3789
No Verbosity
3790
 
299 dpurdie 3791
The basic command will display the build order and the external
335 dpurdie 3792
dependencies. External dependencies may be prefixed with one of the
3793
following indicators:
299 dpurdie 3794
 
335 dpurdie 3795
=over 8
3796
 
361 dpurdie 3797
=item   '+' Multiple versions of this package are being used by sandboxed components.
335 dpurdie 3798
 
361 dpurdie 3799
=item   '*' The package cannot be found in any of the package archives.
335 dpurdie 3800
 
3801
=back
3802
 
361 dpurdie 3803
=item *
299 dpurdie 3804
 
361 dpurdie 3805
Verbosity of 1
3806
 
359 dpurdie 3807
This level of verbosity will display the build order and detailed information
299 dpurdie 3808
on the dependencies. The dependencies will be prefixed with:
3809
 
3810
=over 8
3811
 
361 dpurdie 3812
=item   E Dependent Package is external to the sandbox
299 dpurdie 3813
 
361 dpurdie 3814
=item   I Dependent Package is internal to the sandbox
299 dpurdie 3815
 
3816
=back
3817
 
335 dpurdie 3818
External dependencies may be prefixed with one of the indicators described for
3819
no-verbosity. Additionally the internal consumer of the external package is also
3820
shown. These are prefixed with a 'U'.
299 dpurdie 3821
 
361 dpurdie 3822
=item *
299 dpurdie 3823
 
361 dpurdie 3824
Verbosity of 2
3825
 
6133 dpurdie 3826
Usage information will also be displayed. This is the same as invoking the 
3827
'-usedby' option.
299 dpurdie 3828
 
361 dpurdie 3829
=item *
299 dpurdie 3830
 
361 dpurdie 3831
Verbosity over 2
3832
 
359 dpurdie 3833
This should be considered a debug option. Undocumented internal information will
299 dpurdie 3834
be displayed.
3835
 
3836
=back
3837
 
7319 dpurdie 3838
=for comment ==================================================================
3839
 
7323 dpurdie 3840
The build infomation display will show the state of each package as a cryptic set of four characters within square brackets.
3841
 
3842
The first character may be one of:
3843
 
3844
=over 8
3845
 
3846
=item S - Build is being skipped
3847
 
3848
=item s - Build is being suppressed
3849
 
3850
=item blank - Build is active
3851
 
3852
=back
3853
 
3854
The second character may be one of:
3855
 
3856
=over 8
3857
 
3858
=item * - This is the current package
3859
 
3860
=item B - Has been build
3861
 
3862
=item - - A 'noBuild'. Will not be built due to build filters
3863
 
3864
=back
3865
 
3866
The third character may be one of:
3867
 
3868
=over 8
3869
 
3870
=item E - The package only exists in dpkg_archive
3871
 
3872
=item L - The package has been built and exists within the sandbox
3873
 
3874
=item M - The package has been built and exists in both the sandbox and dpkg_archive
3875
 
3876
=back
3877
 
3878
The fourth character may be one of (requires the -fingerprint option):
3879
 
3880
=over 8
3881
 
3882
=item G - A good fingerprint
3883
 
3884
=item B - A bad fingerprint. Files in the package have been modified since the last build.
3885
 
3886
=item blank - The package has not been built and no fingerprint has been calculated.
3887
 
3888
=back
3889
 
4197 dpurdie 3890
=head1 Buildfilter
3891
 
3892
=head2 NAME
3893
 
3894
Display and Modify Sandbox buildfilter
3895
 
3896
=head2 SYNOPSIS
3897
 
3898
jats sandbox buildfilter [command options] [TARGETS]+
3899
 
3900
 Command Options
3901
    -help[=n]               - Command specific help, [n=1,2,3]
3902
    -man                    - Same as -help=3
3903
 
3904
 Target Names
3905
    -TARGET                 - Remove target from the current buildfilter
3906
    +TARGET                 - Add target to current buildfilter
3907
    TARGET                  - If first target, then reset buildfilter 
3908
                              and add target, otherwise add target.
3909
 
3910
=head2 OPTIONS
3911
 
3912
The 'buildfilter' command takes the following options:
3913
 
3914
=over 8
3915
 
3916
=item -TARGET
3917
 
3918
If a target name starts with a '-' and is not an option, then that target will be
3919
removed from the current buildfilter. 
3920
 
3921
If the named target is not a part of the current buildfilter then nothing will happen.
3922
 
3923
=item +TARGET
3924
 
3925
If a target name starts with a '+' then that target will be added to the current buildfilter.
3926
 
3927
If the named target is already a part of the current buildfilter then nothing will happen.
3928
 
3929
 
3930
=item TARGET
3931
 
3932
If a target name does not start with either a '-' or a '+' then the target will be added to the
3933
current buildfilter.
3934
 
3935
If this is the first named target then the build filter will be set to this one target.
3936
 
3937
=back
3938
 
3939
=head2 DESCRIPTION
3940
 
3941
The 'buildfilter' command will display and optionally modify the build filter used within
3942
the sandbox.
3943
 
3944
=head2 EXAMPLES
3945
 
3946
The command
3947
 
3948
    jats sandbox buildfilter 
3949
 
3950
will simply display the current buildfilter.
3951
 
3952
The command
3953
 
3954
    jats sandbox buildfilter +COBRA +PPC_603E
3955
 
3956
will append the build targets COBRA and PPC_603E to the current buildfilter.
3957
 
3958
The command
3959
 
3960
    jats sandbox buildfilter -COBRA
3961
 
3962
will remove the build target COBRA from the current buildfilter.
3963
 
3964
The command
3965
 
3966
    jats sandbox buildfilter COBRA +PPC_603E
3967
 or jats sandbox buildfilter COBRA PPC_603E
3968
 
3969
will set the buildfilter to be COBRA and PPC_603E
3970
 
7319 dpurdie 3971
=for comment ==================================================================
3972
 
6133 dpurdie 3973
=head1 Skip Build
3974
 
3975
=head2 NAME
3976
 
3977
Mark a package to be skipped during the build
3978
 
3979
=head2 SYNOPSIS
3980
 
3981
jats sandbox [un]skip [command options] [PackageName]+
3982
 
3983
 Command Options
3984
    -help[=n]               - Command specific help, [n=1,2,3]
3985
    -man                    - Same as -help=3
3986
    -[no]machine            - Skip on on this type of machine
3987
 
3988
=head2 ARGUMENTS
3989
 
3990
Arguments to the 'skip' command are the names of packages to be marked.
3991
 
3992
If no packages are named then the command will display all packages that are marked to be skipped.
3993
 
3994
If the named package is '.', then the current package will be excluded.
3995
 
3996
=head2 OPTIONS
3997
 
3998
The 'skip' command takes the following options:
3999
 
4000
=over 8
4001
 
4002
=item -[no]machine
4003
 
4004
This option will flag that the package will be skipped only on this type of build machine.
4005
 
4006
=back
4007
 
4008
=head2 DESCRIPTION
4009
 
4010
The 'skip' command marked the named packages to be skipped during the build, or the mark will be removed.
4011
 
4012
=head2 EXAMPLES
4013
 
4014
The command
4015
 
4016
    jats sandbox skip package1 
4017
 
4018
will mark package1 to be skipped during the following builds.
4019
 
7319 dpurdie 4020
=for comment ==================================================================
4021
 
4022
=head1 Error Build
4023
 
4024
=head2 NAME
4025
 
4026
Mark a package as having a build error
4027
 
4028
=head2 SYNOPSIS
4029
 
4030
jats sandbox [un]error [command options] [PackageName]+
4031
 
4032
 Command Options
4033
    -help[=n]               - Command specific help, [n=1,2,3]
4034
    -man                    - Same as -help=3
4035
    -[no]machine            - Skip on on this type of machine
7320 dpurdie 4036
    -[no]removeAll          - Remove all error indications
7319 dpurdie 4037
 
4038
=head2 ARGUMENTS
4039
 
4040
Arguments to the 'error' command are the names of packages to be marked.
4041
 
4042
If no packages are named then the command will display all packages that are marked as errored.
4043
 
4044
If the named package is '.', then the current package will be marked.
4045
 
4046
=head2 OPTIONS
4047
 
4048
The 'error' command takes the following options:
4049
 
4050
=over 8
4051
 
4052
=item -[no]machine
4053
 
4054
This option will flag that the package will be skipped only on this type of build machine.
4055
 
7320 dpurdie 4056
=item -[no]removeAll
4057
 
4058
This option will cause all error indication to be removed. It can be used in conjunction with 
4059
other operations.
4060
 
7319 dpurdie 4061
=back
4062
 
4063
=head2 DESCRIPTION
4064
 
7451 dpurdie 4065
The 'error' command marks the named packages to as having build errors. These packages, and packages that
7319 dpurdie 4066
they consume them will be excluded from any build consideration.
4067
 
4068
=head2 EXAMPLES
4069
 
4070
The command
4071
 
4072
    jats sandbox error package1 
4073
 
4074
will mark package1 as having a build error.
4075
 
4076
=for comment ==================================================================
4077
 
6133 dpurdie 4078
=head1 Sandbox Finger Print
4079
 
4080
=head2 NAME
4081
 
4082
Various fingerprint operations
4083
 
4084
=head2 SYNOPSIS
4085
 
4086
jats sandbox finger[print] [options]
4087
 
4088
 Command Options
4089
    -help[=n]               - Command specific help, [n=1,2,3]
4090
    -man                    - Same as -help=3
4091
    -[no]generate           - Generate a fingerprint over a package
4092
    -[no]delete             - Delete the fingerprint information
4093
 
4094
=head2 ARGUMENTS
4095
 
4096
Arguments to the 'fingerprint' command are the names of packages to be processed.
4097
 
4098
If no packages are named then the command will process the current package, if any.
4099
 
4100
=head2 OPTIONS
4101
 
4102
The 'fingerprint' command takes the following options:
4103
 
4104
=over 8
4105
 
4106
=item -[no]generate
4107
 
4108
This option will cause the fingerprint of the package to be regenerated.
4109
 
4110
=item -[no]delete
4111
 
4112
This option will delete the fingerprint information associated wit a package.
4113
 
4114
=back
4115
 
4116
=head2 DESCRIPTION
4117
 
4118
The 'fingerprint' command, will by default, examine the packages fingerprint and report
4119
if the package has been modified since the fingerprint was created.
4120
 
4121
Options allow different modes of operation.
4122
 
4123
A fingerprint may only be created after the 'build.pl' file has been created. It requires the
4124
build process to generate metadata about the package.
4125
 
4126
=head2 EXAMPLES
4127
 
4128
The command
4129
 
4130
    jats sandbox fingerprint -generate
4131
 
4132
will regenerate the fingerprint of the current package. Useful after trivial edits to 
4133
enable the sandbox builder to bypass the package and not to rebuild it and all of its dependents.
4134
 
7319 dpurdie 4135
=for comment ==================================================================
4136
 
359 dpurdie 4137
=head1 Command all
331 dpurdie 4138
 
359 dpurdie 4139
=head2 NAME
4140
 
4141
Build packages in the sandbox
4142
 
4143
=head2 SYNOPSIS
4144
 
1329 dpurdie 4145
jats sandbox all [command options] [arguments]
359 dpurdie 4146
 
7307 dpurdie 4147
 Common Options:
4148
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 4149
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 4150
    -toPackage=name            - Stop building after package
4151
    -fromPackage=name          - Start building from package
4152
    -justPackage=name[,name]   - Build named packages
4153
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 4154
    -entireSandbox             - Process the entire sandbox
4155
    -users                     - Process package users, not dependencies
7307 dpurdie 4156
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
6133 dpurdie 4157
    -[no]keepgoing             - Ignore errors
7307 dpurdie 4158
    -[no]reScan                - Recalculate and cache sandbox structure
4159
 Command Specific Options
6133 dpurdie 4160
    -[no]skip                  - Skip if no source change (default:skip)
359 dpurdie 4161
 
6133 dpurdie 4162
 
359 dpurdie 4163
=head2 ARGUMENTS
4164
 
4165
Arguments are passed to the 'make' phase of the process.
4166
 
4167
=head2 OPTIONS
4168
 
6133 dpurdie 4169
=over
359 dpurdie 4170
 
6133 dpurdie 4171
=item B<-[no]skip>
4172
 
4173
This operation overides the default smart building mechanism.
4174
 
4175
By default, a package will not be built if the last build was successful and 
4176
there has not been any change to the source of the package, since the last 
4177
succesful build.
4178
 
4179
=back
4180
 
359 dpurdie 4181
=head2 DESCRIPTION
4182
 
331 dpurdie 4183
The 'all' command will perform build, if the build files are out of date,
4184
followed by a make in each of the packages within the sandbox, in the correct
4185
build order.
4186
 
4187
Any arguments are passed to the 'make' phase of the process.
4188
 
4189
This command may be used to:
4190
 
4191
=over 8
4192
 
361 dpurdie 4193
=item *
331 dpurdie 4194
 
361 dpurdie 4195
Pickup any build file changes.
331 dpurdie 4196
 
361 dpurdie 4197
=item *
4198
 
4199
Resume a failed build.
4200
 
331 dpurdie 4201
=back
4202
 
7319 dpurdie 4203
=for comment ==================================================================
4204
 
359 dpurdie 4205
=head1 Command build
331 dpurdie 4206
 
359 dpurdie 4207
=head2 NAME
4208
 
4209
Build packages in the sandbox
4210
 
4211
=head2 SYNOPSIS
4212
 
1329 dpurdie 4213
jats sandbox build [command options] [arguments]
359 dpurdie 4214
 
7307 dpurdie 4215
 Common Options:
4216
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 4217
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 4218
    -toPackage=name            - Stop building after package
4219
    -fromPackage=name          - Start building from package
4220
    -justPackage=name[,name]   - Build named packages
4221
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 4222
    -entireSandbox             - Process the entire sandbox
4223
    -users                     - Process package users, not dependencies
7307 dpurdie 4224
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
6133 dpurdie 4225
    -[no]keepgoing             - Ignore errors
7307 dpurdie 4226
    -[no]reScan                - Recalculate and cache sandbox structure
4227
 Command Specific Options
6133 dpurdie 4228
    -[no]skip                  - Skip if no source change (default:skip)
359 dpurdie 4229
 
4230
=head2 ARGUMENTS
4231
 
4232
Arguments are passed to the 'make' phase of the process.
4233
 
4234
=head2 OPTIONS
4235
 
6133 dpurdie 4236
=over
359 dpurdie 4237
 
6133 dpurdie 4238
=item B<-[no]skip>
4239
 
4240
This operation overides the default smart building mechanism.
4241
 
4242
By default, a package will not be built if the last build was successful and 
4243
there has not been any change to the source of the package, since the last 
4244
succesful build.
4245
 
4246
=back
4247
 
359 dpurdie 4248
=head2 DESCRIPTION
4249
 
331 dpurdie 4250
The 'build' command will force a build followed by a make in each of the packages
4251
within the sandbox, in the correct build order.
4252
 
4253
Any arguments are passed to the 'make' phase of the process.
4254
 
4255
In practice, the 'sandbox all' command is quicker.
4256
 
7319 dpurdie 4257
=for comment ==================================================================
4258
 
359 dpurdie 4259
=head1 Clean
331 dpurdie 4260
 
359 dpurdie 4261
=head2 NAME
4262
 
4263
Clean all sandbox components
4264
 
4265
=head2 SYNOPSIS
4266
 
1329 dpurdie 4267
jats sandbox clean|clobber [command options]
359 dpurdie 4268
 
7307 dpurdie 4269
 Common Options:
4270
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 4271
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 4272
    -toPackage=name            - Stop building after package
4273
    -fromPackage=name          - Start building from package
4274
    -justPackage=name[,name]   - Build named packages
4275
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 4276
    -entireSandbox             - Process the entire sandbox
4277
    -users                     - Process package users, not dependencies
7307 dpurdie 4278
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
6133 dpurdie 4279
    -[no]keepgoing             - Ignore errors
7307 dpurdie 4280
    -[no]reScan                - Recalculate and cache sandbox structure
359 dpurdie 4281
 
4282
=head2 ARGUMENTS
4283
 
4284
None
4285
 
4286
=head2 OPTIONS
4287
 
7307 dpurdie 4288
The are no command specific options.
359 dpurdie 4289
 
4290
=head2 DESCRIPTION
4291
 
4292
The 'clean' command will perform a 'jats make clean' in all components in the
4293
sandbox.
4294
 
4295
The 'clobber' command will perform a 'jats clobber' in all components in the
4296
sandbox.
4297
 
7319 dpurdie 4298
=for comment ==================================================================
4299
 
359 dpurdie 4300
=head1 make
4301
 
4302
=head2 NAME
4303
 
4304
Make packages in the sandbox
4305
 
4306
=head2 SYNOPSIS
4307
 
1329 dpurdie 4308
jats sandbox make [command options] [arguments]
359 dpurdie 4309
 
7307 dpurdie 4310
 Common Options:
4311
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 4312
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 4313
    -toPackage=name            - Stop building after package
4314
    -fromPackage=name          - Start building from package
4315
    -justPackage=name[,name]   - Build named packages
4316
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 4317
    -entireSandbox             - Process the entire sandbox
4318
    -users                     - Process package users, not dependencies
7307 dpurdie 4319
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
4320
    -[no]keepgoing             - Ignore errors
4321
    -[no]reScan                - Recalculate and cache sandbox structure
359 dpurdie 4322
 
4323
=head2 ARGUMENTS
4324
 
4325
Arguments are passed to the 'make' phase of the process.
4326
 
4327
=head2 OPTIONS
4328
 
4329
The are no command specific options.
4330
 
4331
=head2 DESCRIPTION
4332
 
331 dpurdie 4333
The 'make' command will perform a 'make' operation in each of the packages
4334
within the sandbox, in the correct build order.
4335
 
4336
Any arguments are passed to the 'make'.
4337
 
7319 dpurdie 4338
=for comment ==================================================================
4339
 
359 dpurdie 4340
=head1 cmd
331 dpurdie 4341
 
359 dpurdie 4342
=head2 NAME
4343
 
4344
Process each package with a specified command.
4345
 
4346
=head2 SYNOPSIS
4347
 
1329 dpurdie 4348
jats sandbox cmd [command options] [arguments]
359 dpurdie 4349
 
7307 dpurdie 4350
 Common Options:
4351
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 4352
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 4353
    -toPackage=name            - Stop building after package
4354
    -fromPackage=name          - Start building from package
4355
    -justPackage=name[,name]   - Build named packages
4356
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 4357
    -entireSandbox             - Process the entire sandbox
4358
    -users                     - Process package users, not dependencies
7307 dpurdie 4359
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
4360
    -[no]keepgoing             - Ignore errors
4361
    -[no]reScan                - Recalculate and cache sandbox structure
7308 dpurdie 4362
 Command Specific Options
4363
    -[no]reverse               - Reverse the processing order
359 dpurdie 4364
 
4365
=head2 ARGUMENTS
4366
 
4367
Arguments are passed to a JATS command.
4368
 
4369
=head2 OPTIONS
4370
 
7308 dpurdie 4371
The 'cmd' command takes the following options:
359 dpurdie 4372
 
7308 dpurdie 4373
=over 8
4374
 
4375
=item -[no]reverse
4376
 
4377
This option will controlls the order in which the packages will be processed.
4378
 
4379
The default option is 'noreverse'. Packages will be processed in the build order.
4380
 
2054 dpurdie 4381
=back
4382
 
359 dpurdie 4383
=head2 DESCRIPTION
4384
 
331 dpurdie 4385
The 'cmd' command will pass all of its arguments to JATS in the build directory
4386
of each of the packages within the sandbox, in the package build order.
4387
 
4086 dpurdie 4388
=head2 EXAMPLES
4389
 
4390
The following command will update all the Subversion-based packages in the sandbox.
4391
 
4392
    jats sandbox cmd eprog svn update
4393
 
4394
Note the use of 'eprog' in the command string. This tells JATS to run the external
4395
(to JATS) program. Without this the command would run the JATS-internal command
4396
called 'svn' - with different results.
4397
 
4398
The following command will update the dependencies in the build.pl files to match
4399
those of a nominated release. This will only affect the package versions
4400
external to the sandbox, although all version information in the build.pl
4401
files will be updated.
4402
 
4403
    jats sandbox cmd upddep -rtagid=12345
4404
 
7319 dpurdie 4405
=for comment ==================================================================
4406
 
359 dpurdie 4407
=head1 Cache
331 dpurdie 4408
 
359 dpurdie 4409
=head2 NAME
331 dpurdie 4410
 
359 dpurdie 4411
Cache dependent packages
331 dpurdie 4412
 
359 dpurdie 4413
jats sandbox [options] cache [command options]
331 dpurdie 4414
 
359 dpurdie 4415
 Options:
4416
    -help[=n]               - Help message, [n=1,2,3]
4417
    -man                    - Full documentation [-help=3]
4418
    -verbose[=n]            - Verbose command operation
337 dpurdie 4419
 
359 dpurdie 4420
 Command Options
4421
    -help[=n]               - Command specific help, [n=1,2,3]
337 dpurdie 4422
 
359 dpurdie 4423
=head2 ARGUMENTS
4424
 
4425
The are no command specific arguments.
4426
 
4427
=head2 OPTIONS
4428
 
4429
The are no command specific options.
4430
 
4431
=head2 DESCRIPTION
4432
 
4433
The 'cache' command will cache all external dependent packages into the users
4434
dpkg_archive_cache as defined through the EnvVar GBE_DPKG_CACHE. The result is
4435
similar to the command 'jats sandbox build -cache', without the overhead of
4436
building the sandbox components.
4437
 
4438
This command allows the simple creation of a small development environment that
4439
is not tied to the larger Development Environment. It may then be used in a
337 dpurdie 4440
disconnected mode to perform development.
4441
 
7319 dpurdie 4442
=for comment ==================================================================
4443
 
7304 dpurdie 4444
=head1 Sandbox Test Links
4445
 
4446
=head2 NAME
4447
 
4448
Test and delete sandbox link files
4449
 
4450
=head2 SYNOPSIS
4451
 
4452
jats sandbox testlinks [options]
4453
 
4454
 Command Options
4455
    -help[=n]               - Command specific help, [n=1,2,3]
4456
    -man                    - Same as -help=3
4457
    -[no]delete             - Delete bad links
4458
 
4459
=head2 ARGUMENTS
4460
 
4461
This command does not take any arguments
4462
 
4463
=head2 OPTIONS
4464
 
4465
The 'fingerprint' command takes the following options:
4466
 
4467
=over 8
4468
 
4469
=item -[no]delete
4470
 
4471
This option will delete the link files if they are bad.
4472
 
4473
=back
4474
 
4475
=head2 DESCRIPTION
4476
 
4477
The 'testlinks' command, will by default, examine symbolic links within the sandbox and report on
4478
broken links.
4479
 
7306 dpurdie 4480
An option allows the broken links to be deleted.
7304 dpurdie 4481
 
4482
Each package in the sandbox will have a symbolic link to the packages 'package' area. If a package is removed
4483
from the sandbox the link file may be left in the sandbox and cause a 'build' to fail.
4484
 
4485
=head2 EXAMPLES
4486
 
4487
The command
4488
 
4489
    jats sandbox testlinks
4490
 
4491
will test the symbolic links in the sandbox metadata.
4492
 
7319 dpurdie 4493
=for comment ==================================================================
4494
 
7306 dpurdie 4495
=head1 Sandbox Scan Depth
4496
 
4497
=head2 NAME
4498
 
4499
Set and Display the build file scanner depth
4500
 
4501
=head2 SYNOPSIS
4502
 
4503
jats sandbox scandepth [options] [depth]
4504
 
4505
 Command Options
4506
    -help[=n]               - Command specific help, [n=1,2,3]
4507
    -man                    - Same as -help=3
4508
 
4509
=head2 ARGUMENTS
4510
 
4511
This command takes one optional argument. A positive number that control the 
4512
depth of the build filter scanner.
4513
 
4514
The default value is '3'. Deeper scans may be required for sandboxes containing badly formed 
4515
packages. The tradoff is speed for all sandbox operations.
4516
 
4517
Setting the scan depth will force a rescan of the sandbox build files on the next command that
4518
requires the information.
4519
 
4520
=head2 OPTIONS
4521
 
4522
The scandepth command only accepts the standard help and man options.
4523
 
4524
=head2 DESCRIPTION
4525
 
4526
The scandepth command, will by default, display the current value for the build file scanner.
4527
 
4528
If a numeric argument is provided this will set the future build file scan depth.
4529
 
4530
=head2 EXAMPLES
4531
 
4532
The command
4533
 
4534
    jats sandbox scandepth 5
4535
 
4536
will set future build file scan to a maximum of 5 directories below the root of the sandbox.
4537
 
7319 dpurdie 4538
=for comment ==================================================================
4539
 
4540
=head1 Write Build Data
4541
 
4542
=head2 NAME
4543
 
4544
Write out build system data
4545
 
4546
=head2 SYNOPSIS
4547
 
4548
jats sandbox writeBuildData [options]
4549
 
4550
 Command Options
4551
    -help[=n]               - Command specific help, [n=1,2,3]
4552
    -man                    - Same as -help=3
4553
    -outfile=path           - Specify the location of the output file
7321 dpurdie 4554
    -[no]fullData           - Provide detailed information on all the package
7319 dpurdie 4555
 
4556
=head2 ARGUMENTS
4557
 
4558
This command does not take any arguments
4559
 
4560
=head2 OPTIONS
4561
 
4562
The 'writeBuildData' command takes the following options:
4563
 
4564
=over 8
4565
 
4566
=item -outfile=path
4567
 
4568
This option will control the location of the generated file. The path includes the name of the output file.
4569
 
4570
The directory in which the file is to be created must exist. The file itself will be deleted and 
4571
recreated. Ideally it should not be present at the beginning of the command.
4572
 
7321 dpurdie 4573
=item -[no]fullData
4574
 
4575
This option controls the level of detail provided in the response. When enabled complete details 
4576
of all the packages will be provided. This should only be need when a new repository is being 
4577
processed.
4578
 
7319 dpurdie 4579
=back
4580
 
4581
=head2 DESCRIPTION
4582
 
4583
The writeBuildData command is used by the automated build system to extract information from 
4584
the sandbox. Data is written to a JSON file.
4585
 
4586
=head2 EXAMPLES
4587
 
4588
The command
4589
 
4590
    jats sandbox writeBuildData -outpath=data.json
4591
 
4592
will write a json formatted file that contains data for the build system.
4593
 
7320 dpurdie 4594
=for comment ==================================================================
4595
 
4596
=head1 Generate Package Signatures
4597
 
4598
=head2 NAME
4599
 
4600
Generate Package Signatures
4601
 
4602
=head2 SYNOPSIS
4603
 
4604
jats sandbox genPkgSigs [options]
4605
 
4606
 Command Options
4607
    -help[=n]               - Command specific help, [n=1,2,3]
4608
    -man                    - Same as -help=3
4609
 
4610
=head2 ARGUMENTS
4611
 
4612
This command does not take any arguments
4613
 
4614
=head2 OPTIONS
4615
 
4616
The 'genPkgSigs' command does not have any command specific options.
4617
 
4618
=head2 DESCRIPTION
4619
 
4620
The genPkgSigs command is used by the automated build system to generate package signatures
4621
of all dependent packages.
4622
 
4623
=head2 EXAMPLES
4624
 
4625
The command
4626
 
4627
    jats -cd PackagePath sandbox genPkgSigs
4628
 
4629
=for comment ==================================================================
4630
 
4631
=head1 Set Abt Marker
4632
 
4633
=head2 NAME
4634
 
4635
Set Abt Marker file
4636
 
4637
=head2 SYNOPSIS
4638
 
4639
jats sandbox setAbtMarker [options]
4640
 
4641
 Command Options
4642
    -help[=n]               - Command specific help, [n=1,2,3]
4643
    -man                    - Same as -help=3
4644
 
4645
=head2 ARGUMENTS
4646
 
4647
This command does not take any arguments
4648
 
4649
=head2 OPTIONS
4650
 
4651
The 'setAbtMarker' command does not have any command specific options.
4652
 
4653
=head2 DESCRIPTION
4654
 
4655
The setAbtMarker command is used by the automated build system to place a marker file
4656
in the sandbox such that JATS will recognise the sandbox as being used by the 
4657
'Auto Build Tool'. This will affect the operation of several Jats commands.
4658
 
4659
=head2 EXAMPLES
4660
 
4661
The command
4662
 
4663
    jats -cd PackagePath sandbox setAbtMarker
4664
 
227 dpurdie 4665
=cut
4666