Subversion Repositories DevTools

Rev

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