Subversion Repositories DevTools

Rev

Rev 7323 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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