Subversion Repositories DevTools

Rev

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

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