Subversion Repositories DevTools

Rev

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

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