Subversion Repositories DevTools

Rev

Rev 7319 | Rev 7321 | 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;
1581
 
1582
    Getopt::Long::Configure('pass_through');
1583
    getOptionsFromArray ( \@cmd_opts,
7320 dpurdie 1584
                          'outfile=s'   => \$opt_outfile,
7319 dpurdie 1585
                          ) || Error ("Invalid command line" );
1586
    SubCommandHelp( $opt_help, 'Write Build Data') if ($opt_help  );
1587
 
1588
    #
1589
    #   Calculate sandbox info
1590
    #   All data written will be based on this information
1591
    #
1592
    calc_sandbox_info(1);
1593
    calc_signature_info();
1594
 
1595
    #
1596
    #   Generate build data
1597
    #   Consists of a few sections
1598
    #       BuildPlan   - Package names to be built, in order
1599
    #                     In practice only the first can be built
1600
    #                     the others can be used as an indication of builds to be performed
1601
    #                     
1602
    #   
1603
    my %BuildData;
1604
    my @BuildPlan = ();
1605
    my @BuildEntry;
7320 dpurdie 1606
    my @PkgData;
7319 dpurdie 1607
 
1608
    foreach my $fe ( @build_order ) {
7320 dpurdie 1609
        my $data;
1610
        $data->{name} = $fe->{dname};
1611
        $data->{signature} = $fe->{signature};
1612
        $data->{error} = $fe->{buildError} ? 1 : 0;
1613
        $data->{excluded} = $fe->{buildExclude} ? 1 : 0;
1614
        $data->{prebuilt} = $fe->{si} eq 1? 1 : 0;
1615
        push @PkgData, $data;
1616
    }
1617
 
1618
 
1619
    foreach my $fe ( @build_order ) {
7319 dpurdie 1620
        next if $fe->{buildError};
1621
        next if $fe->{buildExclude};
1622
        next if $fe->{buildSkip};
1623
        next unless $fe->{buildActive};
1624
        next if $fe->{si} eq 1;
1625
 
1626
        push @BuildPlan, $fe->{fname};
1627
        push @BuildEntry, $fe;
1628
    }
1629
 
1630
    push @{$BuildData{BuildPlan}}, @BuildPlan;
1631
 
1632
    #
1633
    #   Add information on the first item
1634
    #   This is the package that will be built so we need more information
1635
    #
1636
    my $BuildPkg = $BuildEntry[0];
1637
    my $pkgData;
1638
    if ($BuildPkg)
1639
    {
1640
        $pkgData->{fname} = $BuildPkg->{fname};
1641
        $pkgData->{dname} = $BuildPkg->{dname};
1642
        $pkgData->{dir} = $BuildPkg->{dir};
1643
        $pkgData->{name} = $BuildPkg->{name};
1644
        $pkgData->{version} = $BuildPkg->{version};
1645
        $pkgData->{prj} = $BuildPkg->{prj};
7320 dpurdie 1646
 
1647
        if ($BuildPkg->{si} eq 3)
1648
        {
1649
            $pkgData->{error} = 1;
1650
            $pkgData->{signature} = "MSG: Cannot create";
1651
            $pkgData->{generic} = 0;
1652
        }
1653
        else
1654
        {
1655
            $pkgData->{error} = 1;
1656
            $pkgData->{signature} = $BuildPkg->{signature};
1657
 
1658
            #
1659
            #   Determine if the package is 'GENERIC'
1660
            #   Read in the build.cfg file
1661
            #
1662
            my $pkgInterface = getpkgInterface($BuildPkg);
1663
            ReadBuildConfig( $pkgInterface, '', '--NoError' );
1664
            $pkgData->{generic} = ReadBuildConfig::isGenericBuild();
1665
        }
7319 dpurdie 1666
    }
1667
 
1668
    $BuildData{BuildPkgData} = $pkgData;
7320 dpurdie 1669
    $BuildData{PkgData} = \@PkgData;
7319 dpurdie 1670
 
1671
#DebugDumpData("data", $BuildPkg);
1672
 
7320 dpurdie 1673
    if ($opt_outfile) {
1674
        FileCreate($opt_outfile, to_json( \%BuildData, { ascii => 1, pretty => 1 }));
1675
    } else {
1676
        print( to_json( \%BuildData, { ascii => 1, pretty => 1 }) . "\n");
1677
    }
7319 dpurdie 1678
#    DebugDumpData("BuildData",\%BuildData);
1679
    #
1680
    #   All done
1681
    #
1682
    exit(0);
1683
}
1684
 
1685
#-------------------------------------------------------------------------------
7320 dpurdie 1686
# Function        : setAbtMarker 
1687
#
1688
# Description     : Set a marker file in the sandbox such that JATS will recognise
1689
#                   the sandbox as being a special ABT enabled sandbox
1690
#
1691
# Inputs          : None    
1692
#
1693
# Returns         : Does not return 
1694
#
1695
sub setAbtMarker
1696
{
1697
    my (@cmd_opts ) = @_;
1698
 
1699
    Getopt::Long::Configure('pass_through');
1700
    getOptionsFromArray ( \@cmd_opts,
1701
                          ) || Error ("Invalid command line" );
1702
    SubCommandHelp( $opt_help, 'Set Abt Marker') if ($opt_help  );
1703
 
1704
    Message ("Setting ABT marker file");
1705
    TouchFile( CatPaths($GBE_DPKG_SBOX, 'abtMarker'));
1706
    $GBE_ABT = 1;
1707
 
1708
    #
1709
    #   All done
1710
    #
1711
    exit(0);
1712
}
1713
 
1714
#-------------------------------------------------------------------------------
1715
# Function        : generatepkgSignatures 
1716
#
1717
# Description     : Generate package signatures for dependent packages
1718
#                   Intended to be used by build systems 
1719
#
1720
# Inputs          : 
1721
#
1722
# Returns         : 
1723
#
1724
sub generatepkgSignatures
1725
{
1726
    my (@cmd_opts ) = @_;
1727
 
1728
    Getopt::Long::Configure('pass_through');
1729
    getOptionsFromArray ( \@cmd_opts,
1730
                          ) || Error ("Invalid command line" );
1731
    SubCommandHelp( $opt_help, 'Generate Package Signatures') if ($opt_help  );
1732
 
1733
    #
1734
    #   Calculate sandbox info
1735
    #   All data written will be based on this information
1736
    #
1737
    Message ("Generating Package Signatures");
1738
    calc_sandbox_info();
1739
    calc_signature_info();
1740
 
1741
    #
1742
    #   All done
1743
    #
1744
    exit(0);
1745
}
1746
 
1747
#-------------------------------------------------------------------------------
7319 dpurdie 1748
# Function        : calc_signature_info 
1749
#
1750
# Description     : Calculate signature information for all packages in the sandbox
1751
#                   Used to create build system information 
1752
#
1753
# Inputs          : Nothing 
1754
#
1755
# Returns         : Updates global data structures
1756
#                   The %packages item {si} will be set to one of:
1757
#                       1 - Have a prebuild package
1758
#                       2 - Have generated a signature, but do not have a prebuilt package
1759
#                       3 - Error generating the signature
1760
#                       4 - Excluded - Dependent package has no signature
1761
#                       5 - Excluded - Packages skipped or not active 
1762
#
1763
sub calc_signature_info
1764
{
7320 dpurdie 1765
    Debug("calc_signature_info");
1766
    SystemConfig(ExitOnError => 0);
7319 dpurdie 1767
    foreach my $fe ( @build_order )
1768
    {
7320 dpurdie 1769
        if (exists $fe->{si}) {
1770
            Debug("calc_signature_info. Exists $fe->{dname}, $fe->{si}");
1771
            next;
1772
        }
7319 dpurdie 1773
        if ( !$fe->{buildActive} || $fe->{buildSkip} ) {
1774
            $fe->{si} = 5;
7320 dpurdie 1775
            Debug("calc_signature_info. Skip $fe->{dname}");
7319 dpurdie 1776
            next;
1777
        }
1778
 
1779
        #
1780
        #   If this package has a signature file then we don't need to re-create it
1781
        #
1782
        my $result = 0;
1783
        my ($preBuilt, $haveSignature) = locatePreBuiltPackage($fe);
1784
        unless ($haveSignature) {
1785
            my $dir = $fe->{dir};
1786
            $result = JatsCmd( "-cd=$dir", 'build', 'signature');
7320 dpurdie 1787
            Debug("calc_signature_info. $fe->{dname} Build Signature. $result");
7319 dpurdie 1788
            }
1789
 
1790
        unless ($result) {
1791
            #
1792
            #   Signature generated OK
1793
            #
1794
            ($preBuilt, $haveSignature) = locatePreBuiltPackage($fe);
7320 dpurdie 1795
            Debug("calc_signature_info. $fe->{dname} Examine: $preBuilt, $haveSignature");
7319 dpurdie 1796
            if ($preBuilt) {
1797
                $fe->{si} = 1;
1798
                $fe->{signature} = $haveSignature;
1799
            } elsif ($haveSignature) {
1800
                $fe->{si} = 2;
1801
                $fe->{signature} = $haveSignature;
1802
            } else {
1803
                $result = 1;
1804
            }
1805
        }
1806
 
1807
        #
1808
        #   Error creating the signature
1809
        #   Mark this package and all those that depend on it
1810
        #   
1811
        if ($result) {
7320 dpurdie 1812
            Debug("calc_signature_info. Error $fe->{dname}");
7319 dpurdie 1813
            $fe->{si} = 3;
1814
            if ( exists($fe->{'usedBy'}))
1815
            {
1816
                foreach my $entry (@{$fe->{'usedBy'}}) {
1817
                    my $pe = $packages{$entry};
1818
                    $pe->{si} = 4; 
1819
                }
1820
            }
1821
        }
1822
    }
1823
}
1824
 
1825
#-------------------------------------------------------------------------------
6133 dpurdie 1826
# Function        : calc_rootFingerPrint 
1827
#
1828
# Description     : Calculate a finger print of all the directories in the
1829
#                   sandbox root.
1830
#                   
1831
#                   Used to determine if the user has added or remove a package
1832
#                   from the sandbox
1833
#
1834
# Inputs          : None
1835
#
1836
# Returns         : SHA1 hash
1837
#
1838
sub calc_rootFingerPrint
1839
{
1840
    my $fpSha1 = Digest->new("SHA-1");
1841
 
1842
    foreach my $pname ( glob("*") )
1843
    {
1844
        next if ( $pname =~ m~^\.~ );
1845
        next if ( $pname =~ m~dpkg_archive$~ );
1846
        next if ( $pname =~ m~^CVS$~ );
1847
        next unless ( -d $pname );
1848
 
1849
        $fpSha1->add($pname);
1850
 
1851
        #
1852
        #   Include stop files in fingerprint too
1853
        #
1854
        $fpSha1->add("$pname/stop" ) if ( -f "$pname/stop" ); 
1855
        $fpSha1->add("$pname/stop.$GBE_MACHTYPE" ) if ( -f "$pname/stop.$GBE_MACHTYPE" ); 
1856
 
1857
    }
1858
    return $fpSha1->hexdigest;
1859
}
1860
 
1861
#-------------------------------------------------------------------------------
227 dpurdie 1862
# Function        : cmd
1863
#
1864
# Description     : Execute a command in all the sandboxes
1865
#                       Locate the base of the sandbox
1866
#                       Locate all packages in the sandbox
1867
#                       Locate all build files in each sandbox
1868
#                       Determine build order
1869
#                       Issue commands for each sandbox in order
1870
#
255 dpurdie 1871
# Inputs          : Arguments passed to jats build
227 dpurdie 1872
#
1873
# Returns         : Will exit
1874
#
1875
sub cmd
1876
{
1329 dpurdie 1877
    my ($hcmd, @cmd_opts ) = @_;
7308 dpurdie 1878
    my $opt_reverse;
359 dpurdie 1879
 
1880
    Getopt::Long::Configure('pass_through');
7308 dpurdie 1881
    getOptionsFromArray ( \@cmd_opts,
1882
                          'reverse!' => \$opt_reverse,
1883
                          ) || Error ("Invalid command line" );
359 dpurdie 1884
    SubCommandHelp( $opt_help, $hcmd) if ($opt_help  );
1885
 
227 dpurdie 1886
    #
1887
    #   Determine Sandbox information
1888
    #   Populate global variables
1889
    #
1890
    calc_sandbox_info();
7308 dpurdie 1891
    if ($opt_reverse) {
1892
        @build_order = reverse @build_order;
1893
    }
227 dpurdie 1894
    foreach my $fe ( @build_order )
1895
    {
6133 dpurdie 1896
        my $active = displayHeader($fe, { showPath => 1 });
227 dpurdie 1897
 
6133 dpurdie 1898
        if ($active)
1899
        {
1900
            my $dir = $fe->{dir};
1901
            my $result = JatsCmd( "-cd=$dir", @cmd_opts);
1902
            if ( $result ) {
1903
                if ( $opt_keepgoing ) {
1904
                    Warning ("Cmd failure");
1905
                } else {
1906
                    Error   ("Cmd failure");
1907
                }
2054 dpurdie 1908
            }
1909
        }
227 dpurdie 1910
    }
1911
 
1912
    exit 0;
1913
}
1914
 
1915
#-------------------------------------------------------------------------------
331 dpurdie 1916
# Function        : buildcmd
1917
#
1918
# Description     : Build the entire sandbox
1919
#                   The all and the build are similar.
1920
#                   Its not really useful to do a build without a make
1921
#                   so we don't try
1922
#
1923
# Inputs          : Arguments passed to jats make
1924
#
1925
#
1926
# Returns         : Will exit
1927
#
1928
 
