Subversion Repositories DevTools

Rev

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

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