Subversion Repositories DevTools

Rev

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