Subversion Repositories DevTools

Rev

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