Subversion Repositories DevTools

Rev

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

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