Subversion Repositories DevTools

Rev

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

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