1929
sub buildcmd
1930
{
337 dpurdie 1931
    my ($cmd, @cmd_opts) = @_;
331 dpurdie 1932
    my @build_opts;
337 dpurdie 1933
    my @make_opts;
6133 dpurdie 1934
    my $opt_skip = 1;
1935
    my $opt_clean = 0;
331 dpurdie 1936
 
1937
    #
359 dpurdie 1938
    #   Extract and options
1939
    #
1940
    Getopt::Long::Configure('pass_through');
6133 dpurdie 1941
    getOptionsFromArray ( \@cmd_opts,
1942
                          'skip!' => \$opt_skip,
1943
                          'clean!' => \$opt_clean,
1944
    ) || Error ("Invalid command line" );
359 dpurdie 1945
    SubCommandHelp( $opt_help, "Command $cmd") if ($opt_help );
361 dpurdie 1946
 
359 dpurdie 1947
    #
331 dpurdie 1948
    #   Insert default options
1949
    #
1950
    push @build_opts, '-noforce' if ( $cmd eq 'all' );
6133 dpurdie 1951
    push @build_opts, '-force'   if ( $cmd ne 'all' );
331 dpurdie 1952
 
337 dpurdie 1953
    #
1954
    #   Attempt to split the options into build and make options
1955
    #   Only handle the often used options to build.
1956
    #
1957
    foreach  ( @cmd_opts )
1958
    {
1959
        if ( m/^-cache/ || m/^-package/ || m/^-forcebuildpkg/ || m/-expert/) {
1960
            push @build_opts, $_;
1961
        } else {
1962
            push @make_opts, $_;
1963
        }
1964
    }
1965
 
6133 dpurdie 1966
    push @make_opts, 'all'  unless ( @make_opts );
331 dpurdie 1967
 
1968
    #
1969
    #   Determine Sandbox information
1970
    #   Populate global variables
1971
    #
1972
    calc_sandbox_info();
1973
    foreach my $fe ( @build_order )
1974
    {
6133 dpurdie 1975
        my $active = displayHeader($fe, { showPath => 1 });
1976
        if ($active) {
331 dpurdie 1977
 
6133 dpurdie 1978
            #
1979
            #   Determine build success tag file
7319 dpurdie 1980
            #   If the tag file exists, then see if any files in the package source are more
6133 dpurdie 1981
            #   recent than the tag file
1982
            #
1983
            my $mustBuild = 1;
1984
            my $sigMatch = 0;
1985
            my $tagFile = getPkgFingerPrintFile($fe);
1986
 
1987
            if ( -e $tagFile ) {
1988
                if ( TagFileMatch($tagFile, genPkgFingerPrint($fe, 'Test')) ) {
1989
                    $sigMatch = 1;
1990
                    if ($opt_skip) {
1991
                        $mustBuild = 0;
1992
                    } else {
1993
                        $mustBuild = 2;
1994
                    }
1995
                } else {
1996
                }
1997
            } else {
1998
                    $mustBuild = 2;
1999
                    $sigMatch = -1;
2000
            }
2001
 
7301 dpurdie 2002
Debug0("Skip: $opt_skip, sigMatch: $sigMatch, Build: $mustBuild, Opts: @make_opts",);
6133 dpurdie 2003
            if ($mustBuild)
2004
            {
2005
                if (1)
2006
                {
2007
                    unlink $tagFile;
2008
                    my $dir = $fe->{dir};
2009
                    my $result;
2010
 
2011
                    $result = JatsCmd( "-cd=$dir", 'build', @build_opts);
2012
                    if ($result)
2013
                    {
2014
                        if ($opt_keepgoing)
2015
                        {
2016
                            Warning( "Build Cmd failure - Keep going");
2017
                            next;
2018
                        }
7307 dpurdie 2019
                        Error ("Build Cmd failure: $dir");
6133 dpurdie 2020
                    }
2021
 
2022
                    #
2023
                    #   Skip make if we have a prebuilt package
2024
                    #
2025
                    my $mustMake = 1;
7301 dpurdie 2026
                    if ($mustBuild == 2)
2027
                    {
2028
                        my $pbFound = locatePreBuiltPackage($fe);
2029
                        Debug0("Prebuilt: $pbFound");
2030
                        $mustMake = 0 if $pbFound;
2031
                    }
6133 dpurdie 2032
 
2033
                    if ($mustMake)
2034
                    {
2035
                        JatsCmd( "-cd=$dir", 'make', 'clean') if $opt_clean;
2036
                        $result = JatsCmd( "-cd=$dir", 'make',  @make_opts);
2037
                        if ($result)
2038
                        {
2039
                            if ($opt_keepgoing)
2040
                            {
2041
                                Warning( "Make Cmd failure - Keep going");
2042
                                next;
2043
                            }
7307 dpurdie 2044
                            Error ("Make Cmd failure: $dir");
6133 dpurdie 2045
                        }
2046
                    }
2047
                }
2048
 
7307 dpurdie 2049
                Verbose ("Save fingerprint: $tagFile");
6133 dpurdie 2050
                FileCreate( $tagFile, genPkgFingerPrint($fe,'Generation') );
2051
            }
2052
            else
2053
            {
2054
                Message ("No file changes since last build. Skipping")
2055
            }
2056
        }
331 dpurdie 2057
    }
2058
 
2059
    exit 0;
2060
}
2061
 
2062
#-------------------------------------------------------------------------------
273 dpurdie 2063
# Function        : clean
2064
#
2065
# Description     : Execute a command in all the sandboxes
2066
#                       Locate the base of the sandbox
2067
#                       Locate all packages in the sandbox
2068
#                       Locate all build files in each sandbox
2069
#                       Determine build order
2070
#                       Issue commands for each sandbox in order
2071
#
2072
# Inputs          : Arguments passed to jats build
2073
#
2074
# Returns         : Will exit
2075
#
2076
sub clean
2077
{
1329 dpurdie 2078
    my ($mode, @cmd_opts ) = @_;
359 dpurdie 2079
 
273 dpurdie 2080
    #
359 dpurdie 2081
    #   Extract and options
2082
    #
2083
    Getopt::Long::Configure('pass_through');
1329 dpurdie 2084
    getOptionsFromArray ( \@cmd_opts ) || Error ("Invalid command line" );
359 dpurdie 2085
    SubCommandHelp( $opt_help, "Clean") if ($opt_help );
2086
 
2087
    #
273 dpurdie 2088
    #   Determine Sandbox information
2089
    #   Populate global variables
2090
    #
2091
    calc_sandbox_info();
2092
 
2093
    my @cmd = $mode eq 'clobber' ? ('clobber') : ('make', 'clean' );
2094
 
2095
    #
2096
    #   Clobber and clean need to be done in the reverse order
2097
    #
2098
    foreach my $fe ( reverse @build_order )
2099
    {
6133 dpurdie 2100
        my $active = displayHeader($fe, { showPath => 1 });
2101
        if ($active)
2102
        {
2103
            my $dir = $fe->{dir};
2104
            my $result = JatsCmd( "-cd=$dir", @cmd, @cmd_opts);
2105
            if ($result)
2106
            {
2107
                if ($opt_keepgoing)
2108
                {
2109
                    Warning("Command Failure");
2110
                }
2111
                else
2112
                {
2113
                    Error ("Cmd failure") if ( $result );
2114
                }
2115
            }
2116
        }
273 dpurdie 2117
    }
2118
 
2119
    exit 0;
2120
}
2121
 
2122
 
