Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
227 dpurdie 1
########################################################################
263 dpurdie 2
# Copyright (C) 2008 ERG Limited, 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;
44
 
45
 
46
use Pod::Usage;                             # required for help support
47
use Getopt::Long qw(:config require_order); # Stop on non-option
48
my $VERSION = "1.0.0";                      # Update this
49
 
50
#
51
#   Options
52
#
53
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
54
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
359 dpurdie 55
my $opt_help = 0;                           # Help level
56
my $opt_exact = 0;                          # Exact (escrow) build
1273 dpurdie 57
my $opt_toPackage;                          # Control recursion
58
my $opt_fromPackage;                        # Control recursion
59
my @opt_exactPackage;                       # Control recursion
60
my @opt_ignorePackage;                      # Control recursion
227 dpurdie 61
 
62
#
63
#   Globals - Provided by the JATS environment
64
#
65
my $USER         = $ENV{'USER'};
66
my $UNIX         = $ENV{'GBE_UNIX'};
67
my $HOME         = $ENV{'HOME'};
68
my $GBE_SANDBOX  = $ENV{'GBE_SANDBOX'};
69
my $GBE_DPKG_SBOX= $ENV{'GBE_DPKG_SBOX'};
325 dpurdie 70
my $GBE_MACHTYPE = $ENV{'GBE_MACHTYPE'};
227 dpurdie 71
 
335 dpurdie 72
my $GBE_DPKG_LOCAL = $ENV{'GBE_DPKG_LOCAL'};
73
my $GBE_DPKG_CACHE = $ENV{'GBE_DPKG_CACHE'};
74
my $GBE_DPKG       = $ENV{'GBE_DPKG'};
75
my $GBE_DPLY       = $ENV{'GBE_DPLY'};
76
my $GBE_DPKG_STORE = $ENV{'GBE_DPKG_STORE'};
77
 
227 dpurdie 78
#
79
#   Globals
80
#
1273 dpurdie 81
my @stopped = ();                         # Stopped entries
227 dpurdie 82
my @build_order = ();                     # Build Ordered list of entries
255 dpurdie 83
my %extern_deps;                          # Hash of external dependencies
227 dpurdie 84
my %packages;                             # Hash of packages
85
 
86
 
87
#-------------------------------------------------------------------------------
88
# Function        : Mainline Entry Point
89
#
90
# Description     :
91
#
92
# Inputs          :
93
#
94
my $result = GetOptions (
299 dpurdie 95
                "help|h:+"      => \$opt_help,
96
                "manual:3"      => \$opt_help,
337 dpurdie 97
                "verbose:+"     => \$opt_verbose,           # flag, multiple use allowed
227 dpurdie 98
                );
99
 
100
                #
101
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
102
                #
103
 
104
#
105
#   Process help and manual options
106
#
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
#
359 dpurdie 123
#   Determine Sandbox type. Exact or local
124
#
125
$opt_exact = (-f  $GBE_SANDBOX . '/sandbox_dpkg_archive/.exact' )
126
    if ( $GBE_SANDBOX );
127
 
128
#
227 dpurdie 129
#   Parse the user command and decide what to do
130
#
359 dpurdie 131
#   Remove user command from the command line. This will leave command options
132
#   in @ARGV so that they can be parsed by the subcommand.
227 dpurdie 133
#
134
my $cmd = shift @ARGV || "";
135
help(1)                                 if ( $cmd =~ m/^help$/ || $cmd eq "" );
359 dpurdie 136
buildcmd($cmd, @ARGV )                  if ( $cmd =~ m/(^all$)|(^build$)/  );
137
cache(@ARGV)                            if ( $cmd =~ m/^cache$/  );
138
clean($cmd, @ARGV)                      if ( $cmd =~ m/(^clobber$)|(^clean$)/  );
139
cmd('make', $cmd, @ARGV )               if ( $cmd =~ m/(^make$)/  );
140
cmd('cmd', @ARGV)                       if ( $cmd =~ m/^cmd$/ );
141
create_sandbox()                        if ( $cmd =~ m/^create$/ );
299 dpurdie 142
delete_sandbox()                        if ( $cmd =~ m/^delete$/ );
227 dpurdie 143
info(@ARGV)                             if ( $cmd =~ m/^info$/ );
359 dpurdie 144
populate(@ARGV)                         if ( $cmd =~ m/^populate$/  );
227 dpurdie 145
 
146
Error ("Unknown sandbox command: $cmd");
147
exit 1;
148
 
149
 
150
#-------------------------------------------------------------------------------
151
#
152
#   Give the user a clue
153
#
154
sub help
155
{
156
    my ($level) = @_;
157
    $level = $opt_help unless ( $level );
158
 
159
    pod2usage(-verbose => 0, -message => "Version: ". $VERSION)  if ($level == 1 );
160
    pod2usage(-verbose => $level -1 );
161
}
162
 
