Subversion Repositories DevTools

Rev

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