Subversion Repositories DevTools

Rev

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