163
#-------------------------------------------------------------------------------
164
# Function        : create_sandbox
165
#
166
# Description     : create a sandbox in the current current directory
167
#
168
# Inputs          : None
169
#
170
#
171
sub create_sandbox
172
{
359 dpurdie 173
    GetOptions (
174
                "help:+"        => \$opt_help,
175
                "manual:3"      => \$opt_help,
176
                "exact"         => \$opt_exact,
177
                ) || Error ("Invalid command line" );
178
 
179
    SubCommandHelp( $opt_help, "Create Sandbox") if ($opt_help || $#ARGV >= 0 );
180
 
227 dpurdie 181
    Error ("Cannot create a sandbox within a sandbox",
182
           "Sandbox base is: $GBE_SANDBOX" ) if ( $GBE_SANDBOX );
359 dpurdie 183
 
227 dpurdie 184
    mkdir ('sandbox_dpkg_archive') || Error ("Cannot create the directory: sandbox_dpkg_archive") ;
359 dpurdie 185
 
186
    TouchFile( 'sandbox_dpkg_archive/.exact', 'Sandbox marker file')
187
        if ($opt_exact);
188
 
189
    Message ('Sandbox created' . ($opt_exact ? ' - With exact version number processing' : ''));
227 dpurdie 190
    exit  0;
191
}
192
 
193
#-------------------------------------------------------------------------------
299 dpurdie 194
# Function        : delete_sandbox
195
#
196
# Description     : Delete a sandbox
197
#                   Its up to the user the delete the components in the sandbox
198
#
199
# Inputs          : None
200
#
361 dpurdie 201
# Returns         :
299 dpurdie 202
#
203
sub delete_sandbox
204
{
359 dpurdie 205
    GetOptions (
206
                "help:+"        => \$opt_help,
207
                "manual:3"      => \$opt_help,
208
                ) || Error ("Invalid command line" );
209
 
210
    SubCommandHelp( $opt_help, "Delete Sandbox") if ($opt_help || $#ARGV >= 0 );
211
 
299 dpurdie 212
    unless ( $GBE_SANDBOX )
213
    {
214
        Warning("No sandbox found to delete");
215
    }
216
    else
217
    {
365 dpurdie 218
        Error ("Sandbox directory not completely removed")
361 dpurdie 219
            if RmDirTree( "$GBE_SANDBOX/sandbox_dpkg_archive" );
299 dpurdie 220
 
221
        Message("Sandbox information deleted",
222
                "Sandbox components must be manually deleted");
223
    }
224
    exit 0;
225
}
226
 
227
#-------------------------------------------------------------------------------
227 dpurdie 228
# Function        : info
229
#
230
# Description     : Display Sandbox information
231
#
232
# Inputs          : Command line args
233
#                   -v  - Be more verbose
234
#
235
# Returns         : Will exit
236
#
237
sub info
238
{
359 dpurdie 239
    GetOptions (
240
                "help:+"        => \$opt_help,
241
                "manual:3"      => \$opt_help,
242
                "verbose:+"     => \$opt_verbose,
1273 dpurdie 243
                'topackage:s'   => \$opt_toPackage,
244
                'frompackage:s' => \$opt_fromPackage,
245
                'justpackage:s' => \@opt_exactPackage,
246
                'ignorepackage:s' => \@opt_ignorePackage,
359 dpurdie 247
                ) || Error ("Invalid command line" );
227 dpurdie 248
 
359 dpurdie 249
    SubCommandHelp( $opt_help, "Sandbox Information") if ($opt_help || $#ARGV >=0 );
361 dpurdie 250
 
227 dpurdie 251
    #
252
    #   Determine Sandbox information
253
    #   Populate global variables
254
    #
1273 dpurdie 255
    calc_sandbox_info(1);
227 dpurdie 256
 
257
    #
258
    #   Display information
259
    #
359 dpurdie 260
    Message ("Type   : " . ($opt_exact ? 'Exact' : 'Development') );
261
    Message ("Base   : $GBE_SANDBOX");
227 dpurdie 262
    Message ("Archive: $GBE_DPKG_SBOX");
263
 
1273 dpurdie 264
 
227 dpurdie 265
    Message ("Build Order");
1273 dpurdie 266
    foreach my $pname ( @stopped )
267
    {
268
        Message( "    Level:" . "-"  . " Name: " . $pname . ' (Stopped)');
269
    }
227 dpurdie 270
    foreach my $fe ( @build_order )
271
    {
1273 dpurdie 272
        Message( "    Level:" . $fe->{level} . " Name: " . $fe->{dname} . ($fe->{buildActive} ? '' : ' (Build Suppressed)'));
227 dpurdie 273
        Message( DisplayPath ("        Path: $fe->{dir}" )) if $opt_verbose;
274
 
275
        if ( $opt_verbose )
276
        {
359 dpurdie 277
            foreach my $idep ( sort values %{$fe->{'ideps'}} )
227 dpurdie 278
            {
359 dpurdie 279
                Message ("        I:$idep");
227 dpurdie 280
            }
281
 
359 dpurdie 282
            foreach my $edep ( sort keys %{$fe->{'edeps'}} )
227 dpurdie 283
            {
359 dpurdie 284
                my ($ppn,$ppv) = split( $; , $edep);
285
                Message ("        E:$ppn $ppv");
227 dpurdie 286
            }
361 dpurdie 287
 
227 dpurdie 288
        }
289
    }
290
 
359 dpurdie 291
    #
292
    #   External dependencies flags
293
    #       * - Package does not exist in dpkg_archive
294
    #       + - Multiple versions of this package are used
295
 
255 dpurdie 296
    Message("External Dependencies");
227 dpurdie 297
    foreach my $de ( sort keys %extern_deps )
298
    {
299
        my @vlist = keys %{$extern_deps{$de}};
335 dpurdie 300
        my $flag = $#vlist ? '+' : '';
359 dpurdie 301
        foreach my $pve ( @vlist )
227 dpurdie 302
        {
359 dpurdie 303
            my ($pn,$pv) = split( $; , $pve );
304
            my $exists = check_package_existance($pn,$pv  ) ? '' : '*';
335 dpurdie 305
            my $flags = sprintf ("%4.4s", $flag . $exists);
359 dpurdie 306
            Message ("${flags}${pn} ${pv}");
227 dpurdie 307
            if ( $opt_verbose )
308
            {
359 dpurdie 309
                foreach my $pkg ( @{$extern_deps{$de}{$pve}} )
227 dpurdie 310
                {
359 dpurdie 311
                    my $ppn = join ('.', split( $; , $pkg));
312
                    Message ("        U:$ppn");
227 dpurdie 313
                }
314
            }
359 dpurdie 315
 
227 dpurdie 316
        }
317
    }
318
 
319
    if ( $opt_verbose > 2 )
320
    {
321
        DebugDumpData( "extern_deps", \%extern_deps);
322
        DebugDumpData( "build_order", \@build_order);
323
        DebugDumpData( "packages", \%packages);
324
    }
325
    exit (0);
326
}
327
 
328
#-------------------------------------------------------------------------------
335 dpurdie 329
# Function        : check_package_existance
330
#
331
# Description     : Determine if a given package-version exists
332
#
333
# Inputs          : $name           - Package Name
334
#                   $ver            - Package Version
335
#
336
# Returns         : true            - Package exists
337
#
338
sub check_package_existance
339
{
340
    my ($name, $ver) = @_;
341
    #
342
    #   Look in each package archive directory
343
    #
344
    foreach my $dpkg ( $GBE_DPKG_SBOX,
345
                       $GBE_DPKG_LOCAL,
346
                       $GBE_DPKG_CACHE,
347
                       $GBE_DPKG,
348
                       $GBE_DPLY,
349
                       $GBE_DPKG_STORE )
350
    {
351
        next unless ( $dpkg );
352
        if ( -d "$dpkg/$name/$ver" )
353
        {
354
            return 1;
355
        }
356
    }
357
   return 0;
358
}
359
 
360
 
361
#-------------------------------------------------------------------------------
227 dpurdie 362
# Function        : calc_sandbox_info
363
#
364
# Description     : Examine the sandbox and determine all the important
365
#                   information
366
#
1273 dpurdie 367
#                   Operation will be modified by
368
#                       $opt_toPackage
369
#                       $opt_fromPackage
370
#                       @opt_exactPackage
371
#                       @opt_ignorePackage
227 dpurdie 372
#
1273 dpurdie 373
# Inputs          : info                - True: Just for info
374
#                                               Keep supressed packages
375
#
227 dpurdie 376
# Returns         : Will exit if not in a sandbox
377
#                   Populates global variables
378
#                       @build_order - build ordered array of build entries
379
#
380
sub calc_sandbox_info
381
{
1273 dpurdie 382
    my ($info) = @_;
383
 
227 dpurdie 384
    #
385
    #   Start from the root of the sandbox
386
    #
387
    Error ("Command must be executed from within a Sandbox") unless ( $GBE_SANDBOX );
388
    chdir ($GBE_SANDBOX) || Error ("Cannot chdir to $GBE_SANDBOX");
389
 
390
    #
391
    #   Locate all packages within the sandbox
392
    #   These will be top-level directories - one per package
393
    #
394
    my @dirlist;
395
    my @build_list;
255 dpurdie 396
    foreach my $pname ( glob("*") )
227 dpurdie 397
    {
255 dpurdie 398
        next if ( $pname =~ m~^\.~ );
399
        next if ( $pname =~ m~dpkg_archive$~ );
297 dpurdie 400
        next if ( $pname =~ m~^CVS$~ );
255 dpurdie 401
        next unless ( -d $pname );
402
        Verbose ("Package discovered: $pname");
275 dpurdie 403
 
325 dpurdie 404
        if ( -f "$pname/stop" || -f "$pname/stop.$GBE_MACHTYPE" )
275 dpurdie 405
        {
1273 dpurdie 406
            push @stopped, $pname;
275 dpurdie 407
            Warning("Package contains stop file: $pname");
408
            next;
409
        }
410
 
255 dpurdie 411
        push @dirlist, $pname;
227 dpurdie 412
 
413
        #
414
        #   Locate the build files in each package
245 dpurdie 415
        #   Scan the build files and extract dependancy information
227 dpurdie 416
        #
359 dpurdie 417
        my $bscanner = BuildFileScanner( $pname, 'build.pl',
418
                                                 '--LocateAll',
419
                                                 $opt_exact ? '--ScanExactDependencies' : '--ScanDependencies' );
245 dpurdie 420
        $bscanner->scan();
421
        my @blist = $bscanner->getInfo();
255 dpurdie 422
        Warning ("Package does not have build files: $pname") unless ( @blist );
423
        Warning ("Package has multiple build files: $pname") if ( $#blist > 0 );
245 dpurdie 424
        push @build_list, @blist;
227 dpurdie 425
    }
426
 
427
    #
428
    #   Process each build file and extract
429
    #       Name of the Package
430
    #       Dependency list
431
    #   Build up a hash of dependence information
432
    #
433
 
434
    my %depends;
299 dpurdie 435
    my %multi;
245 dpurdie 436
    foreach my $be ( @build_list )
227 dpurdie 437
    {
245 dpurdie 438
        Verbose( DisplayPath ("Build file: " . $be->{dir} . " Name: " . $be->{file} ));
359 dpurdie 439
        #
440
        #   Sandbox vs Exact processing
441
        #       Set a suitable display name
442
        #       Set a suitable tag
443
        #
444
        $be->{dname} = $opt_exact ? $be->{full}    : $be->{mname};
445
        $be->{tag}   = $opt_exact ? $be->{fullTag} : $be->{package};
446
 
245 dpurdie 447
#        DebugDumpData ("be", $be );
227 dpurdie 448
 
449
        #
299 dpurdie 450
        #   Catch multiple builds for the same package
451
        #   Report later - when we have all
452
        #
359 dpurdie 453
        next unless ( $be->{dname} );
454
        push @{$multi{$be->{dname}}},$be->{dir};
299 dpurdie 455
 
456
        #
227 dpurdie 457
        #   Add into dependency struct
458
        #
1273 dpurdie 459
        $depends{$be->{tag}} = $be;
227 dpurdie 460
    }
461
 
359 dpurdie 462
    foreach my $dname ( sort keys %multi )
299 dpurdie 463
    {
365 dpurdie 464
        ReportError ("Multiple builders for : $dname", @{$multi{$dname}} )
359 dpurdie 465
            if ( scalar @{$multi{$dname}} > 1 );
299 dpurdie 466
    }
467
    ErrorDoExit();
468
 
245 dpurdie 469
#DebugDumpData ("depends", \%depends );
470
 
227 dpurdie 471
    #
472
    #   Determine the build order
473
    #
474
    @build_order = ();
475
    my $more = 1;
476
    my $level = 0;
477
 
478
    #
255 dpurdie 479
    #   Remove any dependencies to 'external' packages
227 dpurdie 480
    #   These will not be met internally and can be regarded as constant
481
    #
1273 dpurdie 482
    #   Split 'depends' into internal (ideps) and external (edeps)
483
    #       edeps : External Dependencies
484
    #               Key:        Name;Version
485
    #               Value:      'tag' - index into packages
486
    #       ideps : Internal Dependencies
487
    #               Key:        'tag'   - Index into packages
488
    #               Value:      'dname' - Display Name
489
    #
227 dpurdie 490
    foreach my $key ( keys %depends )
491
    {
492
        foreach my $build ( keys( %{$depends{$key}{depends}} ))
493
        {
494
            unless (exists $depends{$build})
495
            {
1273 dpurdie 496
                $depends{$key}{'edeps'}{$depends{$key}{depends}{$build}} = $build;
227 dpurdie 497
                delete ($depends{$key}{depends}{$build}) ;
498
                Verbose2( "Not in set: $build");
499
            }
500
            else
501
            {
1273 dpurdie 502
                $depends{$key}{'ideps'}{$build} = $depends{$build}{dname};
227 dpurdie 503
            }
504
        }
505
    }
359 dpurdie 506
 
507
#DebugDumpData ("depends", \%depends );
508
 
361 dpurdie 509
 
359 dpurdie 510
    #
511
    #   Determine package build order
512
    #       Scan the list of packages in the build set and determine
513
    #       those with no dependencies. These can be built.
514
    #       Remove those packages as dependents from all packages
515
    #       Repeat.
516
    #
1273 dpurdie 517
    my $scan_active = $opt_fromPackage ? 0 : 1;
518
    my $scan_start = 0;
519
    my $scan_stop = 0;
520
    my %notFound;
521
    my %found;
522
 
523
    #   Elements in @opt_exactPackage may be comma seperated names
524
    #   Split them out
525
    if ( @opt_exactPackage )
526
    {
527
        foreach ( @opt_exactPackage )
528
        {
529
            $notFound{$_} = 1 foreach ( split(/\s*,\s*/,$_) );
530
        }
531
        @opt_exactPackage = keys %notFound;
532
    }
533
 
534
    if ( @opt_ignorePackage )
535
    {
536
        foreach ( @opt_ignorePackage )
537
        {
538
            $found{$_} = 1 foreach ( split(/\s*,\s*/,$_) );
539
        }
540
        @opt_ignorePackage = keys %found;
541
    }
542
 
543
 
227 dpurdie 544
    while ( $more )
545
    {
546
        $more = 0;
547
        $level++;
548
        my @build;
549
 
550
        #
551
        #   Locate packages with no dependencies
552
        #
553
        foreach my $key ( keys %depends )
554
        {
555
            next if ( keys( %{$depends{$key}{depends}} ) );
556
            push @build, $key;
557
        }
558
 
559
        foreach my $build ( @build )
560
        {
561
            $more = 1;
1273 dpurdie 562
            my $fe = $depends{$build};
563
            my $scan_add = $scan_active ? 1 : 0;
564
 
565
 
566
            if ( @opt_exactPackage )
567
            {
568
                $scan_add = 0;
569
                foreach my $pname ( @opt_exactPackage )
570
                {
571
                    if ( (($fe->{mname} eq $pname) || ($fe->{name} eq $pname)))
572
                    {
573
                        $scan_add = 1;
574
                        delete $notFound{$pname};
575
                    }
576
                }
577
            }
578
 
579
            if ( @opt_ignorePackage )
580
            {
581
                foreach my $pname ( @opt_ignorePackage )
582
                {
583
                    if ( (($fe->{mname} eq $pname) || ($fe->{name} eq $pname)))
584
                    {
585
                        $scan_add = 0;
586
                        delete $found{$pname};
587
                    }
588
                }
589
            }
590
 
591
 
592
            if ( $opt_toPackage && (($fe->{mname} eq $opt_toPackage) || ($fe->{name} eq $opt_toPackage)))
593
            {
594
                $scan_add = 0;
595
                $scan_active = 0;
596
                $scan_stop = 1;
597
            }
598
 
599
            if ( $opt_fromPackage && (($fe->{mname} eq $opt_fromPackage) || ($fe->{name} eq $opt_fromPackage)))
600
            {
601
                $scan_add = 1;
602
                $scan_active = 1;
603
                $scan_start = 1;
604
            }
605
 
227 dpurdie 606
            $fe->{level} = $level;
1273 dpurdie 607
            $fe->{buildActive} = $scan_add;
227 dpurdie 608
            $packages{$build} = $fe;
1273 dpurdie 609
            push (@build_order, $fe) if ( $scan_add || $info );
227 dpurdie 610
            delete $depends{$build};
611
            delete $fe->{depends};                          # remove now its not needed
612
        }
613
 
614
        foreach my $key ( keys %depends )
615
        {
616
            foreach my $build ( @build )
617
            {
618
                delete $depends{$key}{depends}{$build};
619
            }
620
        }
621
    }
622
 
623
    #
1273 dpurdie 624
    #   Detect bad user specifications
625
    #
626
    ReportError ("Specified FromPackage not found: $opt_fromPackage") if ( $opt_fromPackage && !$scan_start );
627
    ReportError ("Specified ToPackage not found: $opt_toPackage") if ( $opt_toPackage && !$scan_stop );
628
    ReportError ("Specified ExactPackages not found: ", keys( %notFound) ) if ( %notFound );
629
    ReportError ("Specified IgnorePackages not found: ", keys( %found) ) if ( %found );
630
    ErrorDoExit();
631
 
632
    #
633
    #   Calculate the external dependencies
634
    #       Only process packages that are a part of the build
635
    #
636
    #   extern_deps structure
637
    #       Hash key: 'tag'   - Index into packages
638
    #          Value: Hash of:
639
    #                 Key  : Name;Version
640
    #                 Value: Array of: 'tags' (Index into packages)
641
    #                                   of packages that use the external
642
    #                                   component.
643
    {
644
        Verbose ("Calculate external dependencies");
645
        %extern_deps = ();
646
 
647
        foreach my $key ( keys %packages )
648
        {
649
                next unless ( $packages{$key}{buildActive} );
650
                next unless ( $packages{$key}{'edeps'} );
651
                foreach ( keys %{$packages{$key}{'edeps'}} )
652
                {
653
                    push @{$extern_deps{$packages{$key}{'edeps'}{$_}} {$_} }, $key;
654
                }
655
        }
656
    }
657
 
658
    #
227 dpurdie 659
    #   Just to be sure to be sure
660
    #
245 dpurdie 661
    if ( keys %depends )
662
    {
663
        #DebugDumpData ("depends", \%depends );
664
        Error( "Internal algorithm error: Bad dependancy walk",
665
               "Possible circular dependency");
666
    }
227 dpurdie 667
 
1273 dpurdie 668
#   DebugDumpData("Packages", \%packages);
359 dpurdie 669
#   DebugDumpData ("Order", \@build_order);
670
#   DebugDumpData("External Depends", \%extern_deps );
227 dpurdie 671
}
672
 
673
#-------------------------------------------------------------------------------
674
# Function        : cmd
675
#
676
# Description     : Execute a command in all the sandboxes
677
#                       Locate the base of the sandbox
678
#                       Locate all packages in the sandbox
679
#                       Locate all build files in each sandbox
680
#                       Determine build order
681
#                       Issue commands for each sandbox in order
682
#
255 dpurdie 683
# Inputs          : Arguments passed to jats build
227 dpurdie 684
#
685
# Returns         : Will exit
686
#
687
sub cmd
688
{
359 dpurdie 689
    my ($hcmd, @cmds ) = @_;
690
 
691
    Getopt::Long::Configure('pass_through');
1273 dpurdie 692
    getOptionsFromArray ( \@cmds,
359 dpurdie 693
                "help:+"        => \$opt_help,
694
                "manual:3"      => \$opt_help,
1273 dpurdie 695
                'topackage:s'   => \$opt_toPackage,
696
                'frompackage:s' => \$opt_fromPackage,
697
                'justpackage:s' => \@opt_exactPackage,
698
                'ignorepackage:s' => \@opt_ignorePackage,
359 dpurdie 699
                ) || Error ("Invalid command line" );
700
 
701
    SubCommandHelp( $opt_help, $hcmd) if ($opt_help  );
702
 
227 dpurdie 703
    #
704
    #   Determine Sandbox information
705
    #   Populate global variables
706
    #
707
    calc_sandbox_info();
708
    foreach my $fe ( @build_order )
709
    {
710
        my $dir = $fe->{dir};
359 dpurdie 711
        Message( "Level:" . $fe->{level} . " Name: " . $fe->{dname} ,
227 dpurdie 712
                  DisplayPath ("        Path: $fe->{dir}" ));
713
 
263 dpurdie 714
        my $result = JatsCmd( "-cd=$dir", @cmds);
255 dpurdie 715
        Error ("Cmd failure") if ( $result );
227 dpurdie 716
    }
717
 
718
    exit 0;
719
}
720
 
721
#-------------------------------------------------------------------------------
331 dpurdie 722
# Function        : buildcmd
723
#
724
# Description     : Build the entire sandbox
725
#                   The all and the build are similar.
726
#                   Its not really useful to do a build without a make
727
#                   so we don't try
728
#
729
# Inputs          : Arguments passed to jats make
730
#
731
#
732
# Returns         : Will exit
733
#
734
 
735
sub buildcmd
736
{
337 dpurdie 737
    my ($cmd, @cmd_opts) = @_;
331 dpurdie 738
    my @build_opts;
337 dpurdie 739
    my @make_opts;
331 dpurdie 740
 
741
    #
359 dpurdie 742
    #   Extract and options
743
    #
744
    Getopt::Long::Configure('pass_through');
1273 dpurdie 745
    getOptionsFromArray ( \@cmd_opts,
359 dpurdie 746
                "help:+"        => \$opt_help,
747
                "manual:3"      => \$opt_help,
1273 dpurdie 748
                'topackage:s'   => \$opt_toPackage,
749
                'frompackage:s' => \$opt_fromPackage,
750
                'justpackage:s' => \@opt_exactPackage,
751
                'ignorepackage:s' => \@opt_ignorePackage,
359 dpurdie 752
                ) || Error ("Invalid command line" );
753
 
754
    SubCommandHelp( $opt_help, "Command $cmd") if ($opt_help );
361 dpurdie 755
 
359 dpurdie 756
    #
331 dpurdie 757
    #   Insert default options
758
    #
759
    push @build_opts, '-noforce' if ( $cmd eq 'all' );
760
    push @build_opts, '-force' if ( $cmd ne 'all' );
761
 
337 dpurdie 762
    #
763
    #   Attempt to split the options into build and make options
764
    #   Only handle the often used options to build.
765
    #
766
    foreach  ( @cmd_opts )
767
    {
768
        if ( m/^-cache/ || m/^-package/ || m/^-forcebuildpkg/ || m/-expert/) {
769
            push @build_opts, $_;
770
        } else {
771
            push @make_opts, $_;
772
        }
773
    }
774
 
331 dpurdie 775
    push @make_opts, 'all'  unless ( @make_opts  );
776
 
777
    #
778
    #   Determine Sandbox information
779
    #   Populate global variables
780
    #
781
    calc_sandbox_info();
782
    foreach my $fe ( @build_order )
783
    {
784
        my $dir = $fe->{dir};
359 dpurdie 785
        Message( "Level:" . $fe->{level} . " Name: " . $fe->{dname} ,
331 dpurdie 786
                  DisplayPath ("        Path: $fe->{dir}" ));
787
 
788
        JatsCmd( "-cd=$dir", 'build', @build_opts) && Error ("Build Cmd failure") if ( $result );
789
        JatsCmd( "-cd=$dir", 'make',  @make_opts)  && Error ("Make Cmd failure")  if ( $result );
790
    }
791
 
792
    exit 0;
793
}
794
 
795
 
796
#-------------------------------------------------------------------------------
273 dpurdie 797
# Function        : clean
798
#
799
# Description     : Execute a command in all the sandboxes
800
#                       Locate the base of the sandbox
801
#                       Locate all packages in the sandbox
802
#                       Locate all build files in each sandbox
803
#                       Determine build order
804
#                       Issue commands for each sandbox in order
805
#
806
# Inputs          : Arguments passed to jats build
807
#
808
# Returns         : Will exit
809
#
810
sub clean
811
{
812
    my ($mode, @cmds ) = @_;
359 dpurdie 813
 
273 dpurdie 814
    #
359 dpurdie 815
    #   Extract and options
816
    #
817
    Getopt::Long::Configure('pass_through');
1273 dpurdie 818
    getOptionsFromArray ( \@cmds,
359 dpurdie 819
                "help:+"        => \$opt_help,
820
                "manual:3"      => \$opt_help,
1273 dpurdie 821
                'topackage:s'   => \$opt_toPackage,
822
                'frompackage:s' => \$opt_fromPackage,
823
                'justpackage:s' => \@opt_exactPackage,
824
                'ignorepackage:s' => \@opt_ignorePackage,
359 dpurdie 825
                ) || Error ("Invalid command line" );
826
 
827
    SubCommandHelp( $opt_help, "Clean") if ($opt_help );
828
 
829
    #
273 dpurdie 830
    #   Determine Sandbox information
831
    #   Populate global variables
832
    #
833
    calc_sandbox_info();
834
 
835
    my @cmd = $mode eq 'clobber' ? ('clobber') : ('make', 'clean' );
836
 
837
    #
838
    #   Clobber and clean need to be done in the reverse order
839
    #
840
    foreach my $fe ( reverse @build_order )
841
    {
842
        my $dir = $fe->{dir};
359 dpurdie 843
        Message( "Level:" . $fe->{level} . " Name: " . $fe->{dname} ,
273 dpurdie 844
                  DisplayPath ("        Path: $fe->{dir}" ));
845
 
846
        my $result = JatsCmd( "-cd=$dir", @cmd, @cmds);
847
        Error ("Cmd failure") if ( $result );
848
    }
849
 
850
    exit 0;
851
}
852
 
853
 
854
#-------------------------------------------------------------------------------
337 dpurdie 855
# Function        : cache
856
#
857
# Description     : Cache external packages into the sandbox
858
#
859
# Inputs          : @opts                   - User options
860
#
861
# Returns         : Nothing
862
#
863
sub cache
864
{
865
    my (@opts) = @_;
866
 
1273 dpurdie 867
    getOptionsFromArray ( \@opts,
359 dpurdie 868
                "help:+"        => \$opt_help,
869
                "manual:3"      => \$opt_help,
1273 dpurdie 870
                'topackage:s'   => \$opt_toPackage,
871
                'frompackage:s' => \$opt_fromPackage,
872
                'justpackage:s' => \@opt_exactPackage,
873
                'ignorepackage:s' => \@opt_ignorePackage,
359 dpurdie 874
                ) || Error ("Invalid command line" );
875
 
876
    SubCommandHelp( $opt_help, "Cache") if ($opt_help || $#ARGV >= 0 );
877
 
337 dpurdie 878
    #
879
    #   Determine Sandbox information
880
    #   Populate global variables
881
    #
882
    Message("Cache External Dependencies");
883
    calc_sandbox_info();
884
 
885
    #
1273 dpurdie 886
    #   Walk the list of external dependencies and cache each one
337 dpurdie 887
    #
888
    foreach my $de ( sort keys %extern_deps )
889
    {
890
        my @vlist = keys %{$extern_deps{$de}};
359 dpurdie 891
        foreach my $pve ( @vlist )
337 dpurdie 892
        {
359 dpurdie 893
            my ($pn,$pv) = split( $; , $pve );
894
            Message ("Cache ${pn} ${pv}");
895
            JatsTool ('cache_dpkg', "${pn}/${pv}" );
337 dpurdie 896
        }
897
    }
361 dpurdie 898
 
337 dpurdie 899
    exit 0;
361 dpurdie 900
 
337 dpurdie 901
}
902
 
359 dpurdie 903
#-------------------------------------------------------------------------------
904
# Function        : populate
905
#
906
# Description     : Populate the sandbox with package versions
907
#
908
#
909
# Inputs          : commands            - Array of command line arguments
910
#                   Mode-0:
911
#
912
#                       pkg_name pkg_version        - Import files for named package
913
#                       options:
914
#                           -recurse                - Import dependent packages too
915
#                           -missing                - Import dependencies not in dpkg_archive
916
#                           -test                   - Show what would be done
917
#                           -extractfiles           - Extract file, no view
918
#
919
#
920
#
921
#
922
# Returns         : Does not return
923
#
924
use JatsRmApi;
925
use DBI;
337 dpurdie 926
 
359 dpurdie 927
#
928
#   Data Base Interface
929
#
930
my $RM_DB;
931
my $PopLevel = 0;
932
my %PopPackage;
933
my @StrayPackages;
934
my @PopBase;
935
 
936
sub populate
937
{
938
    my $opt_missing = 0;
939
    my $opt_recurse = 0;
940
    my $opt_test = 0;
941
    my $opt_extractfiles;
942
    my @opt_extract = qw(-extract);
943
    my @opt_fnames;
944
 
945
    Getopt::Long::Configure('pass_through');
946
    GetOptions (
947
                "help:+"        => \$opt_help,
948
                "manual:3"      => \$opt_help,
949
                "missing"       => \$opt_missing,
950
                "test"          => \$opt_test,
951
                "recurse:100"   => \$opt_recurse,
952
                ) || Error ("Invalid command line" );
953
 
954
    SubCommandHelp( $opt_help, "Populate Sandbox") if ($opt_help );
955
 
956
    #
957
    #   Extract options for the jats extract utility
958
    #
959
    foreach ( @ARGV )
960
    {
961
        if ( m~^-~ ) {
962
            push ( @opt_extract, $_);
963
        } else {
964
            push ( @opt_fnames, $_);
965
        }
966
    }
967
 
968
    #
969
    #   Allow exactly zero or two 'bare' arguments
970
    #   Create an array of package-versions to be processed.
971
    #
972
    if ( $#opt_fnames >= 0 )
973
    {
365 dpurdie 974
        Error ("Populate: Must specify both a package name and version")
359 dpurdie 975
            if ( $#opt_fnames != 1 );
976
        push @PopBase, join( $;, @opt_fnames );
977
    }
978
    elsif ( $opt_missing )
979
    {
980
        #
981
        #   User has not provided a package name to extract
982
        #   Assume that the user will want missing dependencies
983
        #
984
        #   Determine packages that are not present
985
        #
986
        calc_sandbox_info();
987
 
988
        #
989
        # Scan for missing dependencies
990
        #
991
        foreach my $de ( sort keys %extern_deps )
992
        {
993
            my @vlist = keys %{$extern_deps{$de}};
994
            foreach my $pve ( @vlist )
995
            {
996
                my ($pn,$pv) = split( $; , $pve );
997
                unless (check_package_existance( $pn, $pv ))
998
                {
999
                    push @PopBase, join( $;, $pn , $pv );
1000
                }
1001
            }
1002
        }
1003
    }
1004
    else
1005
    {
1006
        Error ("No command or option specified. See help for command usage");
1007
    }
1008
 
1009
    #
1010
    #   Process the list of package-versions
1011
    #   These are top level packages. Get details from Release Manager
1012
    #
1013
    #DebugDumpData("Data", \@PopBase );
1014
    $PopLevel = 0;
1015
    foreach my $entry ( @PopBase )
1016
    {
1017
        my ($pname, $pver ) = split( $; , $entry);
1018
 
1019
        my $pv_id = getPkgDetailsByName($pname, $pver);
1020
        Error ("populate: $pname, $pver not found in Release Manager" )
1021
            unless ( $pv_id );
1022
        getPkgDetailsByPV_ID($pv_id);
1023
    }
1024
    #
1025
    #   If recursing then process packages that have yet to
1026
    #   be processed. At the start there will be the initial user specified
1027
    #   packages on the list. Place a marker at the end so that we can
1028
    #   determine how far we are recursing down the dependency tree.
1029
    #
1030
    if ( $opt_recurse )
1031
    {
1032
        my $marker = join($; , '_NEXT_LEVEL_', 0, 0 );
1033
        push @StrayPackages, $marker;
1034
        $PopLevel++;
1035
 
1036
        while ( $#StrayPackages >= 0 )
1037
        {
1038
            my ($name, $ver, $pv_id) = split($;, shift @StrayPackages);
1039
 
1040
            #
1041
            #   Marker.
1042
            #   Increment the level of recursion
1043
            #   Detect end conditions
1044
            #
1045
            if ( $name eq '_NEXT_LEVEL_' )
1046
            {
1047
                last unless ($#StrayPackages >= 0 );
1048
                $PopLevel++;
1049
                last if ( $PopLevel > $opt_recurse );
1050
                push @StrayPackages, $marker;
1051
                next;
1052
            }
1053
 
1054
            next if ( exists $PopPackage{$name}{$ver}{done} );
1055
            getPkgDetailsByPV_ID ( $pv_id );
1056
            #print "Stray: $pv_id, $name, $ver\n";
1057
        }
1058
    }
1059
    #DebugDumpData("Data", \%PopPackage );
1060
 
1061
    #
1062
    #   Determine packages that need to be extracted
1063
    #   Not ordered in any way. Could order by level if we wanted
1064
    #
1065
    foreach my $pname ( sort keys %PopPackage )
1066
    {
1067
        foreach my $pver ( sort keys %{$PopPackage{$pname}} )
1068
        {
1069
            #
1070
            #   Create a nice view name for the extraction
365 dpurdie 1071
            #   Will also be used to test for package existence
359 dpurdie 1072
            #
1073
            my $vname = "$pname $pver";
1074
            $vname =~ s~ ~_~g;
1075
            $vname =~ s~__~~g;
1076
 
1077
            if ( -d "$GBE_SANDBOX/$vname" )
1078
            {
1079
                Warning("Package already in sandbox: $pname, $pver");
1080
                next;
1081
            }
1082
 
1083
            #
1084
            #   If scanning for missing packages, then examine archives
1085
            #   for the packages existence. Don't do this on level-0 packages
1086
            #   These have been user specified.
1087
            #
1088
            if ( $opt_missing && $PopPackage{$pname}{$pver}{level}  )
1089
            {
1090
                my $found = check_package_existance( $pname, $pver );
1091
                if ( $found )
1092
                {
1093
                    Verbose ("Package found in archive - skipped: $pname, $pver");
1094
                    next;
1095
                }
1096
            }
1097
 
1098
            #
1099
            #   Generate commands to extract the package
1100
            #
1101
            my $vcstag = $PopPackage{$pname}{$pver}{vcstag};
1102
            my @cmd = qw(jats_vcsrelease);
1103
            push @cmd, "-view=$vname", "-label=$vcstag", @opt_extract;
1104
            if ( $opt_test )
1105
            {
1106
                Message "jats " . QuoteCommand (@cmd );
1107
            }
1108
            else
1109
            {
1110
                Message "Extracting: $pname $pver";
1111
                my $rv = JatsCmd (@cmd);
1112
                Error ("Package version not extracted")
1113
                    if ( $rv );
1114
            }
1115
        }
1116
    }
1117
 
1118
    #
1119
    # This command does not return
1120
    #
1121
    exit (0);
1122
}
1123
 
337 dpurdie 1124
#-------------------------------------------------------------------------------
359 dpurdie 1125
# Function        : getPkgDetailsByName
1126
#
1127
# Description     : Determine the PVID for a given package name and version
1128
#
1129
# Inputs          : $pname          - Package name
1130
#                   $pver           - Package Version
1131
#
361 dpurdie 1132
# Returns         :
359 dpurdie 1133
#
1134
 
1135
sub getPkgDetailsByName
1136
{
1137
    my ($pname, $pver) = @_;
1138
    my $pv_id;
1139
    my (@row);
1140
 
1141
    connectRM(\$RM_DB) unless ($RM_DB);
1142
 
1143
    # First get details for a given package version
1144
 
1145
    my $m_sqlstr = "SELECT pv.PV_ID, pkg.PKG_NAME, pv.PKG_VERSION" .
1146
                    " FROM RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg" .
1147
                    " WHERE pkg.PKG_NAME = \'$pname\' AND pv.PKG_VERSION = \'$pver\' AND pv.PKG_ID = pkg.PKG_ID";
1148
    my $sth = $RM_DB->prepare($m_sqlstr);
1149
    if ( defined($sth) )
1150
    {
1151
        if ( $sth->execute( ) )
1152
        {
1153
            if ( $sth->rows )
1154
            {
1155
                while ( @row = $sth->fetchrow_array )
1156
                {
1157
                    $pv_id = $row[0];
1158
                    my $name = $row[1];
1159
                    my $ver = $row[2];
1160
                    Verbose( "getPkgDetailsByName :PV_ID= $pv_id");
1161
                }
1162
            }
1163
            $sth->finish();
1164
        }
1165
    }
1166
    else
1167
    {
1168
        Error("Prepare failure" );
1169
    }
1170
    return $pv_id;
1171
}
1172
 
1173
#-------------------------------------------------------------------------------
1174
# Function        : getPkgDetailsByPV_ID
1175
#
1176
# Description     : Populate the Packages structure given a PV_ID
1177
#                   Called for each package in the SBOM
1178
#
1179
# Inputs          : PV_ID           - Package Unique Identifier
1180
#
1181
# Returns         : Populates Package
1182
#
1183
sub getPkgDetailsByPV_ID
1184
{
1185
    my ($PV_ID) = @_;
1186
    my $foundDetails = 0;
1187
    my (@row);
1188
 
1189
    connectRM(\$RM_DB) unless ($RM_DB);
1190
 
1191
    # First get details from pv_id
1192
 
1193
    my $m_sqlstr = "SELECT pv.PV_ID, pkg.PKG_NAME, pv.PKG_VERSION, release_manager.PK_RMAPI.return_vcs_tag($PV_ID)" .
1194
                    " FROM RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg " .
1195
                    " WHERE pv.PV_ID = \'$PV_ID\' AND pv.PKG_ID = pkg.PKG_ID";
1196
 
1197
    my $sth = $RM_DB->prepare($m_sqlstr);
1198
    if ( defined($sth) )
1199
    {
1200
        if ( $sth->execute( ) )
1201
        {
1202
            if ( $sth->rows )
1203
            {
1204
                while ( @row = $sth->fetchrow_array )
1205
                {
1206
                    my $pv_id       = $row[0];
1207
                    my $name        = $row[1];
1208
                    my $ver         = $row[2];
1209
                    my $vcstag      = $row[3] || '';
1210
 
1211
                    $vcstag =~ tr~\\/~/~;
1212
                    Verbose ("getPkgDetailsByPV_ID: $PV_ID, $name, $ver, $vcstag");
1213
 
1214
                    $PopPackage{$name}{$ver}{pvid} = $PV_ID;
1215
                    $PopPackage{$name}{$ver}{done} = 1;
1216
                    $PopPackage{$name}{$ver}{vcstag} = $vcstag;
1217
                    $PopPackage{$name}{$ver}{level} = $PopLevel;
1218
                    getDependsByPV_ID( $pv_id, $name, $ver );
1219
                }
1220
            }
1221
            else
1222
            {
1223
                Warning ("No Package details for: PVID: $PV_ID");
1224
            }
1225
            $sth->finish();
1226
        }
1227
        else
1228
        {
1229
            Error("getPkgDetailsByPV_ID: Execute failure", $m_sqlstr );
1230
        }
1231
    }
1232
    else
1233
    {
1234
        Error("Prepare failure" );
1235
    }
1236
}
1237
 
1238
#-------------------------------------------------------------------------------
1239
# Function        : getDependsByPV_ID
1240
#
1241
# Description     : Extract the dependancies for a given package version
1242
#
1243
# Inputs          : $pvid
1244
#
1245
# Returns         :
1246
#
1247
sub getDependsByPV_ID
1248
{
1249
    my ($pv_id, $pname, $pver) = @_;
1250
 
1251
    connectRM(\$RM_DB) unless ($RM_DB);
1252
 
1253
    #
365 dpurdie 1254
    #   Now extract the package dependencies
359 dpurdie 1255
    #
1256
    my $m_sqlstr = "SELECT pkg.PKG_NAME, pv.PKG_VERSION, pd.DPV_ID" .
1257
                   " FROM RELEASE_MANAGER.PACKAGE_DEPENDENCIES pd, RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg" .
1258
                   " WHERE pd.PV_ID = \'$pv_id\' AND pd.DPV_ID = pv.PV_ID AND pv.PKG_ID = pkg.PKG_ID";
1259
    my $sth = $RM_DB->prepare($m_sqlstr);
1260
    if ( defined($sth) )
1261
    {
1262
        if ( $sth->execute( ) )
1263
        {
1264
            if ( $sth->rows )
1265
            {
1266
                while ( my @row = $sth->fetchrow_array )
1267
                {
1268
                    my $name = $row[0];
1269
                    my $ver = $row[1];
1270
 
1271
                    Verbose2( "       Depends: $name, $ver");
1272
                    unless ( exists $PopPackage{$name} && exists $PopPackage{$name}{$ver} && exists $PopPackage{$name}{$ver}{done} )
1273
                    {
1274
                        push @StrayPackages, join($;, $name, $ver, $row[2] );
1275
                    }
1276
                }
1277
            }
1278
            $sth->finish();
1279
        }
1280
    }
1281
    else
1282
    {
1283
        Error("GetDepends:Prepare failure" );
1284
    }
1285
}
1286
 
1287
#-------------------------------------------------------------------------------
1273 dpurdie 1288
# Function        : getOptionsFromArray
1289
#
1290
# Description     : Like getOptions, but handles an array
1291
#                   Provided as the version of Perl used does not have one
1292
#
1293
# Inputs          : pArray                  - Ref to array
1294
#                   ....                    - GetOptions arguments
1295
#
1296
# Returns         : 
1297
#
1298
sub getOptionsFromArray
1299
{
1300
    my ($pArray, %args) = @_;
1301
 
1302
    local ( @ARGV );
1303
    @ARGV = @$pArray;
1304
    my $rv = GetOptions ( %args );
1305
    @$pArray = @ARGV;
1306
 
1307
    return $rv;
1308
}
1309
 
1310
 
1311
#-------------------------------------------------------------------------------
359 dpurdie 1312
# Function        : SubCommandHelp
1313
#
1314
# Description     : Provide help on a subcommand
1315
#
1316
# Inputs          : $help_level             - Help Level 1,2,3
1317
#                   $topic                  - Topic Name
1318
#
1319
# Returns         : This function does not return
1320
#
1321
sub SubCommandHelp
1322
{
1323
    my ($help_level, $topic) = @_;
1324
    my @sections;
1325
    #
1326
    #   Spell out the section we want to display
1327
    #
1328
    #   Note:
1329
    #   Due to bug in pod2usage can't use 'head1' by itself
1330
    #   Each one needs a subsection.
1331
    #
1332
    push @sections, qw( NAME SYNOPSIS ) ;
1333
    push @sections, qw( ARGUMENTS OPTIONS )     if ( $help_level > 1 );
1334
    push @sections, qw( DESCRIPTION EXAMPLES )  if ( $help_level > 2 );
1335
 
1336
    #
1337
    #   Extract section from the POD
1338
    #
1339
    pod2usage({-verbose => 99,
1340
               -noperldoc => 1,
1341
               -sections => $topic . '/' . join('|', @sections) } );
1342
}
1343
 
1344
#-------------------------------------------------------------------------------
227 dpurdie 1345
#   Documentation
359 dpurdie 1346
#   NOTE
227 dpurdie 1347
#
359 dpurdie 1348
#   Each subcommand MUST have
1349
#   head1 section as used by the subcommand
1350
#       This should be empty, as the contents will NOT be displayed
1351
#   head2 sections called
1352
#       NAME SYNOPSIS ARGUMENTS OPTIONS DESCRIPTION EXAMPLES
1353
#
1354
#=head1 xxxxxx
1355
#=head2 NAME
1356
#=head2 SYNOPSIS
1357
#=head2 ARGUMENTS
1358
#=head2 OPTIONS
1359
#=head2 DESCRIPTION
1360
#=head2 EXAMPLES
1361
#
227 dpurdie 1362
 
1363
=pod
1364
 
1365
=head1 NAME
1366
 
1367
jats_sandbox - Build in a Development Sandbox
1368
 
1369
=head1 SYNOPSIS
1370
 
361 dpurdie 1371
  jats sandbox [options] command [command options]
227 dpurdie 1372
 
1373
 Options:
299 dpurdie 1374
    -help[=n]          - Display help with specified detail
227 dpurdie 1375
    -help -help        - Detailed help message
1376
    -man               - Full documentation
1377
 
1273 dpurdie 1378
 Common Options:
1379
    -fromPackage=name          - Start building from package
1380
    -toPackage=name            - Stop building after package
1381
    -justPackage=name[,name]   - Build named packages
1382
    -ignorePackage=name[,name] - Do not build named packages
1383
 
227 dpurdie 1384
 Commands:
1385
    help                - Same as -help
1386
    create              - Create a sandbox in the current directory
359 dpurdie 1387
    populate            - Populate the sandbox with packages
299 dpurdie 1388
    delete              - Delete the sandbox
255 dpurdie 1389
    info [[-v]-v]       - Sandbox information. -v: Be more verbose
227 dpurdie 1390
    cmd                 - Do commands in all sandbox components
331 dpurdie 1391
    all                 - Do 'build', if required, then a make in all sandbox components
1392
    build               - Force 'build and make' in all sandbox components
275 dpurdie 1393
    make                - Do 'make' in all sandbox components
273 dpurdie 1394
    clean               - Do 'make clean' in all sandbox components
1395
    clobber             - Do 'build clobber' is all sandbox components
337 dpurdie 1396
    cache               - Cache external dependent packages
227 dpurdie 1397
 
359 dpurdie 1398
 Use the command
1399
    jats sandbox 'command' -h
1400
 for command specific help
361 dpurdie 1401
 
227 dpurdie 1402
=head1 OPTIONS
1403
 
1404
=over 8
1405
 
299 dpurdie 1406
=item B<-help[=n]>
227 dpurdie 1407
 
1408
Print a brief help message and exits.
299 dpurdie 1409
There are three levels of help
227 dpurdie 1410
 
299 dpurdie 1411
=over 8
1412
 
361 dpurdie 1413
=item   1
299 dpurdie 1414
 
361 dpurdie 1415
Brief synopsis
299 dpurdie 1416
 
361 dpurdie 1417
=item   2
299 dpurdie 1418
 
361 dpurdie 1419
Synopsis and option summary
1420
 
1421
=item   3
1422
 
1423
Detailed help in man format
1424
 
299 dpurdie 1425
=back 8
1426
 
227 dpurdie 1427
=item B<-help -help>
1428
 
1429
Print a detailed help message with an explanation for each option.
1430
 
1431
=item B<-man>
1432
 
299 dpurdie 1433
Prints the manual page and exits. This is the same a -help=3
227 dpurdie 1434
 
1273 dpurdie 1435
=item B<-fromPackage=name>
1436
 
1437
This option is available in all commands that process multiple packages.
1438
Package processing will start at the named package.
1439
 
1440
The default operation is to process all packages.
1441
 
1442
=item B<-toPackage=name>
1443
 
1444
This option is available in all commands that process multiple packages.
1445
Package processing will stop at the named package.
1446
 
1447
The default operation is to process all packages.
1448
 
1449
=item B<-justPackge=name[,name]>
1450
 
1451
This option is available in all commands that process multiple packages. The
1452
named packages will be processed in the correct build order. Packages that are not
1453
named will be skipped.
1454
 
1455
Multiple packages can be named either by separating names with a comma, or
1456
with multiple options.
1457
 
1458
=item B<-ignorePackge=name[,name]>
1459
 
1460
This option is available in all commands that process multiple packages. The
1461
named packages will not be processed.
1462
 
1463
Multiple packages can be named either by separating names with a comma, or
1464
with multiple options.
1465
 
1466
The exclusion of a package takes precedence over its inclusion.
1467
 
279 dpurdie 1468
=back
1469
 
227 dpurdie 1470
=head1 DESCRIPTION
1471
 
299 dpurdie 1472
This program is the primary tool for the maintenance of Development Sandboxes.
1473
 
227 dpurdie 1474
More documentation will follow.
1475
 
279 dpurdie 1476
=head2 SANDBOX DIRECTORY
1477
 
299 dpurdie 1478
The sandbox directory is marked as being a sandbox through the use of the
1479
'sandbox create' command. This will create a suitable structure within the
279 dpurdie 1480
current directory.
1481
 
1482
Several JATS commands operate differently within a sandbox. The 'extract' and
365 dpurdie 1483
'release' commands will create static views within the sandbox and not the
279 dpurdie 1484
normal directory. The 'sandbox' sub commands can only be used within a sandbox.
1485
 
1486
The sandbox directory contains sub directories, each should contain a single
359 dpurdie 1487
package. Sub directories may be created with the 'jats extract' command or with the
1488
'jats sandbox populate' command.
279 dpurdie 1489
 
1490
Note: Symbolic links are not supported. They cannot work as he sandbox mechanism
365 dpurdie 1491
requires that all the packages be contained within a sub directory tree so
279 dpurdie 1492
that the root of the sandbox can be located by a simple scan of the directory
1493
tree.
1494
 
325 dpurdie 1495
If a package subdirectory contains a file called 'stop' or 'stop.
1496
<GBE_MACHTYPE>', then that package will not be considered as a part of the
1497
build-set. A 'stop' file will prevent consideration all build platforms. The 'stop.
1498
<GBE_MACHTYPE>' will only prevent consideration if being built on a GBE_MACHTYPE
1499
type of computer.
279 dpurdie 1500
 
359 dpurdie 1501
=head1 Create Sandbox
299 dpurdie 1502
 
359 dpurdie 1503
=head2 NAME
299 dpurdie 1504
 
359 dpurdie 1505
Create Sandbox
1506
 
1507
=head2 SYNOPSIS
1508
 
1509
jats sandbox [options] create [command options]
1510
 
1511
 Options:
1512
    -help[=n]               - Help message, [n=1,2,3]
1513
    -man                    - Full documentation [-help=3]
1514
    -verbose[=n]            - Verbose command operation
1515
 
1516
 Command Options
1517
    -help[=n]               - Command specific help, [n=1,2,3]
1518
    -verbose[=n]            - Verbose operation
1519
    -exact                  - Create sandbox to reproduce exact versions
1520
 
1521
=head2 OPTIONS
1522
 
1523
The 'create' command takes the following options:
1524
 
1525
=over 8
1526
 
1527
=item -exact
1528
 
1529
When this option is specified the sandbox is marked for exact processing of
1530
package versions. In this mode the version numbers of the packages in the
1531
sandbox are significant. This is ideal for recreating a package-version.
1532
 
1533
The default is for in-exact processing, in which the version numbers of packages
1534
within the sandbox are not significant. The is ideal for development.
1535
 
1536
=back
1537
 
1538
=head2 DESCRIPTION
1539
 
299 dpurdie 1540
The 'create' command will create a sandbox in the users current directory. It is
1541
not possible to create a sandbox within a sandbox.
1542
 
1543
A sandbox can be created in a directory that contains files and subdirectories.
1544
 
1545
The create command simply places a known directory in the current directory.
359 dpurdie 1546
This directory is used by the sandboxing process. It may be manually deleted, or
299 dpurdie 1547
deleted with the 'delete' command.
1548
 
359 dpurdie 1549
=head1 Populate Sandbox
1550
 
1551
=head2 NAME
1552
 
1553
Populate a Sandbox
1554
 
1555
=head2 SYNOPSIS
1556
 
1557
jats sandbox [options] populate [command options] [packageName packageVersion]
1558
 
1559
 Options:
1560
    -help[=n]               - Help message, [n=1,2,3]
1561
    -man                    - Full documentation [-help=3]
1562
    -verbose[=n]            - Verbose command operation
1563
 
1564
 Command Options
1565
    -help[=n]               - Command specific help, [n=1,2,3]
1566
    -recurse[=n]            - Locate dependencies within packages
1567
    -missing                - Locate missing packages
1568
    -test                   - Do not extract packages
1569
    -<Other>                - Pass options to jats extract
1570
 
1571
=head2 ARGUMENTS
1572
 
1573
The 'populate' command can take a package name and version as arguments. It will
1574
then populate the sandbox with this package. See 'DESCRIPTION' for details.
1575
 
1576
=head2 OPTIONS
1577
 
1578
The 'populate' command takes the following options:
1579
 
1580
=over 4
1581
 
1582
=item -recurse[=N]
1583
 
1584
This option will modify the operation of the command such that dependencies
1585
of named packages can also be extracted into the sandbox.
1586
 
1587
The default operation is to only extract named packages. If the option is
1588
specified then all dependent packages are processed. An optional numeric argument
1589
can be specified to limit the depth of the recursion.
1590
 
1591
=item -missing
1592
 
1593
This option will modify the operation of the dependency recursion scanning such
1594
that dependent packages that exist in a package archive will not be extracted.
1595
 
1596
Use of this option allows a sandbox to be populated with packages that are
1597
required by packages in the sandbox, but are not available in a package archive.
1598
 
1599
=item -test
1600
 
1601
This option will prevent the command from performing the extraction. It will
1602
simply display the JATS commands that can be used to perform the extraction.
1603
 
1604
=item -<Other>
1605
 
1606
Options not understood by the 'populate' sub command will be passed through
1607
the package extraction program. Useful options include:
1608
 
363 dpurdie 1609
=over 4
359 dpurdie 1610
 
361 dpurdie 1611
=item *
359 dpurdie 1612
 
361 dpurdie 1613
-extractfiles
359 dpurdie 1614
 
361 dpurdie 1615
=item *
1616
 
1617
-branch=<branch name>
1618
 
359 dpurdie 1619
=back
1620
 
1621
=back
1622
 
1623
=head2 DESCRIPTION
1624
 
1625
The 'populate' command can be used to assist in populating the sandbox. It has
1626
two modes of operation.
1627
 
363 dpurdie 1628
=over 4
359 dpurdie 1629
 
361 dpurdie 1630
=item 1
359 dpurdie 1631
 
361 dpurdie 1632
Named Package
1633
 
363 dpurdie 1634
If the user specifies both a package name and a package version then the command
359 dpurdie 1635
will populate the sandbox with that package and optionally its dependencies.
1636
 
361 dpurdie 1637
=item 2
359 dpurdie 1638
 
361 dpurdie 1639
Determine missing dependencies
1640
 
359 dpurdie 1641
If the user does not specify a package name and version, but does specify
1642
the '-missing' option,  then the command will examine the current sandbox and
1643
determine missing dependent packages. It will then populate the sandbox with
1644
these packages and optionally there dependencies.
1645
 
1646
=back
1647
 
1648
=head2 EXAMPLES
1649
 
1650
=over 4
1651
 
361 dpurdie 1652
=item *
359 dpurdie 1653
 
361 dpurdie 1654
jats sandbox populate package1 version1
1655
 
359 dpurdie 1656
This command will populate the sandbox with version1 of package1, if it does not
1657
already exist in the sandbox.
1658
 
361 dpurdie 1659
=item *
359 dpurdie 1660
 
361 dpurdie 1661
jats sandbox populate package1 version1 -recurse -missing
1662
 
359 dpurdie 1663
This command will populate the sandbox with version1 of package1, if it does not
1664
already exist in the sandbox, together will all the packages dependencies that
1665
are not available in a package archive.
1666
 
361 dpurdie 1667
=item *
359 dpurdie 1668
 
361 dpurdie 1669
jats sandbox populate -recurse -missing
1670
 
359 dpurdie 1671
This command will examine the current sandbox and populate the sandbox with
1672
packages that are required to build the packages in the sandbox and the
1673
dependencies of these packages, provide the dependent package is not in a
1674
package archive.
1675
 
361 dpurdie 1676
=item *
359 dpurdie 1677
 
361 dpurdie 1678
jats sandbox populate
1679
 
359 dpurdie 1680
This command will examine the current sandbox and populate the sandbox with
1681
packages that are required to build the packages in the sandbox. It will not
1682
examine the dependents of these packages.
1683
 
1684
=back
1685
 
1686
=head1 Delete Sandbox
1687
 
1688
=head2 NAME
1689
 
365 dpurdie 1690
Delete a a sandbox
359 dpurdie 1691
 
1692
=head2 SYNOPSIS
1693
 
1694
jats sandbox [options] delete
1695
 
1696
 Options:
1697
    -help[=n]               - Help message, [n=1,2,3]
1698
    -man                    - Full documentation [-help=3]
1699
    -verbose[=n]            - Verbose command operation
1700
 
1701
=head2 DESCRIPTION
1702
 
299 dpurdie 1703
The 'delete' command will delete the sandbox's marker directory. The command may
1704
be executed anywhere within the sandbox.
1705
 
359 dpurdie 1706
Once the sandbox has been deleted, the user must remove the components within the
299 dpurdie 1707
sandbox.
1708
 
359 dpurdie 1709
=head1 Sandbox Information
299 dpurdie 1710
 
359 dpurdie 1711
=head2 NAME
1712
 
1713
Display Sandbox Information
1714
 
1715
=head2 SYNOPSIS
1716
 
1717
jats sandbox [options] info [command options]
1718
 
1719
 Options:
1720
    -help[=n]               - Help message, [n=1,2,3]
1721
    -man                    - Full documentation [-help=3]
1722
    -verbose[=n]            - Verbose command operation
1723
 
1724
 Command Options
1725
    -help[=n]               - Command specific help, [n=1,2,3]
1726
    -verbose[=n]            - Display more information
361 dpurdie 1727
 
359 dpurdie 1728
=head2 OPTIONS
1729
 
1730
=over
1731
 
1732
=item B<-verbose[=n]>
1733
 
1734
This options will increase the verbosity of the information being displayed.
1735
Values 1 and 2 are described in the detailed 'DESCRIPTION'. Other values are
1736
reserved for diagnostic use.
1737
 
1738
=back
1739
 
1740
=head2 DESCRIPTION
1741
 
299 dpurdie 1742
The 'info' command will display information about the build order and the
359 dpurdie 1743
dependencies of packages that it finds within the sandbox.
299 dpurdie 1744
 
359 dpurdie 1745
The command works within various levels of verbosity:
299 dpurdie 1746
 
1747
=over 8
1748
 
361 dpurdie 1749
=item *
299 dpurdie 1750
 
361 dpurdie 1751
No Verbosity
1752
 
299 dpurdie 1753
The basic command will display the build order and the external
335 dpurdie 1754
dependencies. External dependencies may be prefixed with one of the
1755
following indicators:
299 dpurdie 1756
 
335 dpurdie 1757
=over 8
1758
 
361 dpurdie 1759
=item   '+' Multiple versions of this package are being used by sandboxed components.
335 dpurdie 1760
 
361 dpurdie 1761
=item   '*' The package cannot be found in any of the package archives.
335 dpurdie 1762
 
1763
=back
1764
 
361 dpurdie 1765
=item *
299 dpurdie 1766
 
361 dpurdie 1767
Verbosity of 1
1768
 
359 dpurdie 1769
This level of verbosity will display the build order and detailed information
299 dpurdie 1770
on the dependencies. The dependencies will be prefixed with:
1771
 
1772
=over 8
1773
 
361 dpurdie 1774
=item   E Dependent Package is external to the sandbox
299 dpurdie 1775
 
361 dpurdie 1776
=item   I Dependent Package is internal to the sandbox
299 dpurdie 1777
 
1778
=back
1779
 
335 dpurdie 1780
External dependencies may be prefixed with one of the indicators described for
1781
no-verbosity. Additionally the internal consumer of the external package is also
1782
shown. These are prefixed with a 'U'.
299 dpurdie 1783
 
361 dpurdie 1784
=item *
299 dpurdie 1785
 
361 dpurdie 1786
Verbosity of 2
1787
 
359 dpurdie 1788
Reserved for future use
299 dpurdie 1789
 
361 dpurdie 1790
=item *
299 dpurdie 1791
 
361 dpurdie 1792
Verbosity over 2
1793
 
359 dpurdie 1794
This should be considered a debug option. Undocumented internal information will
299 dpurdie 1795
be displayed.
1796
 
1797
=back
1798
 
359 dpurdie 1799
=head1 Command all
331 dpurdie 1800
 
359 dpurdie 1801
=head2 NAME
1802
 
1803
Build packages in the sandbox
1804
 
1805
=head2 SYNOPSIS
1806
 
1807
jats sandbox [options] all [command options] [arguments]
1808
 
1809
 Options:
1810
    -help[=n]               - Help message, [n=1,2,3]
1811
    -man                    - Full documentation [-help=3]
1812
    -verbose[=n]            - Verbose command operation
1813
 
1814
 Command Options
1815
    -help[=n]               - Command specific help, [n=1,2,3]
1816
 
1817
=head2 ARGUMENTS
1818
 
1819
Arguments are passed to the 'make' phase of the process.
1820
 
1821
=head2 OPTIONS
1822
 
1823
The are command specific options.
1824
 
1825
=head2 DESCRIPTION
1826
 
331 dpurdie 1827
The 'all' command will perform build, if the build files are out of date,
1828
followed by a make in each of the packages within the sandbox, in the correct
1829
build order.
1830
 
1831
Any arguments are passed to the 'make' phase of the process.
1832
 
1833
This command may be used to:
1834
 
1835
=over 8
1836
 
361 dpurdie 1837
=item *
331 dpurdie 1838
 
361 dpurdie 1839
Pickup any build file changes.
331 dpurdie 1840
 
361 dpurdie 1841
=item *
1842
 
1843
Resume a failed build.
1844
 
331 dpurdie 1845
=back
1846
 
359 dpurdie 1847
=head1 Command build
331 dpurdie 1848
 
359 dpurdie 1849
=head2 NAME
1850
 
1851
Build packages in the sandbox
1852
 
1853
=head2 SYNOPSIS
1854
 
1855
jats sandbox [options] build [command options] [arguments]
1856
 
1857
 Options:
1858
    -help[=n]               - Help message, [n=1,2,3]
1859
    -man                    - Full documentation [-help=3]
1860
    -verbose[=n]            - Verbose command operation
1861
 
1862
 Command Options
1863
    -help[=n]               - Command specific help, [n=1,2,3]
1864
 
1865
=head2 ARGUMENTS
1866
 
1867
Arguments are passed to the 'make' phase of the process.
1868
 
1869
=head2 OPTIONS
1870
 
1871
The are no command specific options.
1872
 
1873
=head2 DESCRIPTION
1874
 
331 dpurdie 1875
The 'build' command will force a build followed by a make in each of the packages
1876
within the sandbox, in the correct build order.
1877
 
1878
Any arguments are passed to the 'make' phase of the process.
1879
 
1880
In practice, the 'sandbox all' command is quicker.
1881
 
359 dpurdie 1882
=head1 Clean
331 dpurdie 1883
 
359 dpurdie 1884
=head2 NAME
1885
 
1886
Clean all sandbox components
1887
 
1888
=head2 SYNOPSIS
1889
 
1890
jats sandbox [options] clean|clobber [command options]
1891
 
1892
 Options:
1893
    -help[=n]               - Help message, [n=1,2,3]
1894
    -man                    - Full documentation [-help=3]
1895
    -verbose[=n]            - Verbose command operation
1896
 
1897
 Command Options
1898
    -help[=n]               - Command specific help, [n=1,2,3]
1899
 
1900
=head2 ARGUMENTS
1901
 
1902
None
1903
 
1904
=head2 OPTIONS
1905
 
1906
No command specific options
1907
 
1908
=head2 DESCRIPTION
1909
 
1910
The 'clean' command will perform a 'jats make clean' in all components in the
1911
sandbox.
1912
 
1913
The 'clobber' command will perform a 'jats clobber' in all components in the
1914
sandbox.
1915
 
1916
=head1 make
1917
 
1918
=head2 NAME
1919
 
1920
Make packages in the sandbox
1921
 
1922
=head2 SYNOPSIS
1923
 
1924
jats sandbox [options] make [command options] [arguments]
1925
 
1926
 Options:
1927
    -help[=n]               - Help message, [n=1,2,3]
1928
    -man                    - Full documentation [-help=3]
1929
    -verbose[=n]            - Verbose command operation
1930
 
1931
 Command Options
1932
    -help[=n]               - Command specific help, [n=1,2,3]
1933
 
1934
=head2 ARGUMENTS
1935
 
1936
Arguments are passed to the 'make' phase of the process.
1937
 
1938
=head2 OPTIONS
1939
 
1940
The are no command specific options.
1941
 
1942
=head2 DESCRIPTION
1943
 
331 dpurdie 1944
The 'make' command will perform a 'make' operation in each of the packages
1945
within the sandbox, in the correct build order.
1946
 
1947
Any arguments are passed to the 'make'.
1948
 
359 dpurdie 1949
=head1 cmd
331 dpurdie 1950
 
359 dpurdie 1951
=head2 NAME
1952
 
1953
Process each package with a specified command.
1954
 
1955
=head2 SYNOPSIS
1956
 
1957
jats sandbox [options] cmd [command options] [arguments]
1958
 
1959
 Options:
1960
    -help[=n]               - Help message, [n=1,2,3]
1961
    -man                    - Full documentation [-help=3]
1962
    -verbose[=n]            - Verbose command operation
1963
 
1964
 Command Options
1965
    -help[=n]               - Command specific help, [n=1,2,3]
1966
 
1967
=head2 ARGUMENTS
1968
 
1969
Arguments are passed to a JATS command.
1970
 
1971
=head2 OPTIONS
1972
 
1973
The are no command specific options.
1974
 
1975
=head2 DESCRIPTION
1976
 
331 dpurdie 1977
The 'cmd' command will pass all of its arguments to JATS in the build directory
1978
of each of the packages within the sandbox, in the package build order.
1979
 
359 dpurdie 1980
=head1 Cache
331 dpurdie 1981
 
359 dpurdie 1982
=head2 NAME
331 dpurdie 1983
 
359 dpurdie 1984
Cache dependent packages
331 dpurdie 1985
 
359 dpurdie 1986
jats sandbox [options] cache [command options]
331 dpurdie 1987
 
359 dpurdie 1988
 Options:
1989
    -help[=n]               - Help message, [n=1,2,3]
1990
    -man                    - Full documentation [-help=3]
1991
    -verbose[=n]            - Verbose command operation
337 dpurdie 1992
 
359 dpurdie 1993
 Command Options
1994
    -help[=n]               - Command specific help, [n=1,2,3]
337 dpurdie 1995
 
359 dpurdie 1996
=head2 ARGUMENTS
1997
 
1998
The are no command specific arguments.
1999
 
2000
=head2 OPTIONS
2001
 
2002
The are no command specific options.
2003
 
2004
=head2 DESCRIPTION
2005
 
2006
The 'cache' command will cache all external dependent packages into the users
2007
dpkg_archive_cache as defined through the EnvVar GBE_DPKG_CACHE. The result is
2008
similar to the command 'jats sandbox build -cache', without the overhead of
2009
building the sandbox components.
2010
 
2011
This command allows the simple creation of a small development environment that
2012
is not tied to the larger Development Environment. It may then be used in a
337 dpurdie 2013
disconnected mode to perform development.
2014
 
227 dpurdie 2015
=cut
2016