Subversion Repositories DevTools

Rev

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