2123
#-------------------------------------------------------------------------------
337 dpurdie 2124
# Function        : cache
2125
#
2126
# Description     : Cache external packages into the sandbox
2127
#
2128
# Inputs          : @opts                   - User options
2129
#
2130
# Returns         : Nothing
2131
#
2132
sub cache
2133
{
1329 dpurdie 2134
    my (@cmd_opts) = @_;
337 dpurdie 2135
 
1329 dpurdie 2136
    getOptionsFromArray ( \@cmd_opts ) || Error ("Invalid command line" );
2137
    SubCommandHelp( $opt_help, "Cache") if ($opt_help || $#cmd_opts >= 0 );
359 dpurdie 2138
 
337 dpurdie 2139
    #
2140
    #   Determine Sandbox information
2141
    #   Populate global variables
2142
    #
2143
    Message("Cache External Dependencies");
6133 dpurdie 2144
    Error ("GBE_DPKG_CACHE not defined") unless $GBE_DPKG_CACHE;
337 dpurdie 2145
    calc_sandbox_info();
2146
 
6133 dpurdie 2147
    JatsTool ('cache_dpkg', "core_devl/jats2_current" );
2148
 
337 dpurdie 2149
    #
1329 dpurdie 2150
    #   Walk the list of external dependencies and cache each one
337 dpurdie 2151
    #
2152
    foreach my $de ( sort keys %extern_deps )
2153
    {
2154
        my @vlist = keys %{$extern_deps{$de}};
359 dpurdie 2155
        foreach my $pve ( @vlist )
337 dpurdie 2156
        {
359 dpurdie 2157
            my ($pn,$pv) = split( $; , $pve );
2158
            Message ("Cache ${pn} ${pv}");
2159
            JatsTool ('cache_dpkg', "${pn}/${pv}" );
337 dpurdie 2160
        }
2161
    }
361 dpurdie 2162
 
337 dpurdie 2163
    exit 0;
361 dpurdie 2164
 
337 dpurdie 2165
}
2166
 
359 dpurdie 2167
#-------------------------------------------------------------------------------
2168
# Function        : populate
2169
#
2170
# Description     : Populate the sandbox with package versions
2171
#
2172
#
2173
# Inputs          : commands            - Array of command line arguments
2174
#                   Mode-0:
2175
#
2176
#                       pkg_name pkg_version        - Import files for named package
2177
#                       options:
2178
#                           -recurse                - Import dependent packages too
2179
#                           -missing                - Import dependencies not in dpkg_archive
2180
#                           -test                   - Show what would be done
2181
#                           -extractfiles           - Extract file, no view
2182
#
2183
#
2184
#
2185
#
2186
# Returns         : Does not return
2187
#
2188
use JatsRmApi;
2189
use DBI;
337 dpurdie 2190
 
359 dpurdie 2191
#
2192
#   Data Base Interface
2193
#
2194
my $RM_DB;
2195
my $PopLevel = 0;
2196
my %PopPackage;
2197
my @StrayPackages;
2198
my @PopBase;
2199
 
2200
sub populate
2201
{
1329 dpurdie 2202
    my (@cmd_opts ) = @_;
359 dpurdie 2203
    my $opt_missing = 0;
2204
    my $opt_recurse = 0;
2205
    my $opt_test = 0;
1329 dpurdie 2206
    my $opt_show = 0;
359 dpurdie 2207
    my $opt_extractfiles;
2208
    my @opt_extract = qw(-extract);
2209
    my @opt_fnames;
1329 dpurdie 2210
    my @opt_exclude;
2211
    my $opt_all;
359 dpurdie 2212
 
1329 dpurdie 2213
 
359 dpurdie 2214
    Getopt::Long::Configure('pass_through');
1329 dpurdie 2215
    getOptionsFromArray ( \@cmd_opts,
2216
                "all"               => \$opt_all,
2217
                "missing"           => \$opt_missing,
2218
                "test"              => \$opt_test,
2219
                "show"              => \$opt_show,
2220
                "recurse:100"       => \$opt_recurse,
2221
                'excludePackage:s'  => sub{ opts_add2List( \@opt_exclude, @_ )},
359 dpurdie 2222
                ) || Error ("Invalid command line" );
2223
 
2224
    SubCommandHelp( $opt_help, "Populate Sandbox") if ($opt_help );
2225
 
2226
    #
1329 dpurdie 2227
    #   Sanity tests
2228
    #
2229
    Error ("Populate: -missing and -all options are mutually exclusive")
2230
        if ( $opt_missing && $opt_all );
2231
 
2232
    #
359 dpurdie 2233
    #   Extract options for the jats extract utility
2234
    #
1329 dpurdie 2235
    foreach ( @cmd_opts )
359 dpurdie 2236
    {
2237
        if ( m~^-~ ) {
2238
            push ( @opt_extract, $_);
2239
        } else {
2240
            push ( @opt_fnames, $_);
2241
        }
2242
    }
2243
 
2244
    #
2245
    #   Allow exactly zero or two 'bare' arguments
2246
    #   Create an array of package-versions to be processed.
2247
    #
2248
    if ( $#opt_fnames >= 0 )
2249
    {
365 dpurdie 2250
        Error ("Populate: Must specify both a package name and version")
359 dpurdie 2251
            if ( $#opt_fnames != 1 );
2252
        push @PopBase, join( $;, @opt_fnames );
2253
    }
1329 dpurdie 2254
    elsif ( $opt_missing || $opt_all )
359 dpurdie 2255
    {
2256
        #
2257
        #   User has not provided a package name to extract
1329 dpurdie 2258
        #   Assume that the user will want all or missing dependencies
359 dpurdie 2259
        #
2260
        #   Determine packages that are not present
2261
        #
2262
        calc_sandbox_info();
2263
 
2264
        #
2265
        # Scan for missing dependencies
2266
        #
2267
        foreach my $de ( sort keys %extern_deps )
2268
        {
2269
            my @vlist = keys %{$extern_deps{$de}};
2270
            foreach my $pve ( @vlist )
2271
            {
2272
                my ($pn,$pv) = split( $; , $pve );
1329 dpurdie 2273
                unless ($opt_missing && check_package_existance( $pn, $pv ))
359 dpurdie 2274
                {
2275
                    push @PopBase, join( $;, $pn , $pv );
2276
                }
2277
            }
2278
        }
2279
    }
2280
    else
2281
    {
2282
        Error ("No command or option specified. See help for command usage");
2283
    }
2284
 
2285
    #
2286
    #   Process the list of package-versions
2287
    #   These are top level packages. Get details from Release Manager
2288
    #
2289
    #DebugDumpData("Data", \@PopBase );
2290
    $PopLevel = 0;
2291
    foreach my $entry ( @PopBase )
2292
    {
2293
        my ($pname, $pver ) = split( $; , $entry);
2294
 
2295
        my $pv_id = getPkgDetailsByName($pname, $pver);
2296
        Error ("populate: $pname, $pver not found in Release Manager" )
2297
            unless ( $pv_id );
2298
        getPkgDetailsByPV_ID($pv_id);
2299
    }
2300
    #
2301
    #   If recursing then process packages that have yet to
2302
    #   be processed. At the start there will be the initial user specified
2303
    #   packages on the list. Place a marker at the end so that we can
2304
    #   determine how far we are recursing down the dependency tree.
2305
    #
1329 dpurdie 2306
    $opt_recurse = ($opt_all ? 100 : $opt_recurse);
359 dpurdie 2307
    if ( $opt_recurse )
2308
    {
2309
        my $marker = join($; , '_NEXT_LEVEL_', 0, 0 );
2310
        push @StrayPackages, $marker;
2311
        $PopLevel++;
2312
 
2313
        while ( $#StrayPackages >= 0 )
2314
        {
2315
            my ($name, $ver, $pv_id) = split($;, shift @StrayPackages);
2316
 
2317
            #
2318
            #   Marker.
2319
            #   Increment the level of recursion
2320
            #   Detect end conditions
2321
            #
2322
            if ( $name eq '_NEXT_LEVEL_' )
2323
            {
2324
                last unless ($#StrayPackages >= 0 );
2325
                $PopLevel++;
2326
                last if ( $PopLevel > $opt_recurse );
2327
                push @StrayPackages, $marker;
2328
                next;
2329
            }
2330
 
2331
            next if ( exists $PopPackage{$name}{$ver}{done} );
2332
            getPkgDetailsByPV_ID ( $pv_id );
2333
            #print "Stray: $pv_id, $name, $ver\n";
2334
        }
2335
    }
2336
    #DebugDumpData("Data", \%PopPackage );
2337
 
2338
    #
2339
    #   Determine packages that need to be extracted
1329 dpurdie 2340
    #   Sort alphabetically - case insensitive
359 dpurdie 2341
    #
1329 dpurdie 2342
    foreach my $pname ( sort {lc($a) cmp lc($b)} keys %PopPackage )
359 dpurdie 2343
    {
1329 dpurdie 2344
        pkgscan:
359 dpurdie 2345
        foreach my $pver ( sort keys %{$PopPackage{$pname}} )
2346
        {
2347
            #
2348
            #   Create a nice view name for the extraction
365 dpurdie 2349
            #   Will also be used to test for package existence
359 dpurdie 2350
            #
2351
            my $vname = "$pname $pver";
2352
            $vname =~ s~ ~_~g;
2353
            $vname =~ s~__~~g;
2354
 
2355
            if ( -d "$GBE_SANDBOX/$vname" )
2356
            {
2357
                Warning("Package already in sandbox: $pname, $pver");
2358
                next;
2359
            }
2360
 
2361
            #
2362
            #   If scanning for missing packages, then examine archives
2363
            #   for the packages existence. Don't do this on level-0 packages
2364
            #   These have been user specified.
2365
            #
2366
            if ( $opt_missing && $PopPackage{$pname}{$pver}{level}  )
2367
            {
2368
                my $found = check_package_existance( $pname, $pver );
2369
                if ( $found )
2370
                {
2371
                    Verbose ("Package found in archive - skipped: $pname, $pver");
2372
                    next;
2373
                }
2374
            }
2375
 
2376
            #
1329 dpurdie 2377
            #   Has the user specifically excluded this package
2378
            #   Allow three forms
2379
            #       packageName
2380
            #       packageName_Version
2381
            #       packageName.projectName
2382
            #
2383
            my $excluded;
2384
            foreach my $ename ( @opt_exclude )
2385
            {
2386
                if ( $ename eq $pname ) {
2387
                    $excluded = 1;
2388
                } elsif ($ename eq $pname .'_' . $pver ) {
2389
                    $excluded = 1;
2390
                } else {
2391
                    if ( $pver =~ m~(\.[a-z]{2,4})$~ )
2392
                    {
2393
                        $excluded = ($ename eq $pname . $1 );
2394
                    }
2395
                }
2396
 
2397
                if ( $excluded )
2398
                {
2399
                    Message ("Package excluded by user - skipped: $pname, $pver");
2400
                    next pkgscan;
2401
                }
2402
            }
2403
 
2404
            #
359 dpurdie 2405
            #   Generate commands to extract the package
2406
            #
2407
            my $vcstag = $PopPackage{$pname}{$pver}{vcstag};
2408
            my @cmd = qw(jats_vcsrelease);
2409
            push @cmd, "-view=$vname", "-label=$vcstag", @opt_extract;
1329 dpurdie 2410
            if ( $opt_show )
359 dpurdie 2411
            {
1329 dpurdie 2412
                Message ("$pname $pver");
2413
            }
2414
            elsif ( $opt_test )
2415
            {
359 dpurdie 2416
                Message "jats " . QuoteCommand (@cmd );
2417
            }
2418
            else
2419
            {
2420
                Message "Extracting: $pname $pver";
2421
                my $rv = JatsCmd (@cmd);
2422
                Error ("Package version not extracted")
2423
                    if ( $rv );
2424
            }
2425
        }
2426
    }
2427
 
2428
    #
2429
    # This command does not return
2430
    #
2431
    exit (0);
2432
}
2433
 
337 dpurdie 2434
#-------------------------------------------------------------------------------
4197 dpurdie 2435
# Function        : buildfilter 
2436
#
2437
# Description     : Manipulate the sandbox build filter
2438
#
2439
# Inputs          : Optional filter names
2440
#                       +NAME - will add filter
2441
#                       -NAME will remove it
2442
#                       NAME will set it
2443
#                   No args will just display the build filter
2444
#
2445
# Returns         : Does not return
2446
#
2447
sub buildfilter
2448
{
2449
    my (@cmd_opts ) = @_;
2450
    my @filter_list;
2451
    my $first_arg = 1;
2452
    my $modified;
2453
 
2454
    Getopt::Long::Configure('pass_through');
2455
    getOptionsFromArray ( \@cmd_opts ) || Error ("Invalid command line" );
2456
 
2457
    SubCommandHelp( $opt_help, "Buildfilter") if ($opt_help );
2458
 
2459
    #
2460
    #   Set the initial filter list
2461
    #   This will have been parsed by JATS before we get here
2462
    #
2463
    @filter_list = split( /[,\s]+/, join(',', $GBE_BUILDFILTER));
2464
 
2465
    #
2466
    #   Extract options for the jats extract utility
2467
    #
2468
    foreach ( @cmd_opts )
2469
    {
2470
        if (m~^\+(.*)~)
2471
        {
2472
            UniquePush( \@filter_list, $1);
2473
        }
2474
        elsif (m~^\-(.*)~)
2475
        {
2476
            ArrayDelete( \@filter_list, $1);
2477
        }
2478
        else
2479
        {
2480
            @filter_list = () if ($first_arg);
2481
            UniquePush( \@filter_list, $_);
2482
        }
2483
        $first_arg = 0;
2484
        $modified = 1;
2485
    }
2486
 
2487
    #
2488
    #   Display the results to the user
2489
    #
2490
    Message('BuildFilter:', @filter_list);
2491
 
2492
    #
2493
    #   Write out a new file
2494
    #
2495
    if ($modified)
2496
    {
7306 dpurdie 2497
        FileCreate($filterFile, @filter_list);
4197 dpurdie 2498
    }
2499
 
2500
    #
2501
    # This command does not return
2502
    #
2503
    exit (0);
2504
}
2505
 
2506
 
2507
#-------------------------------------------------------------------------------
359 dpurdie 2508
# Function        : getPkgDetailsByName
2509
#
2510
# Description     : Determine the PVID for a given package name and version
2511
#
2512
# Inputs          : $pname          - Package name
2513
#                   $pver           - Package Version
2514
#
361 dpurdie 2515
# Returns         :
359 dpurdie 2516
#
2517
 
2518
sub getPkgDetailsByName
2519
{
2520
    my ($pname, $pver) = @_;
2521
    my $pv_id;
2522
    my (@row);
2523
 
2524
    connectRM(\$RM_DB) unless ($RM_DB);
2525
 
2526
    # First get details for a given package version
2527
 
2528
    my $m_sqlstr = "SELECT pv.PV_ID, pkg.PKG_NAME, pv.PKG_VERSION" .
2529
                    " FROM RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg" .
2530
                    " WHERE pkg.PKG_NAME = \'$pname\' AND pv.PKG_VERSION = \'$pver\' AND pv.PKG_ID = pkg.PKG_ID";
2531
    my $sth = $RM_DB->prepare($m_sqlstr);
2532
    if ( defined($sth) )
2533
    {
2534
        if ( $sth->execute( ) )
2535
        {
2536
            if ( $sth->rows )
2537
            {
2538
                while ( @row = $sth->fetchrow_array )
2539
                {
2540
                    $pv_id = $row[0];
2541
                    my $name = $row[1];
2542
                    my $ver = $row[2];
2543
                    Verbose( "getPkgDetailsByName :PV_ID= $pv_id");
2544
                }
2545
            }
2546
            $sth->finish();
2547
        }
2548
    }
2549
    else
2550
    {
2551
        Error("Prepare failure" );
2552
    }
2553
    return $pv_id;
2554
}
2555
 
2556
#-------------------------------------------------------------------------------
2557
# Function        : getPkgDetailsByPV_ID
2558
#
2559
# Description     : Populate the Packages structure given a PV_ID
2560
#                   Called for each package in the SBOM
2561
#
2562
# Inputs          : PV_ID           - Package Unique Identifier
2563
#
2564
# Returns         : Populates Package
2565
#
2566
sub getPkgDetailsByPV_ID
2567
{
2568
    my ($PV_ID) = @_;
2569
    my $foundDetails = 0;
2570
    my (@row);
2571
 
2572
    connectRM(\$RM_DB) unless ($RM_DB);
2573
 
2574
    # First get details from pv_id
2575
 
2576
    my $m_sqlstr = "SELECT pv.PV_ID, pkg.PKG_NAME, pv.PKG_VERSION, release_manager.PK_RMAPI.return_vcs_tag($PV_ID)" .
2577
                    " FROM RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg " .
2578
                    " WHERE pv.PV_ID = \'$PV_ID\' AND pv.PKG_ID = pkg.PKG_ID";
2579
 
2580
    my $sth = $RM_DB->prepare($m_sqlstr);
2581
    if ( defined($sth) )
2582
    {
2583
        if ( $sth->execute( ) )
2584
        {
2585
            if ( $sth->rows )
2586
            {
2587
                while ( @row = $sth->fetchrow_array )
2588
                {
2589
                    my $pv_id       = $row[0];
2590
                    my $name        = $row[1];
2591
                    my $ver         = $row[2];
2592
                    my $vcstag      = $row[3] || '';
2593
 
2594
                    $vcstag =~ tr~\\/~/~;
2595
                    Verbose ("getPkgDetailsByPV_ID: $PV_ID, $name, $ver, $vcstag");
2596
 
2597
                    $PopPackage{$name}{$ver}{pvid} = $PV_ID;
2598
                    $PopPackage{$name}{$ver}{done} = 1;
2599
                    $PopPackage{$name}{$ver}{vcstag} = $vcstag;
2600
                    $PopPackage{$name}{$ver}{level} = $PopLevel;
2601
                    getDependsByPV_ID( $pv_id, $name, $ver );
2602
                }
2603
            }
2604
            else
2605
            {
2606
                Warning ("No Package details for: PVID: $PV_ID");
2607
            }
2608
            $sth->finish();
2609
        }
2610
        else
2611
        {
2612
            Error("getPkgDetailsByPV_ID: Execute failure", $m_sqlstr );
2613
        }
2614
    }
2615
    else
2616
    {
2617
        Error("Prepare failure" );
2618
    }
2619
}
2620
 
2621
#-------------------------------------------------------------------------------
2622
# Function        : getDependsByPV_ID
2623
#
2624
# Description     : Extract the dependancies for a given package version
2625
#
2626
# Inputs          : $pvid
2627
#
2628
# Returns         :
2629
#
2630
sub getDependsByPV_ID
2631
{
2632
    my ($pv_id, $pname, $pver) = @_;
2633
 
2634
    connectRM(\$RM_DB) unless ($RM_DB);
2635
 
2636
    #
365 dpurdie 2637
    #   Now extract the package dependencies
359 dpurdie 2638
    #
2639
    my $m_sqlstr = "SELECT pkg.PKG_NAME, pv.PKG_VERSION, pd.DPV_ID" .
2640
                   " FROM RELEASE_MANAGER.PACKAGE_DEPENDENCIES pd, RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg" .
2641
                   " WHERE pd.PV_ID = \'$pv_id\' AND pd.DPV_ID = pv.PV_ID AND pv.PKG_ID = pkg.PKG_ID";
2642
    my $sth = $RM_DB->prepare($m_sqlstr);
2643
    if ( defined($sth) )
2644
    {
2645
        if ( $sth->execute( ) )
2646
        {
2647
            if ( $sth->rows )
2648
            {
2649
                while ( my @row = $sth->fetchrow_array )
2650
                {
2651
                    my $name = $row[0];
2652
                    my $ver = $row[1];
2653
 
2654
                    Verbose2( "       Depends: $name, $ver");
2655
                    unless ( exists $PopPackage{$name} && exists $PopPackage{$name}{$ver} && exists $PopPackage{$name}{$ver}{done} )
2656
                    {
2657
                        push @StrayPackages, join($;, $name, $ver, $row[2] );
2658
                    }
2659
                }
2660
            }
2661
            $sth->finish();
2662
        }
2663
    }
2664
    else
2665
    {
2666
        Error("GetDepends:Prepare failure" );
2667
    }
2668
}
2669
 
2670
#-------------------------------------------------------------------------------
1329 dpurdie 2671
# Function        : getOptionsFromArray
2672
#
2673
# Description     : Like getOptions, but handles an array
2674
#                   Provided as the version of Perl used does not have one
2675
#
2676
# Inputs          : pArray                  - Ref to array
2677
#                   ....                    - GetOptions arguments
2678
#
2679
# Returns         : 
2680
#
2681
sub getOptionsFromArray
2682
{
2683
    my ($pArray, %args) = @_;
2684
 
2685
    #
7307 dpurdie 2686
    #   Helper to parse --multiBuilders
2687
    #
2688
    my $parseMulti = sub {
2689
        my ($ref, $value) = @_;
2690
        $value = 'error' unless length($value);
2691
        my %valid = (error => 0, report => 1, ignore => 2);
2692
        unless (exists $valid{lc $value}) {
2693
            die ("Invalid option for  --$ref->{name}\n");
2694
        };
2695
        $opt_multiBuilders = $valid{lc $value};
2696
    };
2697
 
2698
 
2699
    #
1329 dpurdie 2700
    #   Common arguments
2701
    #
2702
    my %commonOptions = (
2703
        'help|h:+'          => \$opt_help,
2704
        'manual:3'          => \$opt_help,
2705
        'verbose:+'         => \$opt_verbose,
2706
        'topackage:s'       => \$opt_toPackage,
2707
        'frompackage:s'     => \$opt_fromPackage,
2708
        'justpackage:s'     => sub{ opts_add2List( \@opt_justPackage, @_ )},
2709
        'ignorepackage:s'   => sub{ opts_add2List( \@opt_ignorePackage, @_ )},
6133 dpurdie 2710
        'entireSandBox!'    => \$opt_allSandbox,
2711
        'users!'            => \$opt_processUsedBy,
2712
        'keepgoing!'        => \$opt_keepgoing,
2713
        'rescan!'           => \$opt_reScan,
7307 dpurdie 2714
        'multiBuilders:s'   => $parseMulti, 
7319 dpurdie 2715
        'onlylevel:i'       => \$opt_onlyLevel,
1329 dpurdie 2716
        );
2717
 
2718
    #
2719
    #   Merge in the user options
2720
    #
2721
    @commonOptions{keys %args} = values %args;
2722
 
2723
    local ( @ARGV );
2724
    @ARGV = @$pArray;
2725
    my $rv = GetOptions ( %commonOptions );
2726
    @$pArray = @ARGV;
2727
 
2728
    ErrorConfig('verbose' => $opt_verbose );
2729
    return $rv;
2730
}
2731
 
2732
#-------------------------------------------------------------------------------
6133 dpurdie 2733
# Function        : displayHeader 
2734
#
7307 dpurdie 2735
# Description     : Display a build header, if the entry is active
2736
#                   ie: Between a --From and --To
6133 dpurdie 2737
#
2738
# Inputs          : $fe             - Build entry
7307 dpurdie 2739
#                   Hash of options
2740
#                       indent          => Text       - Indent text
2741
#                       showPath        => Bool
2742
#                       showSimplePath  => Bool
2743
#                       testFingerPrint => Bool
6133 dpurdie 2744
#
2745
# Returns         : True if this entry is to be fully process
7319 dpurdie 2746
#                   False if its being skipped
2747
#                   
2748
#                   The entry may be have a buildError or a buildExclude
2749
#                   and still be active
6133 dpurdie 2750
#
2751
sub displayHeader
2752
{
2753
    my $fe = shift @_;
7307 dpurdie 2754
    if ($fe->{buildActive} || $fe->{buildSkip})
2755
    {
2756
        my $args = pop @_ if (@_ > 0 and UNIVERSAL::isa($_[-1],'HASH'));
2757
        #    my ($fe, %args) = @_;
6133 dpurdie 2758
 
7307 dpurdie 2759
        my $indent = $args->{indent} || '';
2760
        my $showPath = $args->{showPath};
2761
        my $showSimplePath = $args->{showSimplePath};
6133 dpurdie 2762
 
7307 dpurdie 2763
        my ($status, $estatus) = addBuildInfo($fe, $args);
2764
        $estatus = '' if $showSimplePath;
2765
 
2766
        my $msg1 = $indent . sprintf('Level:%02d [%s] Name: %s', $fe->{level}, $status, $fe->{dname} . $estatus );
2767
        if ($showSimplePath) {
2768
            my $msg1Len = length($msg1);
2769
            $msg1 = sprintf("%-*s Path: %s", 26 + $maxDname ,$msg1, $fe->{dir}); 
6133 dpurdie 2770
        }
7307 dpurdie 2771
        if ( $showPath) {
2772
            my $msg1Len = length($msg1);
2773
            if ($msg1Len < 80) {
2774
                $msg1 .= ' ' . '=' x (79 - $msg1Len);
2775
            }
2776
        }
2777
        Message( $msg1 ,  $showPath ? DisplayPath ("        Path: $fe->{dir}" ) : undef);
6133 dpurdie 2778
    }
2779
 
2780
   return $fe->{buildActive};
2781
}
2782
 
2783
#-------------------------------------------------------------------------------
2784
# Function        : addBuildInfo 
2785
#
2786
# Description     : Add some build info status
2787
#                   It will have a .sig file if its been sucessfully built
7319 dpurdie 2788
#                   
2789
#                   StatusFlags
2790
#                   Position 1: S - Build Skipped, s - Build Suppressed
2791
#                   Position 2: Blank - Not processed  , - = NoBuild, B - Built * - Current package
2792
#                   Position 3: P - Prebuilt, L - Local, M - Both local and prebuilt
2793
#                   Position 4: G - Good Fingerprint, b - Bad Fingerprint
6133 dpurdie 2794
#
2795
# Inputs          : $fe     - Package info 
2796
#
7319 dpurdie 2797
# Returns         : StatusFlags
2798
#                   StatusText
6133 dpurdie 2799
#
2800
sub addBuildInfo
2801
{
2802
    my ($fe, $args) = @_;
2803
    my $txt = '';
7319 dpurdie 2804
    my $statusS = ' ';
6133 dpurdie 2805
    my $statusB = ' ';
7319 dpurdie 2806
    my $statusP = ' ';
6133 dpurdie 2807
    my $statusF = ' ';
2808
 
2809
    unless ($fe->{buildActive}) {
2810
        $txt .= ($fe->{buildSkip}) ? ' (Build Skipped)' : ' (Build Suppressed)';
2811
        $statusS = ($fe->{buildSkip}) ? 'S' : 's';
2812
    }
2813
 
7319 dpurdie 2814
    if ($fe->{buildError} || $fe->{buildExclude} ) {
2815
        $txt .= ($fe->{buildError})   ? ' (Build Error)' : '';
2816
        $txt .= ($fe->{buildExclude}) ? ' (Build Excluded)' : '';
2817
        $statusS = ($fe->{buildError}) ? 'E' : 'e';
2818
    }
2819
 
2820
 
6133 dpurdie 2821
    if ($fe->{buildCurrent})
2822
    {
2823
        $statusB = '*';
2824
        $txt .= ' (Current Package)';
2825
    }
2826
 
7319 dpurdie 2827
    my $fpFile = getPkgFingerPrintFile($fe);
2828
    if (-f $fpFile)
6133 dpurdie 2829
    {
7319 dpurdie 2830
        my $nobFile = $fpFile;
7312 dpurdie 2831
        $nobFile =~ s~ffp$~nob~;
2832
        if (-f $nobFile) {
6133 dpurdie 2833
            $txt .= ' [NoBuild]';
2834
            $statusB = '-';
2835
        } else {
2836
            $txt .= ' [Built]';
2837
            $statusB = 'B';
2838
        }
7319 dpurdie 2839
    }
6133 dpurdie 2840
 
7319 dpurdie 2841
    if ($args->{testFingerPrint})
2842
    {
2843
        if ( TagFileMatch($fpFile, genPkgFingerPrint($fe, 'Test')) )
6133 dpurdie 2844
        {
7319 dpurdie 2845
            $txt .= ' [GoodFinger]';
2846
            $statusF = 'G';
2847
        } else {
2848
            $txt .= ' [BadFinger]';
2849
            $statusF = 'b';
6133 dpurdie 2850
        }
2851
    }
2852
 
7319 dpurdie 2853
    my ($preBuilt, $haveSignature) = locatePreBuiltPackage($fe);
2854
    if ($haveSignature) {
2855
        $txt .= ' [SigCalc]';
2856
        $statusP = 's';
2857
    }
7312 dpurdie 2858
    if ($preBuilt) {
2859
        $txt .= ' [PreBuilt]';
2860
        $statusP = 'P';
7319 dpurdie 2861
    }
2862
 
7320 dpurdie 2863
    unless ($GBE_ABT) {
2864
        my $plink = catdir( $GBE_DPKG_SBOX, $fe->{name}, 'sandbox.' . $fe->{prj} . '.lnk' );
2865
        my $linkTarget = getPackageLink ($plink);
2866
        Verbose ("Sandbox link: $plink -> $linkTarget");
2867
        if (-d $linkTarget) {
2868
            $txt .= ' [Local]';
2869
            if ($preBuilt) {
2870
                $statusP = 'M';
2871
            } else {
2872
                $statusP = 'L';
2873
            }
7319 dpurdie 2874
        }
2875
    }
7312 dpurdie 2876
 
2877
    return "$statusS$statusB$statusP$statusF", $txt ;
6133 dpurdie 2878
}
2879
 
2880
#-------------------------------------------------------------------------------
1329 dpurdie 2881
# Function        : opts_add2List
2882
#
2883
# Description     : Option processing helper
2884
#                   Add comma separated options to an array
2885
#                   User can then add items one at a time, or several at once
2886
#
2887
# Inputs          : aref        - Ref to an array to extent
2888
#                   arg2        - Option name
2889
#                   arg3        - Option value
2890
#
2891
# Returns         : 
2892
#
2893
sub opts_add2List
2894
{
2895
    my( $ref, $name, $value) = @_;
2896
    if ( $value )
2897
    {
2898
        foreach ( split(/\s*,\s*/,$value) )
2899
        {
2900
            push @{$ref}, $_;
2901
        }
2902
    }
2903
}
2904
 
2905
#-------------------------------------------------------------------------------
6133 dpurdie 2906
# Function        : genPkgFingerPrint 
2907
#
2908
# Description     : Generate a fingerprint over all files in the packages tree as
2909
#                   well as the package dependencies
2910
# 
2911
#                   Only used to detect changes to files in the subdir
2912
# 
2913
#                   This version does not actually generate a fingerprint over
2914
#                   the data file, rather the metadata of the file. This is much (much)
2915
#                   faster as there is no file i/o.
2916
#                   
2917
#                   It does assume that the file metadata will change if the file is changed
2918
#                   Will also detect the addition / deletion of files
2919
#                   
7312 dpurdie 2920
#                   Note: This signature is not machine - type safe
6133 dpurdie 2921
#                         It will vary between machines (windows/Linux/...)
7312 dpurdie 2922
#                         At the moment the Sandbox is really a single machine tool
6133 dpurdie 2923
#
2924
# Inputs          : $fe            - Package entry of the package to process
2925
#                   $mode          - Diagnostic: mode
2926
#
2927
# Returns         : A SHA1 hash over all the files
2928
#                   
2929
#
2930
sub genPkgFingerPrint
2931
{
2932
    my ($fe, $mode) = @_;
2933
    my $genPkgFingerPrintSha1;
2934
    my $genPkgFingerPrintCount;
2935
    my @fpdata;
2936
 
2937
    #
2938
    #   Get the package GbeFiles.cfg file
2939
    #       This is held in the interface directory and is created during the build
2940
    #       Since the fingerprint is only genertated AFTER a successful build the file will always
2941
    #       be available
2942
    #       
2943
    #       All we need from this file is a list of Src directories that were discovered during
2944
    #       the build. Unfortuanatley they are not always below the root of the package.
2945
    #
2946
    my $ifaceDir = getpkgInterface($fe);
2947
    return 0 unless defined $ifaceDir;
2948
    return 0 unless ToolsetFiles::GetDataFile($ifaceDir); 
2949
 
2950
    #
2951
    #   Generate a list of directories in the package
2952
    #   This is the root directory and all other Src directories discovered
2953
    #
2954
    my @dirList = ToolsetFiles::GetSubTrees($ifaceDir);
2955
    Error ("Internal:ToolsetFiles::GetDirList for $fe->{dname} not populated" ) unless @dirList;
2956
 
2957
    #
7312 dpurdie 2958
    #   Generate a hash of toolset files and toolset-internal directories
2959
    #       These won't be included in the finger print as they are subject
2960
    #       to change by a 'build'.
2961
    #
2962
    my %toolsetFiles = map { $_ => 1 } ToolsetFiles::GetFiles($ifaceDir, 1);
2963
    my %toolsetDirs  = map { $_ => 1 } ToolsetFiles::GetBuildDirs($ifaceDir);
2964
 
2965
    #
6133 dpurdie 2966
    #   Create the hash
2967
    #
2968
    $genPkgFingerPrintSha1 = Digest->new("SHA-1");
2969
    push @fpdata, $mode;
2970
 
2971
    #
2972
    #   Include all dependent packages in the fingerprint
2973
    #       We are using the sandbox fingerprint of dependent packages
2974
    #       This will ensure that a change in a package will ripple through
2975
    #
2976
    foreach my $idep ( sort keys %{$fe->{ideps}})
2977
    {
2978
        my $ipkg = $packages{$idep};
2979
        my $tagFile = getPkgFingerPrintFile($ipkg); 
2980
        my $tag = TagFileRead($tagFile);
2981
        my $text = "$tagFile: $tag";
2982
        $genPkgFingerPrintSha1->add($text);
2983
#Debug0("genPkgFingerPrint: $text, ", $genPkgFingerPrintSha1->clone->hexdigest() );
2984
        push @fpdata, $text . ':' . $genPkgFingerPrintSha1->clone->hexdigest();
2985
    }
2986
 
2987
    #
2988
    #   Anonymous sub: findFile wanted function
2989
    #   Unlike the generation of the package signature, we don't need to
2990
    #   exclude any files.
2991
    #
2992
    my $wanted = sub {
2993
        my $item = $File::Find::name;
2994
 
2995
        #
2996
        #   Get file info
2997
        #       Kill of the last access time - not useful
2998
        #       
2999
        #       Need to exclude files that change during a null build
3000
        #           /interface/GbeFiles.cfg
3001
        #           /build.log
7312 dpurdie 3002
        #           These files are tracked in GbeBuild.cfg
3003
        #       Need to directories that change during a null build
3004
        #           These files are tracked in GbeBuild.cfg
6133 dpurdie 3005
        #           
3006
        #       Symlinks present problems.
3007
        #       Some packages generate symlinks as they create file system images. The
3008
        #       links are not designed to be interpreted in the context of the current
3009
        #       computer. As a result.
3010
        #           Some may be broken - on the current machine
3011
        #           Some may address files that change - ie: /proc, /var, /dev
3012
        #           Some may address files that such as /afc, /root
3013
        #       Don't want to discard all symlinks. Many of them will address package
3014
        #       dependencies and we do want to detect changes, but those changes will
3015
        #       be picked up by the packages fingerprint.
3016
        #       
3017
        #       Directories also appear to be a problem
3018
        #       The created and modified date-times appear to be modified for no good reason
3019
        #       
3020
        #       Current solution: Do not include 'stat' data for ANY symlink or directory
3021
        #
3022
        my @data = stat($item);
3023
        my $text;
7312 dpurdie 3024
 
3025
        if ( exists $toolsetFiles{$item}) {
6133 dpurdie 3026
            $text = "$item : SKIPPED FILE : ";
3027
 
3028
        }  elsif (-d $item ) {
7312 dpurdie 3029
            $text = "$item : DIRECTORY";
3030
            if ( exists $toolsetDirs{$item}) {
3031
                $File::Find::prune = 1;
3032
                $text = "$item : SKIP INTERNAL DIRECTORY";
3033
            }
3034
 
6133 dpurdie 3035
        }  elsif (-l $item ) {
3036
            if ( ! @data) {
3037
                $text = "$item : BROKEN SYMLINK : ";
3038
            } else {
3039
                my $linkTarget = readlink($item) || 'Read Error';
3040
                $text = "$item :SYMLINK: $linkTarget";
3041
            }
3042
 
3043
        } else {
3044
            $data[8] = 0;               # atime - will change
3045
            $data[12] = '-';            # blocks - seen to change for unknown reasons
3046
            $text = "$item : @data";
3047
        }
3048
        $genPkgFingerPrintCount++;
3049
        $genPkgFingerPrintSha1->add($text);
3050
#Debug0("genPkgFingerPrint: $text, ", $genPkgFingerPrintSha1->clone->hexdigest() );
3051
        push @fpdata, $text . ':' . $genPkgFingerPrintSha1->clone->hexdigest();
3052
    };
3053
 
3054
    #
3055
    #   Process all files in the package
3056
    #
3057
    $genPkgFingerPrintCount = 0;
3058
    my $dir = $fe->{dir};
3059
    File::Find::find( { wanted => $wanted , no_chdir => 1}, @dirList );
3060
#Debug0("genPkgFingerPrint: $dir, $genPkgFingerPrintCount, ", $genPkgFingerPrintSha1->clone->hexdigest() );
3061
    push @fpdata, $dir . ':'. $genPkgFingerPrintCount . ':' . $genPkgFingerPrintSha1->clone->hexdigest();
3062
 
3063
    #
3064
    #   Debugging - delete later
3065
    #   Save FP data to a file
3066
    #
7301 dpurdie 3067
    my $fpDebugFile = catdir($GBE_SANDBOX, 'sandbox_dpkg_archive', $fe->{name} . '.' . $fe->{prj} . '_' . time() . '.fpd');
7312 dpurdie 3068
#Debug0("fpDebugFile: $fpDebugFile");
7301 dpurdie 3069
    FileCreate($fpDebugFile, @fpdata);
6133 dpurdie 3070
 
3071
    return $genPkgFingerPrintSha1->hexdigest;
3072
}
3073
 
3074
 
3075
#-------------------------------------------------------------------------------
3076
# Function        : getPkgFingerPrintFile 
3077
#
3078
# Description     : Return the package file that contains the packages Fast Finger Print
3079
#
3080
# Inputs          : $fe     - Package entry 
3081
#
3082
# Returns         : Full path to the packages fingerprint tag file
3083
#
3084
sub getPkgFingerPrintFile
3085
{
3086
    my ($fe) = @_;
3087
    my $tagFile = catdir($GBE_SANDBOX, 'sandbox_dpkg_archive', $fe->{name}, 'sandbox.' . $fe->{prj} . '.ffp');
3088
    return $tagFile;
3089
}
3090
 
3091
 
3092
#-------------------------------------------------------------------------------
359 dpurdie 3093
# Function        : SubCommandHelp
3094
#
3095
# Description     : Provide help on a subcommand
3096
#
3097
# Inputs          : $help_level             - Help Level 1,2,3
3098
#                   $topic                  - Topic Name
3099
#
3100
# Returns         : This function does not return
3101
#
3102
sub SubCommandHelp
3103
{
3104
    my ($help_level, $topic) = @_;
3105
    my @sections;
3106
    #
3107
    #   Spell out the section we want to display
3108
    #
3109
    #   Note:
3110
    #   Due to bug in pod2usage can't use 'head1' by itself
3111
    #   Each one needs a subsection.
3112
    #
3113
    push @sections, qw( NAME SYNOPSIS ) ;
3114
    push @sections, qw( ARGUMENTS OPTIONS )     if ( $help_level > 1 );
3115
    push @sections, qw( DESCRIPTION EXAMPLES )  if ( $help_level > 2 );
3116
 
3117
    #
3118
    #   Extract section from the POD
3119
    #
3120
    pod2usage({-verbose => 99,
3121
               -noperldoc => 1,
3122
               -sections => $topic . '/' . join('|', @sections) } );
3123
}
3124
 
3125
#-------------------------------------------------------------------------------
227 dpurdie 3126
#   Documentation
359 dpurdie 3127
#   NOTE
227 dpurdie 3128
#
359 dpurdie 3129
#   Each subcommand MUST have
3130
#   head1 section as used by the subcommand
3131
#       This should be empty, as the contents will NOT be displayed
3132
#   head2 sections called
3133
#       NAME SYNOPSIS ARGUMENTS OPTIONS DESCRIPTION EXAMPLES
3134
#
3135
#=head1 xxxxxx
3136
#=head2 NAME
3137
#=head2 SYNOPSIS
3138
#=head2 ARGUMENTS
3139
#=head2 OPTIONS
3140
#=head2 DESCRIPTION
3141
#=head2 EXAMPLES
3142
#
227 dpurdie 3143
 
3144
=pod
3145
 
3146
=head1 NAME
3147
 
3148
jats_sandbox - Build in a Development Sandbox
3149
 
3150
=head1 SYNOPSIS
3151
 
361 dpurdie 3152
  jats sandbox [options] command [command options]
227 dpurdie 3153
 
3154
 Options:
1329 dpurdie 3155
    -help[=n]                  - Display help with specified detail
3156
    -help -help                - Detailed help message
3157
    -man                       - Full documentation
227 dpurdie 3158
 
1329 dpurdie 3159
 Options for recursion control:
7319 dpurdie 3160
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 3161
    -toPackage=name            - Stop building after package
3162
    -fromPackage=name          - Start building from package
3163
    -justPackage=name[,name]   - Build named packages
3164
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 3165
    -entireSandbox             - Process the entire sandbox
3166
    -users                     - Process package users, not dependencies
7307 dpurdie 3167
 Options common to all commands:
6133 dpurdie 3168
    -[no]keepgoing             - Ignore errors
3169
    -[no]reScan                - Recalculate and cache sandbox structure
7307 dpurdie 3170
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
1329 dpurdie 3171
 
227 dpurdie 3172
 Commands:
3173
    help                - Same as -help
3174
    create              - Create a sandbox in the current directory
359 dpurdie 3175
    populate            - Populate the sandbox with packages
299 dpurdie 3176
    delete              - Delete the sandbox
255 dpurdie 3177
    info [[-v]-v]       - Sandbox information. -v: Be more verbose
4197 dpurdie 3178
    buildfilter         - Modify and display sandbox buildfilter
6133 dpurdie 3179
    [un]skip            - Mark a package to be skipped during the build
7319 dpurdie 3180
    [un]error           - Mark a package as having build errors
6133 dpurdie 3181
    fingerprint         - Various fingerprint operations
7304 dpurdie 3182
    testlinks           - Test / Delete broken package symlinks
7306 dpurdie 3183
    scandepth           - Set/Display the build file scan depth
227 dpurdie 3184
    cmd                 - Do commands in all sandbox components
1329 dpurdie 3185
    all                 - Do 'build', if required, then a make in all components
331 dpurdie 3186
    build               - Force 'build and make' in all sandbox components
275 dpurdie 3187
    make                - Do 'make' in all sandbox components
273 dpurdie 3188
    clean               - Do 'make clean' in all sandbox components
3189
    clobber             - Do 'build clobber' is all sandbox components
337 dpurdie 3190
    cache               - Cache external dependent packages
7319 dpurdie 3191
    writeBuildData      - Write out build data
7320 dpurdie 3192
    genPkgSigs          - Generate package Signatures
3193
    setAbtMarker        - Set Build System Marker file
227 dpurdie 3194
 
359 dpurdie 3195
 Use the command
3196
    jats sandbox 'command' -h
3197
 for command specific help
361 dpurdie 3198
 
227 dpurdie 3199
=head1 OPTIONS
3200
 
3201
=over 8
3202
 
299 dpurdie 3203
=item B<-help[=n]>
227 dpurdie 3204
 
3205
Print a brief help message and exits.
299 dpurdie 3206
There are three levels of help
227 dpurdie 3207
 
299 dpurdie 3208
=over 8
3209
 
361 dpurdie 3210
=item   1
299 dpurdie 3211
 
361 dpurdie 3212
Brief synopsis
299 dpurdie 3213
 
361 dpurdie 3214
=item   2
299 dpurdie 3215
 
361 dpurdie 3216
Synopsis and option summary
3217
 
3218
=item   3
3219
 
3220
Detailed help in man format
3221
 
299 dpurdie 3222
=back 8
3223
 
227 dpurdie 3224
=item B<-help -help>
3225
 
3226
Print a detailed help message with an explanation for each option.
3227
 
3228
=item B<-man>
3229
 
299 dpurdie 3230
Prints the manual page and exits. This is the same a -help=3
227 dpurdie 3231
 
7319 dpurdie 3232
=item B<-onlyLevel=number>
3233
 
3234
This option is available in all commands that process multiple packages.
3235
Package processing will be limited to the specified level. 
3236
 
3237
This can be used to perform a multi-machine build. Level-1 builds are performed 
3238
on all machines and the results merged into the common package store, then Level-2 builds 
3239
are performed on all machines.
3240
 
3241
Level-1 packages have no dependencies.
3242
 
3243
Level-2 packages only have dependancies on Level-1 packages
3244
 
3245
Level-N packages only have dependancies on packages below Level N-1
3246
 
1329 dpurdie 3247
=item B<-toPackage=name>
3248
 
3249
This option is available in all commands that process multiple packages.
3250
Package processing will stop at the named package.
3251
 
4688 dpurdie 3252
The package name can be specified in one of three forms:
1329 dpurdie 3253
 
4184 dpurdie 3254
=over 8
3255
 
3256
=item 1 
3257
 
3258
Just the package name. ie: MyPackage
3259
 
3260
=item 2 
3261
 
3262
The package name and the project suffix. ie: MyPackage.prj
3263
 
3264
=item 3 
3265
 
3266
The package name and version, joined with an underscore: ie: MyPackage_1.0.0000.prj
3267
 
3268
=back 8
3269
 
1329 dpurdie 3270
=item B<-fromPackage=name>
3271
 
3272
This option is available in all commands that process multiple packages.
3273
Package processing will start at the named package.
3274
 
4688 dpurdie 3275
The package name can be specified in one of the three forms described under the '-toPackage' option.
1329 dpurdie 3276
 
3277
=item B<-justPackage=name[,name]>
3278
 
3279
This option is available in all commands that process multiple packages. The
3280
named packages will be processed in the correct build order. Packages that are
3281
not named will be skipped, unless the package is being processed due to
3282
being in the 'fromPackage' to 'toPackage' range.
3283
 
3284
Multiple packages can be named either by separating names with a comma, or
3285
with multiple options.
3286
 
4688 dpurdie 3287
The package names can be specified as a mix of the three forms described under the '-toPackage' option.
4184 dpurdie 3288
 
1329 dpurdie 3289
=item B<-ignorePackage=name[,name]>
3290
 
3291
This option is available in all commands that process multiple packages. The
3292
named packages will not be processed.
3293
 
3294
Multiple packages can be named either by separating names with a comma, or
3295
with multiple options.
3296
 
3297
The exclusion of a package takes precedence over its inclusion.
3298
 
4688 dpurdie 3299
The package names can be specified as a mix of the three forms described under the '-toPackage' option.
4184 dpurdie 3300
 
6133 dpurdie 3301
=item B<-[no]entireSandbox>
3302
 
7307 dpurdie 3303
This option will override the automatic package localisation that will occur if the user starts the command
3304
within a subdirectory of a package within the sandbox and will process the entire sanbbox.
6133 dpurdie 3305
 
3306
If the user start the command within a subdirectory of a package then the sandbox commands will be localised
3307
to the current package and the dependencies of the package.
3308
 
3309
=item B<-[no]users>
3310
 
3311
This option will completely change the packages considered to be built. The normal operation is to consider
3312
the current package and all packages that it depends upon.
3313
 
3314
This option will consider all packages that 'use' the current package, either directly or indirectly. It does not 
3315
include the 'current' pakage in this list. The assumption is that the current package has been sucessfully built 
3316
and needs to tested.
3317
 
3318
This option will work when they is a current package to be processed and not the entire sandbox.
3319
 
3320
The intended purpose of this option is to simplify regression testing.
3321
 
3322
=item B<-[no]keepgoing>
3323
 
3324
This options controls the behaviour of the command when an error is encountered.
3325
 
3326
The default operation is to terminate the command on the package with the
3327
error. This can be modified so that errors are ignored.
3328
 
3329
=item B<-[no]reScan>
3330
 
3331
This option controls the process of locating build files within the sandbox.
3332
 
3333
The default operation is to scan the sandbox and to cache the location of the build files.
3334
 
3335
If a package is added or removed from the sandbox, then the sandbox will need to be rescanned.
3336
Jats will detect when a package has been added or removed, but if the internal structure of the
3337
packages has changed the cached data may be incorrect. 
3338
 
7307 dpurdie 3339
=item B<-multiBuilders=mode>
3340
 
3341
If a package-name can be built by multiple packages then the sandbox processing will
3342
normally report an error.
3343
 
3344
This option allow the error to be reported as a warning or to be ignored altogether. The named package will be 
3345
excluded from the build set.
3346
 
3347
Valid values for 'mode' are: error, report and ignore.  The default mode is 'error'.
3348
 
279 dpurdie 3349
=back
3350
 
227 dpurdie 3351
=head1 DESCRIPTION
3352
 
299 dpurdie 3353
This program is the primary tool for the maintenance of Development Sandboxes.
3354
 
227 dpurdie 3355
More documentation will follow.
3356
 
279 dpurdie 3357
=head2 SANDBOX DIRECTORY
3358
 
299 dpurdie 3359
The sandbox directory is marked as being a sandbox through the use of the
3360
'sandbox create' command. This will create a suitable structure within the
279 dpurdie 3361
current directory.
3362
 
3363
Several JATS commands operate differently within a sandbox. The 'extract' and
365 dpurdie 3364
'release' commands will create static views within the sandbox and not the
279 dpurdie 3365
normal directory. The 'sandbox' sub commands can only be used within a sandbox.
3366
 
3367
The sandbox directory contains sub directories, each should contain a single
359 dpurdie 3368
package. Sub directories may be created with the 'jats extract' command or with the
3369
'jats sandbox populate' command.
279 dpurdie 3370
 
6133 dpurdie 3371
Note: Symbolic links are not supported. They cannot work as the sandbox mechanism
365 dpurdie 3372
requires that all the packages be contained within a sub directory tree so
279 dpurdie 3373
that the root of the sandbox can be located by a simple scan of the directory
3374
tree.
3375
 
325 dpurdie 3376
If a package subdirectory contains a file called 'stop' or 'stop.
3377
<GBE_MACHTYPE>', then that package will not be considered as a part of the
6133 dpurdie 3378
build-set. A 'stop' file will prevent consideration for all build platforms. The 'stop.
325 dpurdie 3379
<GBE_MACHTYPE>' will only prevent consideration if being built on a GBE_MACHTYPE
3380
type of computer.
279 dpurdie 3381
 
3559 dpurdie 3382
If the sandbox contains a file called 'buildfilter', then the contents of the
3383
file will be read and used a buildfilter. The file is processed by reading each
3384
line and:
3385
 
3386
=over 4
3387
 
4184 dpurdie 3388
=item * 
3559 dpurdie 3389
 
4184 dpurdie 3390
Removing white space at both ends of the line
3559 dpurdie 3391
 
4184 dpurdie 3392
=item * 
3559 dpurdie 3393
 
4184 dpurdie 3394
Removing empty lines
3559 dpurdie 3395
 
4184 dpurdie 3396
=item * 
3397
 
3398
Lines that start with a # are comments and are removed
3399
 
3400
=item * 
3401
 
3402
Remaining lines are joined together to form a buildfilter
3403
 
3559 dpurdie 3404
=back
3405
 
7319 dpurdie 3406
=for comment ==================================================================
3407
 
359 dpurdie 3408
=head1 Create Sandbox
299 dpurdie 3409
 
359 dpurdie 3410
=head2 NAME
299 dpurdie 3411
 
359 dpurdie 3412
Create Sandbox
3413
 
3414
=head2 SYNOPSIS
3415
 
1329 dpurdie 3416
jats sandbox create [command options]
359 dpurdie 3417
 
3418
 Command Options
3419
    -help[=n]               - Command specific help, [n=1,2,3]
3420
    -verbose[=n]            - Verbose operation
3421
 
3422
=head2 OPTIONS
3423
 
7301 dpurdie 3424
The 'create' command takes no options.
359 dpurdie 3425
 
3426
=head2 DESCRIPTION
3427
 
299 dpurdie 3428
The 'create' command will create a sandbox in the users current directory. It is
3429
not possible to create a sandbox within a sandbox.
3430
 
3431
A sandbox can be created in a directory that contains files and subdirectories.
3432
 
3433
The create command simply places a known directory in the current directory.
359 dpurdie 3434
This directory is used by the sandboxing process. It may be manually deleted, or
299 dpurdie 3435
deleted with the 'delete' command.
3436
 
7319 dpurdie 3437
=for comment ==================================================================
3438
 
359 dpurdie 3439
=head1 Populate Sandbox
3440
 
3441
=head2 NAME
3442
 
3443
Populate a Sandbox
3444
 
3445
=head2 SYNOPSIS
3446
 
1329 dpurdie 3447
jats sandbox populate [command options] [packageName packageVersion]
359 dpurdie 3448
 
7307 dpurdie 3449
 Common Options:
3450
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 3451
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 3452
    -toPackage=name            - Stop building after package
3453
    -fromPackage=name          - Start building from package
3454
    -justPackage=name[,name]   - Build named packages
3455
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 3456
    -entireSandbox             - Process the entire sandbox
3457
    -users                     - Process package users, not dependencies
7307 dpurdie 3458
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
3459
    -[no]keepgoing             - Ignore errors
3460
    -[no]reScan                - Recalculate and cache sandbox structure
3461
 Command Specific Options
1329 dpurdie 3462
    -excludePackage=name[,name]- Do not extract named package
3463
    -recurse[=n]               - Locate dependencies within packages
3464
    -all                       - Populate with all dependencies
3465
    -missing                   - Locate missing packages
3466
    -show                      - Show packages that would be extracted
3467
    -test                      - Do not extract packages
3468
    -<Other>                   - Pass options to jats extract
359 dpurdie 3469
 
3470
=head2 ARGUMENTS
3471
 
3472
The 'populate' command can take a package name and version as arguments. It will
3473
then populate the sandbox with this package. See 'DESCRIPTION' for details.
3474
 
3475
=head2 OPTIONS
3476
 
3477
The 'populate' command takes the following options:
3478
 
3479
=over 4
3480
 
1329 dpurdie 3481
=item -excludePackage=name[,name]
3482
 
3483
This option prevents one, or more, packages from populating the sandbox.
3484
Packages specified with this option will not be extracted from version control
3485
and added to the sandbox.
3486
 
4688 dpurdie 3487
Packages can be identified in three ways:
1329 dpurdie 3488
 
3489
=over 4
3490
 
3491
=item 1. Package Name
3492
 
3493
All package versions matching the named package will be excluded.
3494
 
3495
=item 2. Package Name and Version
3496
 
3497
Only the specified version of the named package will be excluded. The
3498
user specifies the package name and version as a single string separated with
3499
an underscore. ie: core_devl_2.100.5000.cr
3500
 
3501
=item 3. Package Name and Suffix
3502
 
3503
All packages matching the named package and project will be excluded. The
3504
user specifies the package name and project as a single string separated with
3505
a dot. ie: core_devl.cr
3506
 
3507
 
3508
=back
3509
 
359 dpurdie 3510
=item -recurse[=N]
3511
 
3512
This option will modify the operation of the command such that dependencies
3513
of named packages can also be extracted into the sandbox.
3514
 
3515
The default operation is to only extract named packages. If the option is
3516
specified then all dependent packages are processed. An optional numeric argument
3517
can be specified to limit the depth of the recursion.
3518
 
1329 dpurdie 3519
=item -all
3520
 
3521
This option will populate the sandbox will all dependencies of packages that are
3522
currently in the sandbox.
3523
 
3524
The global options that control recursion will affect the packages that are
3525
processed.
3526
 
3527
This option cannot be used with the '-missing' option.
3528
 
359 dpurdie 3529
=item -missing
3530
 
3531
This option will modify the operation of the dependency recursion scanning such
3532
that dependent packages that exist in a package archive will not be extracted.
3533
 
3534
Use of this option allows a sandbox to be populated with packages that are
3535
required by packages in the sandbox, but are not available in a package archive.
3536
 
1329 dpurdie 3537
The global options that control recursion will affect the packages that are
3538
processed.
3539
 
3540
This option cannot be used with the '-all' option.
3541
 
3542
=item -show
3543
 
3544
This option will prevent the command from performing the extraction. It will
3545
simply display the names of the packages that would be extracted.
3546
 
359 dpurdie 3547
=item -test
3548
 
3549
This option will prevent the command from performing the extraction. It will
3550
simply display the JATS commands that can be used to perform the extraction.
3551
 
3552
=item -<Other>
3553
 
3554
Options not understood by the 'populate' sub command will be passed through
3555
the package extraction program. Useful options include:
3556
 
363 dpurdie 3557
=over 4
359 dpurdie 3558
 
361 dpurdie 3559
=item *
359 dpurdie 3560
 
361 dpurdie 3561
-extractfiles
359 dpurdie 3562
 
361 dpurdie 3563
=item *
3564
 
3565
-branch=<branch name>
3566
 
359 dpurdie 3567
=back
3568
 
3569
=back
3570
 
3571
=head2 DESCRIPTION
3572
 
3573
The 'populate' command can be used to assist in populating the sandbox. It has
3574
two modes of operation.
3575
 
363 dpurdie 3576
=over 4
359 dpurdie 3577
 
361 dpurdie 3578
=item 1
359 dpurdie 3579
 
361 dpurdie 3580
Named Package
3581
 
363 dpurdie 3582
If the user specifies both a package name and a package version then the command
359 dpurdie 3583
will populate the sandbox with that package and optionally its dependencies.
3584
 
361 dpurdie 3585
=item 2
359 dpurdie 3586
 
361 dpurdie 3587
Determine missing dependencies
3588
 
359 dpurdie 3589
If the user does not specify a package name and version, but does specify
3590
the '-missing' option,  then the command will examine the current sandbox and
3591
determine missing dependent packages. It will then populate the sandbox with
3592
these packages and optionally there dependencies.
3593
 
3594
=back
3595
 
3596
=head2 EXAMPLES
3597
 
3598
=over 4
3599
 
361 dpurdie 3600
=item *
359 dpurdie 3601
 
361 dpurdie 3602
jats sandbox populate package1 version1
3603
 
359 dpurdie 3604
This command will populate the sandbox with version1 of package1, if it does not
3605
already exist in the sandbox.
3606
 
361 dpurdie 3607
=item *
359 dpurdie 3608
 
361 dpurdie 3609
jats sandbox populate package1 version1 -recurse -missing
3610
 
359 dpurdie 3611
This command will populate the sandbox with version1 of package1, if it does not
3612
already exist in the sandbox, together will all the packages dependencies that
3613
are not available in a package archive.
3614
 
361 dpurdie 3615
=item *
359 dpurdie 3616
 
361 dpurdie 3617
jats sandbox populate -recurse -missing
3618
 
359 dpurdie 3619
This command will examine the current sandbox and populate the sandbox with
3620
packages that are required to build the packages in the sandbox and the
3621
dependencies of these packages, provide the dependent package is not in a
3622
package archive.
3623
 
361 dpurdie 3624
=item *
359 dpurdie 3625
 
361 dpurdie 3626
jats sandbox populate
3627
 
359 dpurdie 3628
This command will examine the current sandbox and populate the sandbox with
3629
packages that are required to build the packages in the sandbox. It will not
3630
examine the dependents of these packages.
3631
 
3632
=back
3633
 
7319 dpurdie 3634
=for comment ==================================================================
3635
 
359 dpurdie 3636
=head1 Delete Sandbox
3637
 
3638
=head2 NAME
3639
 
4688 dpurdie 3640
Delete a sandbox
359 dpurdie 3641
 
3642
=head2 SYNOPSIS
3643
 
3644
jats sandbox [options] delete
3645
 
3646
 Options:
3647
    -help[=n]               - Help message, [n=1,2,3]
3648
    -man                    - Full documentation [-help=3]
3649
    -verbose[=n]            - Verbose command operation
3650
 
3651
=head2 DESCRIPTION
3652
 
299 dpurdie 3653
The 'delete' command will delete the sandbox's marker directory. The command may
3654
be executed anywhere within the sandbox.
3655
 
359 dpurdie 3656
Once the sandbox has been deleted, the user must remove the components within the
299 dpurdie 3657
sandbox.
3658
 
7319 dpurdie 3659
=for comment ==================================================================
3660
 
359 dpurdie 3661
=head1 Sandbox Information
299 dpurdie 3662
 
359 dpurdie 3663
=head2 NAME
3664
 
3665
Display Sandbox Information
3666
 
3667
=head2 SYNOPSIS
3668
 
1329 dpurdie 3669
jats sandbox info [command options]
359 dpurdie 3670
 
7307 dpurdie 3671
 Common Options:
3672
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 3673
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 3674
    -toPackage=name            - Stop building after package
3675
    -fromPackage=name          - Start building from package
3676
    -justPackage=name[,name]   - Build named packages
3677
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 3678
    -entireSandbox             - Process the entire sandbox
3679
    -users                     - Process package users, not dependencies
7307 dpurdie 3680
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
3681
    -[no]keepgoing             - Ignore errors
3682
    -[no]reScan                - Recalculate and cache sandbox structure
3683
 Command Specific Options
3684
    -verbose[=n]               - Display more information
3685
    -usedby                    - Display package usage information
6133 dpurdie 3686
    -fingerprint               - Display fingerprint information
7306 dpurdie 3687
    -[no]dependencies          - Display external dependencies (default)
3688
    -[no]buildorder            - Display build order (default)
7307 dpurdie 3689
    -[no]path                  - Display path to package
361 dpurdie 3690
 
359 dpurdie 3691
=head2 OPTIONS
3692
 
3693
=over
3694
 
3695
=item B<-verbose[=n]>
3696
 
3697
This options will increase the verbosity of the information being displayed.
3698
Values 1 and 2 are described in the detailed 'DESCRIPTION'. Other values are
3699
reserved for diagnostic use.
3700
 
6133 dpurdie 3701
=item B<-usedby>
3702
 
3703
This option will list all packages that use the current package, both directly and
3704
indirectly. These are packages that should be tested whan changes are made to the 
3705
package.
3706
 
3707
=item B<-fingerprint>
3708
 
3709
This option will cause the information display to include that status of each packages fingerprint.
3710
 
3711
This will slow down the display as the calculation can be time consuming.
3712
 
7306 dpurdie 3713
=item B<-[no]dependencies>
3714
 
3715
This option will cause the information display to include all the external dependencies.
3716
 
3717
=item B<-[no]buildorder>
3718
 
3719
This option will cause the information display to include all the build order.
3720
 
7307 dpurdie 3721
=item B<-[no]path>
3722
 
3723
This option will cause the information display to include all the path to the build file
3724
 
359 dpurdie 3725
=back
3726
 
3727
=head2 DESCRIPTION
3728
 
299 dpurdie 3729
The 'info' command will display information about the build order and the
359 dpurdie 3730
dependencies of packages that it finds within the sandbox.
299 dpurdie 3731
 
359 dpurdie 3732
The command works within various levels of verbosity:
299 dpurdie 3733
 
3734
=over 8
3735
 
361 dpurdie 3736
=item *
299 dpurdie 3737
 
361 dpurdie 3738
No Verbosity
3739
 
299 dpurdie 3740
The basic command will display the build order and the external
335 dpurdie 3741
dependencies. External dependencies may be prefixed with one of the
3742
following indicators:
299 dpurdie 3743
 
335 dpurdie 3744
=over 8
3745
 
361 dpurdie 3746
=item   '+' Multiple versions of this package are being used by sandboxed components.
335 dpurdie 3747
 
361 dpurdie 3748
=item   '*' The package cannot be found in any of the package archives.
335 dpurdie 3749
 
3750
=back
3751
 
361 dpurdie 3752
=item *
299 dpurdie 3753
 
361 dpurdie 3754
Verbosity of 1
3755
 
359 dpurdie 3756
This level of verbosity will display the build order and detailed information
299 dpurdie 3757
on the dependencies. The dependencies will be prefixed with:
3758
 
3759
=over 8
3760
 
361 dpurdie 3761
=item   E Dependent Package is external to the sandbox
299 dpurdie 3762
 
361 dpurdie 3763
=item   I Dependent Package is internal to the sandbox
299 dpurdie 3764
 
3765
=back
3766
 
335 dpurdie 3767
External dependencies may be prefixed with one of the indicators described for
3768
no-verbosity. Additionally the internal consumer of the external package is also
3769
shown. These are prefixed with a 'U'.
299 dpurdie 3770
 
361 dpurdie 3771
=item *
299 dpurdie 3772
 
361 dpurdie 3773
Verbosity of 2
3774
 
6133 dpurdie 3775
Usage information will also be displayed. This is the same as invoking the 
3776
'-usedby' option.
299 dpurdie 3777
 
361 dpurdie 3778
=item *
299 dpurdie 3779
 
361 dpurdie 3780
Verbosity over 2
3781
 
359 dpurdie 3782
This should be considered a debug option. Undocumented internal information will
299 dpurdie 3783
be displayed.
3784
 
3785
=back
3786
 
7319 dpurdie 3787
=for comment ==================================================================
3788
 
4197 dpurdie 3789
=head1 Buildfilter
3790
 
3791
=head2 NAME
3792
 
3793
Display and Modify Sandbox buildfilter
3794
 
3795
=head2 SYNOPSIS
3796
 
3797
jats sandbox buildfilter [command options] [TARGETS]+
3798
 
3799
 Command Options
3800
    -help[=n]               - Command specific help, [n=1,2,3]
3801
    -man                    - Same as -help=3
3802
 
3803
 Target Names
3804
    -TARGET                 - Remove target from the current buildfilter
3805
    +TARGET                 - Add target to current buildfilter
3806
    TARGET                  - If first target, then reset buildfilter 
3807
                              and add target, otherwise add target.
3808
 
3809
=head2 OPTIONS
3810
 
3811
The 'buildfilter' command takes the following options:
3812
 
3813
=over 8
3814
 
3815
=item -TARGET
3816
 
3817
If a target name starts with a '-' and is not an option, then that target will be
3818
removed from the current buildfilter. 
3819
 
3820
If the named target is not a part of the current buildfilter then nothing will happen.
3821
 
3822
=item +TARGET
3823
 
3824
If a target name starts with a '+' then that target will be added to the current buildfilter.
3825
 
3826
If the named target is already a part of the current buildfilter then nothing will happen.
3827
 
3828
 
3829
=item TARGET
3830
 
3831
If a target name does not start with either a '-' or a '+' then the target will be added to the
3832
current buildfilter.
3833
 
3834
If this is the first named target then the build filter will be set to this one target.
3835
 
3836
=back
3837
 
3838
=head2 DESCRIPTION
3839
 
3840
The 'buildfilter' command will display and optionally modify the build filter used within
3841
the sandbox.
3842
 
3843
=head2 EXAMPLES
3844
 
3845
The command
3846
 
3847
    jats sandbox buildfilter 
3848
 
3849
will simply display the current buildfilter.
3850
 
3851
The command
3852
 
3853
    jats sandbox buildfilter +COBRA +PPC_603E
3854
 
3855
will append the build targets COBRA and PPC_603E to the current buildfilter.
3856
 
3857
The command
3858
 
3859
    jats sandbox buildfilter -COBRA
3860
 
3861
will remove the build target COBRA from the current buildfilter.
3862
 
3863
The command
3864
 
3865
    jats sandbox buildfilter COBRA +PPC_603E
3866
 or jats sandbox buildfilter COBRA PPC_603E
3867
 
3868
will set the buildfilter to be COBRA and PPC_603E
3869
 
7319 dpurdie 3870
=for comment ==================================================================
3871
 
6133 dpurdie 3872
=head1 Skip Build
3873
 
3874
=head2 NAME
3875
 
3876
Mark a package to be skipped during the build
3877
 
3878
=head2 SYNOPSIS
3879
 
3880
jats sandbox [un]skip [command options] [PackageName]+
3881
 
3882
 Command Options
3883
    -help[=n]               - Command specific help, [n=1,2,3]
3884
    -man                    - Same as -help=3
3885
    -[no]machine            - Skip on on this type of machine
3886
 
3887
=head2 ARGUMENTS
3888
 
3889
Arguments to the 'skip' command are the names of packages to be marked.
3890
 
3891
If no packages are named then the command will display all packages that are marked to be skipped.
3892
 
3893
If the named package is '.', then the current package will be excluded.
3894
 
3895
=head2 OPTIONS
3896
 
3897
The 'skip' command takes the following options:
3898
 
3899
=over 8
3900
 
3901
=item -[no]machine
3902
 
3903
This option will flag that the package will be skipped only on this type of build machine.
3904
 
3905
=back
3906
 
3907
=head2 DESCRIPTION
3908
 
3909
The 'skip' command marked the named packages to be skipped during the build, or the mark will be removed.
3910
 
3911
=head2 EXAMPLES
3912
 
3913
The command
3914
 
3915
    jats sandbox skip package1 
3916
 
3917
will mark package1 to be skipped during the following builds.
3918
 
7319 dpurdie 3919
=for comment ==================================================================
3920
 
3921
=head1 Error Build
3922
 
3923
=head2 NAME
3924
 
3925
Mark a package as having a build error
3926
 
3927
=head2 SYNOPSIS
3928
 
3929
jats sandbox [un]error [command options] [PackageName]+
3930
 
3931
 Command Options
3932
    -help[=n]               - Command specific help, [n=1,2,3]
3933
    -man                    - Same as -help=3
3934
    -[no]machine            - Skip on on this type of machine
7320 dpurdie 3935
    -[no]removeAll          - Remove all error indications
7319 dpurdie 3936
 
3937
=head2 ARGUMENTS
3938
 
3939
Arguments to the 'error' command are the names of packages to be marked.
3940
 
3941
If no packages are named then the command will display all packages that are marked as errored.
3942
 
3943
If the named package is '.', then the current package will be marked.
3944
 
3945
=head2 OPTIONS
3946
 
3947
The 'error' command takes the following options:
3948
 
3949
=over 8
3950
 
3951
=item -[no]machine
3952
 
3953
This option will flag that the package will be skipped only on this type of build machine.
3954
 
7320 dpurdie 3955
=item -[no]removeAll
3956
 
3957
This option will cause all error indication to be removed. It can be used in conjunction with 
3958
other operations.
3959
 
7319 dpurdie 3960
=back
3961
 
3962
=head2 DESCRIPTION
3963
 
3964
The 'error' command markes the named packages to as having build errors. These packages, and packages that
3965
they consume them will be excluded from any build consideration.
3966
 
3967
=head2 EXAMPLES
3968
 
3969
The command
3970
 
3971
    jats sandbox error package1 
3972
 
3973
will mark package1 as having a build error.
3974
 
3975
=for comment ==================================================================
3976
 
6133 dpurdie 3977
=head1 Sandbox Finger Print
3978
 
3979
=head2 NAME
3980
 
3981
Various fingerprint operations
3982
 
3983
=head2 SYNOPSIS
3984
 
3985
jats sandbox finger[print] [options]
3986
 
3987
 Command Options
3988
    -help[=n]               - Command specific help, [n=1,2,3]
3989
    -man                    - Same as -help=3
3990
    -[no]generate           - Generate a fingerprint over a package
3991
    -[no]delete             - Delete the fingerprint information
3992
 
3993
=head2 ARGUMENTS
3994
 
3995
Arguments to the 'fingerprint' command are the names of packages to be processed.
3996
 
3997
If no packages are named then the command will process the current package, if any.
3998
 
3999
=head2 OPTIONS
4000
 
4001
The 'fingerprint' command takes the following options:
4002
 
4003
=over 8
4004
 
4005
=item -[no]generate
4006
 
4007
This option will cause the fingerprint of the package to be regenerated.
4008
 
4009
=item -[no]delete
4010
 
4011
This option will delete the fingerprint information associated wit a package.
4012
 
4013
=back
4014
 
4015
=head2 DESCRIPTION
4016
 
4017
The 'fingerprint' command, will by default, examine the packages fingerprint and report
4018
if the package has been modified since the fingerprint was created.
4019
 
4020
Options allow different modes of operation.
4021
 
4022
A fingerprint may only be created after the 'build.pl' file has been created. It requires the
4023
build process to generate metadata about the package.
4024
 
4025
=head2 EXAMPLES
4026
 
4027
The command
4028
 
4029
    jats sandbox fingerprint -generate
4030
 
4031
will regenerate the fingerprint of the current package. Useful after trivial edits to 
4032
enable the sandbox builder to bypass the package and not to rebuild it and all of its dependents.
4033
 
7319 dpurdie 4034
=for comment ==================================================================
4035
 
359 dpurdie 4036
=head1 Command all
331 dpurdie 4037
 
359 dpurdie 4038
=head2 NAME
4039
 
4040
Build packages in the sandbox
4041
 
4042
=head2 SYNOPSIS
4043
 
1329 dpurdie 4044
jats sandbox all [command options] [arguments]
359 dpurdie 4045
 
7307 dpurdie 4046
 Common Options:
4047
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 4048
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 4049
    -toPackage=name            - Stop building after package
4050
    -fromPackage=name          - Start building from package
4051
    -justPackage=name[,name]   - Build named packages
4052
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 4053
    -entireSandbox             - Process the entire sandbox
4054
    -users                     - Process package users, not dependencies
7307 dpurdie 4055
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
6133 dpurdie 4056
    -[no]keepgoing             - Ignore errors
7307 dpurdie 4057
    -[no]reScan                - Recalculate and cache sandbox structure
4058
 Command Specific Options
6133 dpurdie 4059
    -[no]skip                  - Skip if no source change (default:skip)
359 dpurdie 4060
 
6133 dpurdie 4061
 
359 dpurdie 4062
=head2 ARGUMENTS
4063
 
4064
Arguments are passed to the 'make' phase of the process.
4065
 
4066
=head2 OPTIONS
4067
 
6133 dpurdie 4068
=over
359 dpurdie 4069
 
6133 dpurdie 4070
=item B<-[no]skip>
4071
 
4072
This operation overides the default smart building mechanism.
4073
 
4074
By default, a package will not be built if the last build was successful and 
4075
there has not been any change to the source of the package, since the last 
4076
succesful build.
4077
 
4078
=back
4079
 
359 dpurdie 4080
=head2 DESCRIPTION
4081
 
331 dpurdie 4082
The 'all' command will perform build, if the build files are out of date,
4083
followed by a make in each of the packages within the sandbox, in the correct
4084
build order.
4085
 
4086
Any arguments are passed to the 'make' phase of the process.
4087
 
4088
This command may be used to:
4089
 
4090
=over 8
4091
 
361 dpurdie 4092
=item *
331 dpurdie 4093
 
361 dpurdie 4094
Pickup any build file changes.
331 dpurdie 4095
 
361 dpurdie 4096
=item *
4097
 
4098
Resume a failed build.
4099
 
331 dpurdie 4100
=back
4101
 
7319 dpurdie 4102
=for comment ==================================================================
4103
 
359 dpurdie 4104
=head1 Command build
331 dpurdie 4105
 
359 dpurdie 4106
=head2 NAME
4107
 
4108
Build packages in the sandbox
4109
 
4110
=head2 SYNOPSIS
4111
 
1329 dpurdie 4112
jats sandbox build [command options] [arguments]
359 dpurdie 4113
 
7307 dpurdie 4114
 Common Options:
4115
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 4116
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 4117
    -toPackage=name            - Stop building after package
4118
    -fromPackage=name          - Start building from package
4119
    -justPackage=name[,name]   - Build named packages
4120
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 4121
    -entireSandbox             - Process the entire sandbox
4122
    -users                     - Process package users, not dependencies
7307 dpurdie 4123
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
6133 dpurdie 4124
    -[no]keepgoing             - Ignore errors
7307 dpurdie 4125
    -[no]reScan                - Recalculate and cache sandbox structure
4126
 Command Specific Options
6133 dpurdie 4127
    -[no]skip                  - Skip if no source change (default:skip)
359 dpurdie 4128
 
4129
=head2 ARGUMENTS
4130
 
4131
Arguments are passed to the 'make' phase of the process.
4132
 
4133
=head2 OPTIONS
4134
 
6133 dpurdie 4135
=over
359 dpurdie 4136
 
6133 dpurdie 4137
=item B<-[no]skip>
4138
 
4139
This operation overides the default smart building mechanism.
4140
 
4141
By default, a package will not be built if the last build was successful and 
4142
there has not been any change to the source of the package, since the last 
4143
succesful build.
4144
 
4145
=back
4146
 
359 dpurdie 4147
=head2 DESCRIPTION
4148
 
331 dpurdie 4149
The 'build' command will force a build followed by a make in each of the packages
4150
within the sandbox, in the correct build order.
4151
 
4152
Any arguments are passed to the 'make' phase of the process.
4153
 
4154
In practice, the 'sandbox all' command is quicker.
4155
 
7319 dpurdie 4156
=for comment ==================================================================
4157
 
359 dpurdie 4158
=head1 Clean
331 dpurdie 4159
 
359 dpurdie 4160
=head2 NAME
4161
 
4162
Clean all sandbox components
4163
 
4164
=head2 SYNOPSIS
4165
 
1329 dpurdie 4166
jats sandbox clean|clobber [command options]
359 dpurdie 4167
 
7307 dpurdie 4168
 Common Options:
4169
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 4170
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 4171
    -toPackage=name            - Stop building after package
4172
    -fromPackage=name          - Start building from package
4173
    -justPackage=name[,name]   - Build named packages
4174
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 4175
    -entireSandbox             - Process the entire sandbox
4176
    -users                     - Process package users, not dependencies
7307 dpurdie 4177
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
6133 dpurdie 4178
    -[no]keepgoing             - Ignore errors
7307 dpurdie 4179
    -[no]reScan                - Recalculate and cache sandbox structure
359 dpurdie 4180
 
4181
=head2 ARGUMENTS
4182
 
4183
None
4184
 
4185
=head2 OPTIONS
4186
 
7307 dpurdie 4187
The are no command specific options.
359 dpurdie 4188
 
4189
=head2 DESCRIPTION
4190
 
4191
The 'clean' command will perform a 'jats make clean' in all components in the
4192
sandbox.
4193
 
4194
The 'clobber' command will perform a 'jats clobber' in all components in the
4195
sandbox.
4196
 
7319 dpurdie 4197
=for comment ==================================================================
4198
 
359 dpurdie 4199
=head1 make
4200
 
4201
=head2 NAME
4202
 
4203
Make packages in the sandbox
4204
 
4205
=head2 SYNOPSIS
4206
 
1329 dpurdie 4207
jats sandbox make [command options] [arguments]
359 dpurdie 4208
 
7307 dpurdie 4209
 Common Options:
4210
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 4211
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 4212
    -toPackage=name            - Stop building after package
4213
    -fromPackage=name          - Start building from package
4214
    -justPackage=name[,name]   - Build named packages
4215
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 4216
    -entireSandbox             - Process the entire sandbox
4217
    -users                     - Process package users, not dependencies
7307 dpurdie 4218
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
4219
    -[no]keepgoing             - Ignore errors
4220
    -[no]reScan                - Recalculate and cache sandbox structure
359 dpurdie 4221
 
4222
=head2 ARGUMENTS
4223
 
4224
Arguments are passed to the 'make' phase of the process.
4225
 
4226
=head2 OPTIONS
4227
 
4228
The are no command specific options.
4229
 
4230
=head2 DESCRIPTION
4231
 
331 dpurdie 4232
The 'make' command will perform a 'make' operation in each of the packages
4233
within the sandbox, in the correct build order.
4234
 
4235
Any arguments are passed to the 'make'.
4236
 
7319 dpurdie 4237
=for comment ==================================================================
4238
 
359 dpurdie 4239
=head1 cmd
331 dpurdie 4240
 
359 dpurdie 4241
=head2 NAME
4242
 
4243
Process each package with a specified command.
4244
 
4245
=head2 SYNOPSIS
4246
 
1329 dpurdie 4247
jats sandbox cmd [command options] [arguments]
359 dpurdie 4248
 
7307 dpurdie 4249
 Common Options:
4250
    -help[=n], -man            - Command specific help, [n=1,2,3]
7319 dpurdie 4251
    -onlyLevel=number          - Limit building to one level
1329 dpurdie 4252
    -toPackage=name            - Stop building after package
4253
    -fromPackage=name          - Start building from package
4254
    -justPackage=name[,name]   - Build named packages
4255
    -ignorePackage=name[,name] - Do not build named packages
6133 dpurdie 4256
    -entireSandbox             - Process the entire sandbox
4257
    -users                     - Process package users, not dependencies
7307 dpurdie 4258
    -multiBuilders=mode        - Handle conflicting packages. error|report|ignore
4259
    -[no]keepgoing             - Ignore errors
4260
    -[no]reScan                - Recalculate and cache sandbox structure
7308 dpurdie 4261
 Command Specific Options
4262
    -[no]reverse               - Reverse the processing order
359 dpurdie 4263
 
4264
=head2 ARGUMENTS
4265
 
4266
Arguments are passed to a JATS command.
4267
 
4268
=head2 OPTIONS
4269
 
7308 dpurdie 4270
The 'cmd' command takes the following options:
359 dpurdie 4271
 
7308 dpurdie 4272
=over 8
4273
 
4274
=item -[no]reverse
4275
 
4276
This option will controlls the order in which the packages will be processed.
4277
 
4278
The default option is 'noreverse'. Packages will be processed in the build order.
4279
 
2054 dpurdie 4280
=back
4281
 
359 dpurdie 4282
=head2 DESCRIPTION
4283
 
331 dpurdie 4284
The 'cmd' command will pass all of its arguments to JATS in the build directory
4285
of each of the packages within the sandbox, in the package build order.
4286
 
4086 dpurdie 4287
=head2 EXAMPLES
4288
 
4289
The following command will update all the Subversion-based packages in the sandbox.
4290
 
4291
    jats sandbox cmd eprog svn update
4292
 
4293
Note the use of 'eprog' in the command string. This tells JATS to run the external
4294
(to JATS) program. Without this the command would run the JATS-internal command
4295
called 'svn' - with different results.
4296
 
4297
The following command will update the dependencies in the build.pl files to match
4298
those of a nominated release. This will only affect the package versions
4299
external to the sandbox, although all version information in the build.pl
4300
files will be updated.
4301
 
4302
    jats sandbox cmd upddep -rtagid=12345
4303
 
7319 dpurdie 4304
=for comment ==================================================================
4305
 
359 dpurdie 4306
=head1 Cache
331 dpurdie 4307
 
359 dpurdie 4308
=head2 NAME
331 dpurdie 4309
 
359 dpurdie 4310
Cache dependent packages
331 dpurdie 4311
 
359 dpurdie 4312
jats sandbox [options] cache [command options]
331 dpurdie 4313
 
359 dpurdie 4314
 Options:
4315
    -help[=n]               - Help message, [n=1,2,3]
4316
    -man                    - Full documentation [-help=3]
4317
    -verbose[=n]            - Verbose command operation
337 dpurdie 4318
 
359 dpurdie 4319
 Command Options
4320
    -help[=n]               - Command specific help, [n=1,2,3]
337 dpurdie 4321
 
359 dpurdie 4322
=head2 ARGUMENTS
4323
 
4324
The are no command specific arguments.
4325
 
4326
=head2 OPTIONS
4327
 
4328
The are no command specific options.
4329
 
4330
=head2 DESCRIPTION
4331
 
4332
The 'cache' command will cache all external dependent packages into the users
4333
dpkg_archive_cache as defined through the EnvVar GBE_DPKG_CACHE. The result is
4334
similar to the command 'jats sandbox build -cache', without the overhead of
4335
building the sandbox components.
4336
 
4337
This command allows the simple creation of a small development environment that
4338
is not tied to the larger Development Environment. It may then be used in a
337 dpurdie 4339
disconnected mode to perform development.
4340
 
7319 dpurdie 4341
=for comment ==================================================================
4342
 
7304 dpurdie 4343
=head1 Sandbox Test Links
4344
 
4345
=head2 NAME
4346
 
4347
Test and delete sandbox link files
4348
 
4349
=head2 SYNOPSIS
4350
 
4351
jats sandbox testlinks [options]
4352
 
4353
 Command Options
4354
    -help[=n]               - Command specific help, [n=1,2,3]
4355
    -man                    - Same as -help=3
4356
    -[no]delete             - Delete bad links
4357
 
4358
=head2 ARGUMENTS
4359
 
4360
This command does not take any arguments
4361
 
4362
=head2 OPTIONS
4363
 
4364
The 'fingerprint' command takes the following options:
4365
 
4366
=over 8
4367
 
4368
=item -[no]delete
4369
 
4370
This option will delete the link files if they are bad.
4371
 
4372
=back
4373
 
4374
=head2 DESCRIPTION
4375
 
4376
The 'testlinks' command, will by default, examine symbolic links within the sandbox and report on
4377
broken links.
4378
 
7306 dpurdie 4379
An option allows the broken links to be deleted.
7304 dpurdie 4380
 
4381
Each package in the sandbox will have a symbolic link to the packages 'package' area. If a package is removed
4382
from the sandbox the link file may be left in the sandbox and cause a 'build' to fail.
4383
 
4384
=head2 EXAMPLES
4385
 
4386
The command
4387
 
4388
    jats sandbox testlinks
4389
 
4390
will test the symbolic links in the sandbox metadata.
4391
 
7319 dpurdie 4392
=for comment ==================================================================
4393
 
7306 dpurdie 4394
=head1 Sandbox Scan Depth
4395
 
4396
=head2 NAME
4397
 
4398
Set and Display the build file scanner depth
4399
 
4400
=head2 SYNOPSIS
4401
 
4402
jats sandbox scandepth [options] [depth]
4403
 
4404
 Command Options
4405
    -help[=n]               - Command specific help, [n=1,2,3]
4406
    -man                    - Same as -help=3
4407
 
4408
=head2 ARGUMENTS
4409
 
4410
This command takes one optional argument. A positive number that control the 
4411
depth of the build filter scanner.
4412
 
4413
The default value is '3'. Deeper scans may be required for sandboxes containing badly formed 
4414
packages. The tradoff is speed for all sandbox operations.
4415
 
4416
Setting the scan depth will force a rescan of the sandbox build files on the next command that
4417
requires the information.
4418
 
4419
=head2 OPTIONS
4420
 
4421
The scandepth command only accepts the standard help and man options.
4422
 
4423
=head2 DESCRIPTION
4424
 
4425
The scandepth command, will by default, display the current value for the build file scanner.
4426
 
4427
If a numeric argument is provided this will set the future build file scan depth.
4428
 
4429
=head2 EXAMPLES
4430
 
4431
The command
4432
 
4433
    jats sandbox scandepth 5
4434
 
4435
will set future build file scan to a maximum of 5 directories below the root of the sandbox.
4436
 
7319 dpurdie 4437
=for comment ==================================================================
4438
 
4439
=head1 Write Build Data
4440
 
4441
=head2 NAME
4442
 
4443
Write out build system data
4444
 
4445
=head2 SYNOPSIS
4446
 
4447
jats sandbox writeBuildData [options]
4448
 
4449
 Command Options
4450
    -help[=n]               - Command specific help, [n=1,2,3]
4451
    -man                    - Same as -help=3
4452
    -outfile=path           - Specify the location of the output file
4453
 
4454
=head2 ARGUMENTS
4455
 
4456
This command does not take any arguments
4457
 
4458
=head2 OPTIONS
4459
 
4460
The 'writeBuildData' command takes the following options:
4461
 
4462
=over 8
4463
 
4464
=item -outfile=path
4465
 
4466
This option will control the location of the generated file. The path includes the name of the output file.
4467
 
4468
The directory in which the file is to be created must exist. The file itself will be deleted and 
4469
recreated. Ideally it should not be present at the beginning of the command.
4470
 
4471
=back
4472
 
4473
=head2 DESCRIPTION
4474
 
4475
The writeBuildData command is used by the automated build system to extract information from 
4476
the sandbox. Data is written to a JSON file.
4477
 
4478
=head2 EXAMPLES
4479
 
4480
The command
4481
 
4482
    jats sandbox writeBuildData -outpath=data.json
4483
 
4484
will write a json formatted file that contains data for the build system.
4485
 
7320 dpurdie 4486
=for comment ==================================================================
4487
 
4488
=head1 Generate Package Signatures
4489
 
4490
=head2 NAME
4491
 
4492
Generate Package Signatures
4493
 
4494
=head2 SYNOPSIS
4495
 
4496
jats sandbox genPkgSigs [options]
4497
 
4498
 Command Options
4499
    -help[=n]               - Command specific help, [n=1,2,3]
4500
    -man                    - Same as -help=3
4501
 
4502
=head2 ARGUMENTS
4503
 
4504
This command does not take any arguments
4505
 
4506
=head2 OPTIONS
4507
 
4508
The 'genPkgSigs' command does not have any command specific options.
4509
 
4510
=head2 DESCRIPTION
4511
 
4512
The genPkgSigs command is used by the automated build system to generate package signatures
4513
of all dependent packages.
4514
 
4515
=head2 EXAMPLES
4516
 
4517
The command
4518
 
4519
    jats -cd PackagePath sandbox genPkgSigs
4520
 
4521
=for comment ==================================================================
4522
 
4523
=head1 Set Abt Marker
4524
 
4525
=head2 NAME
4526
 
4527
Set Abt Marker file
4528
 
4529
=head2 SYNOPSIS
4530
 
4531
jats sandbox setAbtMarker [options]
4532
 
4533
 Command Options
4534
    -help[=n]               - Command specific help, [n=1,2,3]
4535
    -man                    - Same as -help=3
4536
 
4537
=head2 ARGUMENTS
4538
 
4539
This command does not take any arguments
4540
 
4541
=head2 OPTIONS
4542
 
4543
The 'setAbtMarker' command does not have any command specific options.
4544
 
4545
=head2 DESCRIPTION
4546
 
4547
The setAbtMarker command is used by the automated build system to place a marker file
4548
in the sandbox such that JATS will recognise the sandbox as being used by the 
4549
'Auto Build Tool'. This will affect the operation of several Jats commands.
4550
 
4551
=head2 EXAMPLES
4552
 
4553
The command
4554
 
4555
    jats -cd PackagePath sandbox setAbtMarker
4556
 
227 dpurdie 4557
=cut
4558