Subversion Repositories DevTools

Rev

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