Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
263 dpurdie 1
########################################################################
2
# Copyright (C) 2008 ERG Limited, All rights reserved
3
#
4
# Module name   : jats_ccrelease.pl
5
# Module type   : Makefile system
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   : A script to build a package from a clearcase element
10
#                 The script will:
11
#                   Create a clearcase view
12
#                   Checkout the files
13
#                   Locate the build file
14
#                   Build the packages
15
#                   Install packages
16
#                   Remove the view
17
#
18
#               The script can do a lot of other things too.
19
#
2429 dpurdie 20
#               Defined exit code for automation
21
#                   10 - No files in extracted view
22
#                        Root directory not found
23
#                   11 - Label not found
24
#                   1  - Everything else
25
#
263 dpurdie 26
#......................................................................#
27
 
28
require 5.008_002;
29
use strict;
30
use warnings;
31
use JatsError;
32
use JatsSystem;
33
use FileUtils;
34
use JatsBuildFiles;
35
use ArrayHashUtils;
36
 
37
use Pod::Usage;                             # required for help support
38
use Getopt::Long;
39
use File::Find;
40
use File::Copy;
41
use File::Path;
42
use Cwd;
43
 
44
my $VERSION = "1.6.0";                      # Update this
45
 
46
#
47
#   Options
48
#
49
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
50
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
51
my $opt_help = 0;                           # User help level
52
my @opt_spec;                               # Labels used as a base for the view
53
my $opt_vob;                                # Hint: which VOB to use
54
my $opt_dpkg = 1;                           # Transfer built package to dpkg_archive
55
my $opt_copy = 0;                           # Copy built package to user
56
my $opt_reuse = 0;                          # Re-user view if it exists
57
my $opt_viewname;                           # View Name
58
my $opt_extract;                            # Just create a static view
59
my $opt_extract_files;                      # Just extract files to user - no view
60
my $opt_delete;                             # Just delete the view
61
my @opt_build;                              # build files to use (kludge)
62
my $opt_test;                               # Test the build process - no copy
63
my $opt_cache;                              # Cache external packages
64
my $opt_keep = 0;                           # Keep view if successful
65
my $opt_lock = 0;                           # Lock label before release
66
my $opt_beta;                               # Create beta release
67
my $opt_merge;                              # Merge release
68
my $opt_path;                               # Path for view spec
69
my $opt_runtests = 1;                       # Run unit tests after build
70
my $opt_latest_root;                        # Modify config spec with rule (kludge)
71
my $opt_branch;                             # Create config spec with branch
72
my $opt_debug_build = 0;                    # Build Debug Only
73
my $opt_prod_build = 0;                     # Build ion Only
74
my $opt_config_spec;                        # User provided config spec
75
my $opt_prefix = 1;                         # Prefix the view tag with user-name
76
my $opt_tag;                                # View tag insert (build or export or user)
1403 dpurdie 77
my $opt_devModeStr;                         # Development mode string - not used
263 dpurdie 78
 
79
#
80
#   Globals - Provided by the JATS environment
81
#
82
my $USER            = $ENV{'USER'};
83
my $UNIX            = $ENV{'GBE_UNIX'};
84
my $GBE_SANDBOX     = $ENV{'GBE_SANDBOX'};
85
my $GBE_ABT         = $ENV{'GBE_ABT'} || '0';
279 dpurdie 86
my $MACHINENAME     = $ENV{'GBE_HOSTNAME'};
343 dpurdie 87
my $GBE_VIEWBASE    = $ENV{'GBE_VIEWBASE'};   # Root of the view
263 dpurdie 88
 
89
#
90
#   Globals
91
#
343 dpurdie 92
my $VIEWDIR_ROOT;                           # Root of the static view
263 dpurdie 93
my $VIEWTAG;                                # The view tag
94
my $VIEWDIR;                                # Absolute path to the view
95
my $VIEWPATH;                               # Path relative to clearcase
96
my $user_cwd;
97
my $error = 0;
98
my $label_count = 0;                        # Number of labels to create the view
99
my @label_not_locked;                       # List of unlocked labels
100
my @label_locked;                           # List of labels I locked
101
my @error_list;                             # ClearCmd detected errors
379 dpurdie 102
my $load_count;                             # Loaded files
263 dpurdie 103
 
104
my $UNIX_VOB_PREFIX = '/vobs';
105
my $VOB_PREFIX = $UNIX ? $UNIX_VOB_PREFIX : '';
106
 
107
my $UNIX_VIEW_PREFIX = '/view/';            # Don't know how to determine this value
108
my $WIN32_VIEW_PREFIX = 'o:/';              # Don't know how to determine this value
109
my $VIEW_PREFIX = $UNIX ? $UNIX_VIEW_PREFIX : $WIN32_VIEW_PREFIX ;
110
 
111
my $VOB_SEP         = $UNIX ? '/' : '\\';
112
my $view_prefix     = "${USER}_";
113
 
114
#
115
#   ROOT_VOBS is a list of VOBS too look in first
116
#   If a label is not found in these vobs, then the program will
117
#   look in all vobs. This list is a hint to speed up searching
118
#
119
my $ROOT_VOB;
120
my $root_vob_spec;
121
my @ROOT_VOBS = qw( /LMOS /DPG_SWBase /DPG_SWCode /ProjectCD /MASS_Dev_Bus
122
                    /MASS_Dev_Infra /MOS /MASS_Dataman /MASS_Dev /MASS_Dev_Dataman
123
                    /COTS /GMPTE2005 /GMPTE2005_obe /MPR /MOS );
124
 
125
 
126
#-------------------------------------------------------------------------------
127
# Function        : Mainline Entry Point
128
#
129
# Description     :
130
#
131
# Inputs          :
132
#
133
 
134
#
135
#   Alter some option defaults if we are creating a view within a sandbox
136
#
137
if ( $GBE_SANDBOX )
138
{
343 dpurdie 139
   $GBE_VIEWBASE = $GBE_SANDBOX;
263 dpurdie 140
   $opt_prefix = 0;
321 dpurdie 141
   (my $sandbox_name = $GBE_SANDBOX) =~ s~.*/~~ ;
142
   $opt_tag = 'sandbox.'. $sandbox_name unless ( $opt_tag );
263 dpurdie 143
}
144
 
145
#
146
#   Parse the user options
147
#
148
my $result = GetOptions (
149
                "help+"         => \$opt_help,              # flag, multiple use allowed
150
                "manual:3"      => \$opt_help,              # flag
151
                "v|verbose:+"     => \$opt_verbose,           # flag, multiple use allowed
152
                "label=s"       => \@opt_spec,              # Array of build specs
153
                "spec=s"        => \@opt_spec,              # Array of build specs
154
                "config=s"      => \$opt_config_spec,       # String
155
                "view=s"        => \$opt_viewname,          # String
156
                "vob=s"         => \$opt_vob,               # String
157
                "dpkg!"         => \$opt_dpkg,              # [no]flag
158
                "copy!"         => \$opt_copy,              # [no]flag
159
                "reuse!"        => \$opt_reuse,             # [no]flag
379 dpurdie 160
                "extract:+"     => \$opt_extract,           # flag
263 dpurdie 161
                "extractfiles"  => \$opt_extract_files,     # flag
351 dpurdie 162
                "delete:+"      => \$opt_delete,            # flag
263 dpurdie 163
                "build=s"       => \@opt_build,             # An array of build
164
                "test!"         => \$opt_test,              # [no]flag
165
                "cache"         => \$opt_cache,             # flag
166
                "keep!"         => \$opt_keep,              # [no]flag
167
                "lock!"         => \$opt_lock,              # [no]flag
168
                "beta!"         => \$opt_beta,              # [no]flag
169
                "merge"         => \$opt_merge,             # [no]flag
170
                "path=s"        => \$opt_path,              # string
171
                "runtests!"     => \$opt_runtests,          # [no]flag
172
                "latestroot=s"  => \$opt_latest_root,       # String
173
                "branch=s"      => \$opt_branch,            # String
174
                "mkbranch=s"    => \$opt_branch,            # String
175
                "prodOnly"      => \$opt_prod_build,        # flag
176
                "debugOnly"     => \$opt_debug_build,       # flag
343 dpurdie 177
                "root=s"        => \$GBE_VIEWBASE,          # string
263 dpurdie 178
                "prefix!"       => \$opt_prefix,            # flag
179
                "tag=s"         => \$opt_tag,               # string
1403 dpurdie 180
                'devMode=s'     => \$opt_devModeStr,        # Compatability. Not used
263 dpurdie 181
                );
182
 
183
                #
184
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
185
                #
186
 
187
#
188
#   Process help and manual options
189
#
190
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
191
pod2usage(-verbose => 1)  if ($opt_help == 2 );
192
pod2usage(-verbose => 2)  if ($opt_help > 2 );
193
 
194
InitFileUtils();
195
 
196
#
197
#   Configure the error reporting process now that we have the user options
198
#
379 dpurdie 199
ErrorConfig( 'name'    => 'CCRELEASE',
263 dpurdie 200
             'verbose' => $opt_verbose );
201
 
202
#
203
#   Validate user options
204
#   Use either -label or one command line argument
205
#
206
Error ("Unexpected command line arguments present.","Cannot mix -label and command line label" )
207
    if ( $#opt_spec >= 0 && $#ARGV >= 0);
208
 
209
push @opt_spec, @ARGV;
210
 
211
if ( $opt_config_spec )
212
{
213
    Error("Cannot use -path with -config")      if($opt_path);
214
    Error("Cannot use -branch with -config")    if($opt_branch);
215
    Error("Cannot use -vob with -config")       if($opt_vob);
216
    Error("Cannot use a label with -config")    if( @opt_spec);
217
    Error("Config spec file not found: $opt_config_spec") unless ( -f $opt_config_spec );
218
 
219
    unless ( $opt_viewname )
220
    {
221
        $opt_viewname = StripDirExt($opt_config_spec);
222
        $opt_viewname =~ s~[\.:/\\]~_~g;
223
    }
224
 
225
    $opt_vob = "";
226
 
227
    #
228
    #   Convert file in an absolute file name
229
    #   Will be needed as we change directory
230
    #
231
    $opt_config_spec = FullPath($opt_config_spec);
232
}
233
 
234
unless(  @opt_spec || $opt_config_spec  )
235
{
236
    Error ("Need a view or a label. -help for options") if ( $opt_delete  && ! $opt_viewname );
237
    Error ("Need a label or config_spec. -help for options") unless $opt_delete;
238
}
239
 
240
#
241
#   Convert label with embedded VCS information into a 'normal' form.
242
#   Form:
243
#       CC::label
244
#       CC::path::label
245
#       CC::::label
246
#
247
foreach ( @opt_spec )
248
{
249
    if ( $_ =~ m~^(.+?)::(.*?)(::(.+))?$~ )
250
    {
251
        Error ("Label contains invalid Version Control Identifier($1): $_")
252
            if ( $1 ne 'CC' );
253
 
254
        my $ll = $2;
255
        my $path;
256
        if ( $3 )
257
        {
258
            $path = $2;
259
            $ll = $4;
260
            if ( $path  )
261
            {
262
                Error ("Multiple conflicting Embedded source paths",
263
                       "Path: $opt_path",
264
                     "VCS Spec: $_" ) if ( $opt_path && $path ne $opt_path );
265
                $opt_path = $path;
266
            }
267
        }
268
        $_ = $ll;
269
    }
270
    Verbose ("Clean URL: $_");
271
}
272
 
273
#
274
#   User has specified both debug and production
275
#   Then set both to 0 : ie default
276
#
277
if ( $opt_debug_build + $opt_prod_build > 1 )
278
{
279
    $opt_debug_build = 0;
280
    $opt_prod_build = 0;
281
}
282
 
283
#
284
#   User has requested test mode
285
#       - Don't copy
286
#       - Don't packgae
287
#
288
if ( $opt_test )
289
{
290
    $opt_dpkg = 0;
291
    $opt_copy = 0;
292
}
293
 
294
#
295
#   Determine the machine type
296
#
297
Verbose ("Machine Type: UNIX=$UNIX");
298
 
299
Error ("Machine Name not determined")
300
    unless ( $MACHINENAME );
301
$user_cwd = getcwd;
302
 
303
Error ("USER name not determined" )
304
    unless ( $USER );
305
 
306
#
307
#   Ensure that the 'cleartool' program can be located
308
#
309
Verbose ("Locate clearcase utility in users path");
310
Error ("Cannot locate the 'cleartool' utility in the users PATH")
311
    unless ( LocateProgInPath('cleartool', '--All') );
312
 
313
 
314
#
343 dpurdie 315
#   Clean up the view root directory
263 dpurdie 316
#
343 dpurdie 317
$VIEWDIR_ROOT = Realpath($GBE_VIEWBASE) || $GBE_VIEWBASE;
263 dpurdie 318
 
319
Verbose ("Viewpath: $VIEWDIR_ROOT");
320
Error ("Cannot locate view root directory: $VIEWDIR_ROOT" ) unless (-d $VIEWDIR_ROOT);
321
 
322
#
323
#   Remove any user name from the front of the view name
324
#   Simplifies the deletion process as the user can provide
325
#   the directory name
326
#
327
$view_prefix = "" unless ( $opt_prefix );
328
 
329
#
330
#   Setup user specified viewname
331
#   Include the user name to ensure that the view name is unique-ish
332
#   Keep the name as short as possible as some compilers display a fixed
333
#   length filename in error messages and this name is part of the path
334
#
335
#   Base the viewname on the view label. This will simplify the creation
336
#   of multiple views and reduce the risk of unexpected deletion
337
#
338
$opt_viewname = $opt_spec[0] unless ( defined $opt_viewname );
339
$opt_viewname =~ s~^$view_prefix~~ if (defined($opt_viewname) && $view_prefix && $opt_delete );
340
 
341
#
342
#   Create the view tag
343
#   Attempt to make this globally unique
344
#   Include USER name, MACHINE name, the view name
345
#   Optionally include a user 'tag'. Provided to allow the ABT to maintain
346
#   multiple instances of a view.
347
#
348
unless ( $opt_tag )
349
{
350
    $opt_tag = $opt_extract_files ? 'extract' : 'build';
351
}
352
$VIEWTAG = "${USER}_${MACHINENAME}_${opt_tag}_${opt_viewname}";
353
 
354
#
355
#   Create a clearcase view to be used for the view
356
#
357
$VIEWPATH = "$view_prefix$opt_viewname";
358
$VIEWDIR = "$VIEWDIR_ROOT/$VIEWPATH";
299 dpurdie 359
$VIEWDIR =~ tr~\\/~/~s;
263 dpurdie 360
Verbose( "Hostname: $MACHINENAME" );
361
Verbose( "Viewtag: $VIEWTAG" );
362
Verbose( "Viewpath: $VIEWPATH" );
363
Verbose( "Viewdir : $VIEWDIR" );
364
 
365
#
366
#   If the user has specified a "source path", then we can extract the VOB
367
#   from that path. It will be the first directory
368
#
369
Verbose("Locate Source VOB");
370
if ( $opt_path )
371
{
372
    $opt_path =~ tr~\\/~/~s;
373
    $opt_path =~ s~/+$~~;
374
 
375
    Error( "Source Path needs leading '/'") unless ( $opt_path =~ m~^/~ );
376
    Error( "Source Path is a UNC" ) if ( $opt_path =~ m~^//~ );
377
    Error( "Source Path has drive specifier" ) if ( $opt_path =~ m~^[A-Za-z]\:~ );
378
 
379
    #
380
    #   Extract the VOB from the path
381
    #
382
    unless ( $opt_vob )
383
    {
384
        my $vob = $opt_path;
385
        $vob =~ s~^/~~g;
386
        $vob =~ s~/.*~~g;
387
 
388
        $opt_vob = $vob;
389
        Verbose ("Extract VOB from path: $vob" );
390
    }
391
}
392
 
393
 
394
#
395
#   If the view currently exists then it will be deleted if allowed
396
#
397
delete_view()
299 dpurdie 398
    unless ( $opt_reuse );
263 dpurdie 399
 
299 dpurdie 400
 
263 dpurdie 401
#
402
#   If the user is simply deleting the view then all has been done
403
#
404
exit 0
405
    if ( $opt_delete );
406
 
407
#
408
#   Setup user specified VOB
409
#
410
if ( defined($opt_vob) )
411
{
412
    $ROOT_VOB = "/$opt_vob";
413
    $ROOT_VOB =~ s~//~/~g;
414
    @ROOT_VOBS = $ROOT_VOB;
415
}
416
else
417
{
418
    #
419
    #   Extend the list of ROOT_VOBS with all the known vobs
420
    #   The initial ROOT_VOBS are treated as a "hint" to assist searching
421
    #
422
        my $cmd = ClearToolCmd ('lsvob', '-short');
423
        open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
424
        while (<CMD>)
425
        {
426
            #
427
            #   Filter output from the user
428
            #
429
            chomp;
430
            s~^$UNIX_VOB_PREFIX~~ if ($UNIX);
431
            Verbose2("lsvob: $_");
432
            tr~\\/~/~s;
433
            push @ROOT_VOBS, $_;
434
        }
435
        close(CMD);
436
}
437
 
438
#
439
#   Ensure that the label is present within the specified VOB
440
#   Hunt for the user specified label in a number of well known VOBs
441
#
442
if ( @opt_spec )
443
{
444
    Verbose("Ensure Label is found in a VOB");
445
    my $found = 0;
446
    my $spec = $opt_spec[0];
447
    foreach my $vob ( @ROOT_VOBS )
448
    {
449
        $vob = $UNIX_VOB_PREFIX . $vob if ( $UNIX );
450
        (my $vob_name = $vob) =~ s~/~$VOB_SEP~g;
451
 
452
        Verbose2 ("Examine label $spec in vob: $vob" );
453
 
454
        my $cmd = ClearToolCmd ('lstype', "lbtype:$spec\@$vob_name");
455
        my $cmd_done = 0;
456
        open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
457
        while (<CMD>)
458
        {
459
            #
460
            #   Filter output from the user
461
            #   Stay in loop to avoid Broken Pipe message
462
            #
463
            chomp;
464
            Verbose2("lstype: $_");
465
            next if ( $cmd_done );
466
            next if ( m~Error~ );
467
            next unless ( m~label type~ );
468
            push @label_not_locked, $spec unless( m~\(locked\)~ );
469
            $label_count++;
470
            $found = $vob;
471
            $cmd_done = 1;
472
        }
473
        close(CMD);
474
        last if ( $found );
475
    }
476
 
2429 dpurdie 477
    Error ('ExitCode=11', "Label $spec not found in @ROOT_VOBS")
263 dpurdie 478
        unless ( $found );
479
    Verbose ("Label $spec found in vob: $found" );
480
 
481
    $ROOT_VOB = $found;
482
 
483
    #
484
    #   Create a VOB spec extension
485
    #
486
    $root_vob_spec = '@' . $ROOT_VOB;
487
    $root_vob_spec =~ s~/~$VOB_SEP~g;
488
 
489
    #
490
    #   Ensure that all labels are found in the VOB
491
    #
492
    foreach my $spec ( @opt_spec[1..$#opt_spec] )
493
    {
494
        $label_count++;
495
        Verbose ("Testing label $spec in vob: $ROOT_VOB" );
496
        my $data = qx( cleartool lstype lbtype:$spec$root_vob_spec );
497
        Verbose ( "lstype: $data" );
498
        Error ("Label $spec not found in $ROOT_VOB. All labels must be in the same VOB")
499
            if ( ! $data );
500
        push @label_not_locked, $spec unless( $data =~ m~\(locked\)~ );
501
    }
502
 
503
    #
504
    #   Ensure that the branch is found in the VOB
505
    #
506
    if ( $opt_branch )
507
    {
508
            Verbose ("Testing branch $opt_branch in vob: $ROOT_VOB" );
509
            my $data = qx( cleartool lstype brtype:$opt_branch$root_vob_spec );
510
            Verbose ( "lstype: $data" );
511
            Error ("Branch $opt_branch not found in $ROOT_VOB.")
512
                if ( ! $data );
513
    }
514
 
515
    #
516
    #   Lock the label(s)
517
    #
518
    if ( $opt_lock )
519
    {
520
        my @still_not_locked;
521
        Message( "Locking labels" );
522
        foreach my $spec ( @label_not_locked )
523
        {
524
            Verbose ("Locking $spec");
525
            push @label_locked, $spec;
526
            ClearCmd ('lock', "lbtype:$spec$root_vob_spec" );
527
            push @still_not_locked, $spec if ( @error_list );
528
        }
529
        @label_not_locked = @still_not_locked;
530
 
531
        #
532
        #   Register function to unlock all the locked lables on failure
533
        #
534
        ErrorConfig ('on_exit' => \&unlock_on_error );
535
        Error ("Not all labels locked: @label_not_locked") if ( @label_not_locked  );
536
    }
537
}
538
 
539
#
540
#   Create a new (static) view
541
#   Create a config spec and populate the view
542
#
543
if (! -d $VIEWDIR || ! $opt_reuse )
544
{
545
    Message( "Create the view" . ($GBE_SANDBOX ? " in a SANDBOX" : ""));
546
 
335 dpurdie 547
    my $view_comment = "ViewDir: $VIEWDIR";
548
    $view_comment .= " Created: " . localtime;
263 dpurdie 549
    #
550
    #   Tried creating a co-located view under Windows, but had problems
551
    #       1) Did not work on WindowsServer based build machine ??
552
    #       2) Deleting the view could be a problem if the user had
553
    #          files open in the view.
554
    #       3) Documentation doesn't really like the use of -colocated
555
    #
556
    foreach my $view_count ( 1 .. 5 )
557
    {
558
        my $cc_race_condition;
335 dpurdie 559
        my $cmd = ClearToolCmd ('mkview', '-snapshot', '-tag', $VIEWTAG, '-tcomment', $view_comment, $VIEWDIR);
263 dpurdie 560
        open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
321 dpurdie 561
        @error_list = ();
263 dpurdie 562
        while (<CMD>)
563
        {
564
            #
565
            #   Filter output from the user
566
            #
567
            chomp;
568
            tr~\\/~/~s;
321 dpurdie 569
            push @error_list, $_ if ( m~Error:~ );
263 dpurdie 570
            Verbose2("mkview: $_");
571
 
572
            #
573
            #   Detect Race condition
574
            #   Multiple build daemons creating views too fast for ClearCase
575
            #   ClearCase can hit a race condition and fail to create a view
576
            #
577
            if ( $_ =~ m~Error: Unable to create directory "[^"]+": File exists\.~ )
578
            {
579
                $cc_race_condition = 1;
580
            }
581
        }
582
        close(CMD);
583
 
584
        #
585
        #   Race condition detected
586
        #   Back-off and try again. Will only try a limited number of times
587
        #
588
        if ( $cc_race_condition  )
589
        {
590
            Message ("ClearCase Race condition detected");
591
            sleep ( $view_count );
592
            next;
593
        }
594
        last;
595
    }
321 dpurdie 596
    Error ("Cannot locate the created static view", @error_list)
263 dpurdie 597
        unless ( -d $VIEWDIR );
598
 
599
    #   In order to operate in this view (ie set the config spec, we need to
600
    #   be in the directory of the view
601
    #
602
    chdir ($VIEWDIR) or Error( "Cannot chdir to $VIEWDIR");
603
 
604
    #
605
    #   Create a local package archive
606
    #   May be needed for multipackage builds and it will prevent JATS from
607
    #   finding any outside the view
608
    #
609
    mkdir ( 'local_dpkg_archive')
610
        unless ($GBE_SANDBOX);
611
 
612
    my $config_file = $opt_config_spec;
613
    unless ( $config_file )
614
    {
615
        $config_file = create_config_spec ('config_spec.txt');
616
    }
617
 
618
    Message( "Populating the view");
381 dpurdie 619
    my $rv = ClearTool( 'setcs', '-tag', $VIEWTAG, $config_file );
263 dpurdie 620
}
621
 
269 dpurdie 622
#   Place a tag-file in the user-specified source path
623
#   This will be used by the build-tool to locate the 'source-path' of the
624
#   view, primarily for determining metrics.
263 dpurdie 625
#
269 dpurdie 626
#   Calculate where the dynmaic view will be
627
#   This differ between UNIX/WINDOWS
628
#
399 dpurdie 629
if ( $opt_path && $GBE_ABT && !$opt_extract_files)
269 dpurdie 630
{
631
    Message( "Create Build tagfile");
632
    my $cpath = $VIEWDIR . $VOB_PREFIX . $opt_path;
633
    if ( -d $cpath )
634
    {
635
        TouchFile ( "$cpath/.jats.packageroot" );
636
    }
637
}
638
 
639
#
379 dpurdie 640
#   If we are only extracting files then ...
641
#       Remove the viewtag
642
#       Remove view-specific files
643
#       Eliminate 'vobs' subdirectory and move items up
644
#
645
if ( $opt_extract_files )
646
{
647
 
381 dpurdie 648
    #
649
    #   Remove view tag - will be left with the view
650
    #
2931 dpurdie 651
    Verbose3 ("Remove the viewtag");
379 dpurdie 652
    chdir ( $user_cwd );
653
    ClearCmd ( 'rmview', '-force', '-tag', $VIEWTAG );
654
 
655
    #
656
    #   Remove view specific files
657
    #
381 dpurdie 658
    chdir ( $VIEWDIR ) || Error ("Cannot cd to $VIEWDIR");
379 dpurdie 659
    RmDirTree( 'local_dpkg_archive' );
660
    RmDirTree( '.view.dat' );
661
    foreach my $file ( glob ('update.*.updt') )
662
    {
663
        RmDirTree( $file );
664
    }
665
 
666
    #
381 dpurdie 667
    #   Ensure that the VOB root was extracted
668
    #
2429 dpurdie 669
    Error ('ExitCode=10', "Root directory not found: $VIEWDIR$ROOT_VOB")
381 dpurdie 670
        unless( -d $VIEWDIR . $ROOT_VOB );
2429 dpurdie 671
 
381 dpurdie 672
    #
2429 dpurdie 673
    #   Ensure some files were extracted
674
    #
675
    Error ('ExitCode=10', DisplayPath("View files in: $VIEWDIR, but no files were extracted"))
676
        unless ( $load_count );
677
 
678
 
679
    #
379 dpurdie 680
    #   If Unix based view, then get rid of the VOBS directory
681
    #
682
    if ( $UNIX )
683
    {
684
        foreach my $file ( glob ('vobs/*') )
685
        {
686
            my $target = $file;
687
            $target =~ s~^vobs/~~;
381 dpurdie 688
            rename $file, $target || Error ("Renaming $file. $!");
379 dpurdie 689
        }
690
 
381 dpurdie 691
        rmdir 'vobs' || Error ("Removing vobs directory from: $VIEWDIR");
379 dpurdie 692
    }
693
 
694
    Message DisplayPath("View files in: $VIEWDIR, Files: $load_count" );
695
    exit (0);
696
}
697
 
698
 
699
#
263 dpurdie 700
#   Locate the JATS build files within the populated view
701
#
702
chdir ($VIEWDIR) or Error( "Cannot chdir to $VIEWDIR");
703
Message( "Locating build files");
704
 
705
my $bscanner = BuildFileScanner( "$VIEWDIR$ROOT_VOB", 'build.pl', '--LocateAll' );
706
$bscanner->scan();
707
my @build_list = $bscanner->getInfo();
708
foreach my $be ( @build_list )
709
{
710
    Message( DisplayPath ("Build file: $be->{dir} Name: $be->{file}"));
711
}
712
 
713
#
714
#   If we are extracting the view then we are done
715
#   Display useful information for the user
716
#
717
if ( $opt_extract )
718
{
719
    Message  DisplayPath "View in: $VIEWDIR";
720
    Warning ("No build files found" )   if ( $#build_list < 0 );
721
    Warning( "Multiple build files found" )if ( $#build_list > 0 );
722
    Message ("Not all labels are locked") if ( @label_not_locked  );
723
    Message ("All labels are locked") unless ( @label_not_locked  );
724
    Message ("Development Sandbox") if ( $GBE_SANDBOX );
725
 
726
    exit 0;
727
}
728
 
729
Error ("No build files found")  if ( $#build_list < 0 );
730
 
731
#
732
#   Determine the list of builds to perform
733
#   Ensure that the user-requested build files are present
734
#
735
#   The user specifies the build file, via the mangled package name
736
#   This is package_name . project extension (daf_utils.cr)
737
#
738
if ( $#opt_build  >= 0)
739
{
740
    Verbose( "Check and locate the build files");
741
    @build_list = ();
742
    foreach my $bentry ( @opt_build )
743
    {
744
        if ($bscanner->match( $bentry) )
745
        {
746
            UniquePush (\@build_list, $bscanner->getMatchList() );
747
            Verbose ("Found: $bentry");
748
        }
749
        else
750
        {
751
            Error ("Cannot locate requested build files for: $bentry")
752
        }
753
    }
754
}
755
 
756
#
757
#   Sanity test if we will transfer the generated package to dpkg_archive
758
#   There are some limits
759
#       1) Must have built from one label
760
#       2) That label must be locked
761
#       3) Only one build file
762
#       4) The view must not have been reused
763
#       5) The view has a branch rule
764
#       6) Building from a config spec
765
#       7) Cannot release from a sandbox
766
#
767
my @elist;
768
push @elist, "Package built from multiple labels" unless ( $label_count == 1 || $opt_config_spec );
769
push @elist, "Package built from an unlocked label" if ( @label_not_locked  );
770
push @elist, "Package built with multiple build files" if ( scalar @build_list > 1 );
771
push @elist, "Package from a reused view" if ( $opt_reuse && ! $opt_beta );
772
push @elist, "Package from a development sandbox" if ( $GBE_SANDBOX );
773
push @elist, "View contains a branch" if ( $opt_branch );
774
push @elist, "Package based on a config spec" if ( $opt_config_spec );
775
push @elist, "User has specified build files" if ( $#opt_build > 0 );
776
 
777
if ( @elist )
778
{
779
    Warning ("Cannot officially release the package.", @elist);
780
    Error ("Build terminated as it cannot be released") if ($opt_dpkg && ! $opt_beta);
781
}
782
Warning ("Beta Release") if $opt_beta;
783
 
784
#
785
#   Process each of the build files in the specified order
786
#
787
foreach my $be (@build_list)
788
{
789
 
790
    #
791
    #   We need to change to the build directory
792
    #   Moreover we need the local name of the build directory.
793
    #   Windows does not handle a UNC pathname to well (at all)
794
    #
795
    my $build_dir = $be->{dir};
796
    chdir ("$build_dir") or Error( "Cannot chdir to build directory: $build_dir");
797
 
798
    if ( $be->{file} =~ m/^build.pl$/ )
799
    {
800
        Message ("Using JATS: $build_dir");
801
        #
802
        #   Invoke JATS to build the package and make the package
803
        #
804
        my @build_args = qw(--expert --cache);
805
        push @build_args, '--cache' if $opt_cache;
806
 
807
        my $make_type = 'all';
808
        $make_type = 'all_prod'  if ( $opt_prod_build );
809
        $make_type = 'all_debug' if ( $opt_debug_build );
810
 
811
 
812
        JatsCmd('build', @build_args)               and Error("Package did not build");
813
        JatsCmd('make', $make_type, 'NODEPEND=1')   and Error("Package did not make");
814
        JatsCmd('install');
815
 
816
        if ( $opt_runtests )
817
        {
321 dpurdie 818
            JatsCmd('make', 'run_unit_tests')      and Error("Tests did not run correctly");
263 dpurdie 819
        }
820
    }
821
    else
822
    {
823
        #
824
        #   Ant build files
825
        #
826
        my $pname =  $be->{file};
827
        Message ("Using ANT: $build_dir, $pname");
828
        $pname =~ s~depends.xml$~.xml~;
829
        copy($be->{file}, "auto.xml");
830
        JatsCmd('-buildfile', $pname, 'ant', 'build')        and Error("Package did not build");
831
        JatsCmd('-buildfile', $pname, 'ant', 'make_package') and Error("Package did not make_package");
832
    }
833
}
834
 
835
#
836
#   Copy the generated packages
837
#       1) dpkg_archive
838
#       2) Users local directory
839
#
840
foreach my $be (@build_list)
841
{
842
    my $build_dir = $be->{dir};
843
    chdir ("$build_dir") or Error( "Cannot chdir to build directory: $build_dir");
844
    if ( $opt_dpkg )
845
    {
846
        Message ("Using: $build_dir");
279 dpurdie 847
        my @create_opts = "-o";
848
        push @create_opts ,"-m" if ( $opt_merge );
849
        JatsCmd('-here', 'create_dpkg', @create_opts, '-pname', $be->{name}, '-pversion', $be->{version}) and $error++;
263 dpurdie 850
    }
851
 
852
    if ( $opt_copy )
853
    {
854
        Message ("Copy package to $user_cwd");
855
        copy_directory( 'pkg', $user_cwd, '' );
856
    }
857
 
858
    #
859
    #   Test structure of the package
860
    #   Ensure that it has a descpkg file
861
    #   Validate the package name and version
862
    #   More important for ANT projects than JATS as JATS has a sanity test
863
    #
864
    if ( $opt_test )
865
    {
866
        JatsCmd('-here', 'create_dpkg', '-test', '-pname', $be->{name}, '-pversion', $be->{version}) and $error++;
867
    }
868
 
869
}
870
Error ("Package not transferred")
871
    if ( $error );
872
 
873
 
874
#
875
#   Delete the view
876
#
877
if ( ! $opt_reuse && ! $error && ! $opt_keep )
878
{
879
    delete_view();
880
}
881
else
882
{
883
    Message( "View left in: $VIEWDIR" );
884
}
885
 
886
Message ("End program");
887
exit 0;
888
 
889
#-------------------------------------------------------------------------------
890
# Function        : delete_view
891
#
892
# Description     : Delete a view
893
#
894
# Inputs          : None
895
#                   $VIEWTAG - name of the view
896
#                   $VIEWDIR - path of the view
897
#
898
# Returns         :
899
#
900
sub delete_view
901
{
902
    my $cofound = 0;
903
    my $uuid;
904
 
905
    #
299 dpurdie 906
    #   Simple delete
263 dpurdie 907
    #
299 dpurdie 908
    if ( $opt_extract_files )
263 dpurdie 909
    {
299 dpurdie 910
        if ( -d $VIEWDIR )
911
        {
912
            Message("Remove extracted files: $VIEWTAG");
361 dpurdie 913
            RmDirTree( $VIEWDIR );
299 dpurdie 914
        }
915
    }
916
    else
917
    {
263 dpurdie 918
        #
299 dpurdie 919
        #   If the view physically exists then attempt to phyically remove it
263 dpurdie 920
        #
299 dpurdie 921
        if ( -d $VIEWDIR )
922
        {
923
            #
924
            #   Determine if there are any checked out files in the view
925
            #
926
            Message("Remove the view: $VIEWTAG");
927
            Verbose("Look for checked out files");
263 dpurdie 928
 
299 dpurdie 929
            chdir ( $VIEWDIR );
930
            foreach my $file ( glob ('*') )
263 dpurdie 931
            {
299 dpurdie 932
                next if ( $file =~ m~local_dpkg_archive~ );
933
                next if ( $file =~ m~^view\.~ );
934
                if ( -d $file )
935
                {
936
                    Verbose ("Examine $file for checked out files");
937
                    chdir "$VIEWDIR/$file";
263 dpurdie 938
 
299 dpurdie 939
                    my $cmd = ClearToolCmd('lsco', '-cview', '-rec' );
940
                    open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
941
                    while (<CMD>)
263 dpurdie 942
                    {
299 dpurdie 943
                        #
944
                        #   Filter output from the user
945
                        #
946
                        chomp;
947
                        Verbose("lsco: $_");
948
                        if ( m~checkout version~ )
949
                        {
950
                            $cofound++ ;
951
                            Warning ("Checked out file: $_");
952
                        }
263 dpurdie 953
                    }
299 dpurdie 954
                    close(CMD);
263 dpurdie 955
                }
956
            }
957
 
299 dpurdie 958
            Error ("Will not delete view. Checked out files exist")
959
                if ( $cofound );
263 dpurdie 960
 
299 dpurdie 961
            #
962
            #   Get out of the view
963
            #   Cannot delete the view if we are in it.
964
            #
965
            chdir ( $user_cwd );
263 dpurdie 966
 
299 dpurdie 967
            #
968
            #   Static views should be removed by dirname, not by tag
969
            #
970
            ClearTool( 'rmview', $VIEWDIR );
263 dpurdie 971
 
299 dpurdie 972
            #
973
            #   Now try to delete the directory
974
            #
361 dpurdie 975
            RmDirTree( $VIEWDIR );
299 dpurdie 976
        }
263 dpurdie 977
 
978
        #
299 dpurdie 979
        #   If the view tag still exists then delete the view the hard way
980
        #   Use 'lsview' to locate the views uuid
263 dpurdie 981
        #
299 dpurdie 982
        Verbose("Look for View Tag");
983
        my $cmd = ClearToolCmd ('lsview', '-long', $VIEWTAG );
984
        open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
985
        while (<CMD>)
986
        {
987
            #
988
            #   Filter output from the user
989
            #
990
            chomp;
991
            Verbose("lsview: $_");
992
            $uuid = $1 if ( m~^View uuid:\s+(.*)~ );
993
        }
994
        close(CMD);
995
        if ( $uuid )
996
        {
997
            Warning ("Deleting view - the hard way");
998
            ClearTool( '--Quiet', 'rmview', '-force', '-all', '-uuid', $uuid );
999
            ClearTool( '--Quiet', 'unregister', '-view', '-uuid', $uuid );
1000
            ClearTool( '--Quiet', 'rmtag','-view', '-all', $VIEWTAG );
1001
        }
263 dpurdie 1002
    }
1003
 
1004
    Error ("View was not deleted")
1005
        if ( -d $VIEWDIR );
1006
}
1007
 
1008
#-------------------------------------------------------------------------------
1009
# Function        : copy_directory
1010
#
1011
# Description     : Copy a directory tree
1012
#
1013
# Inputs          : Source directory
1014
#                   Target directory
1015
#                   Strip
1016
#
1017
#                   Should be full pathnames
1018
#
1019
# Returns         :
1020
#
1021
my $copy_error;
1022
my $copy_count;
1023
sub copy_directory
1024
{
1025
    our ($src_dir, $dest_dir, $strip) = @_;
1026
    our $slength = length ($strip);
1027
 
1028
    #
1029
    #   Prevent File::Find from generating warnings
1030
    #
1031
    no warnings 'File::Find';
1032
 
1033
 
1034
    #
1035
    #   Helper routine to copy files
1036
    #
1037
    sub copy_file_wanted
1038
    {
1039
        #
1040
        #   Do not copy directories
1041
        #   Just make the directory entry. May result in empty directories
1042
        #
1043
        if ( -d $_ )
1044
        {
1045
            my $tdir = "$dest_dir/" . substr( $File::Find::dir, $slength);
1046
            $tdir .= "/$_";
1047
            File::Path::mkpath( $tdir )
1048
                unless ( -d $tdir);
1049
            return;
1050
        }
1051
 
1052
        #
1053
        #   When used to copy file from within a clearcase dynamic view the
1054
        #   files may not actually exist. This will generate an error later
1055
        #   so check for existance of file file now.
1056
        #
1057
        return unless ( -e $_ );
1058
 
1059
        #
1060
        #   Have been chdir'ed to the source directory
1061
        #   when invoked
1062
        #
1063
        my $tdir = "$dest_dir/" . substr( $File::Find::dir, $slength);
1064
        my $tfile = "$tdir/$_";
1065
        my $sfile = "$File::Find::dir/$_";
1066
        Verbose ("Copy: $sfile -> $tfile");
1067
 
1068
        File::Path::mkpath( $tdir )
1069
            unless ( -d $tdir);
1070
 
1071
        unlink ( $tfile )
1072
            if ( -f $tfile );
1073
 
1074
        if( ! File::Copy::copy ( $_ , $tfile ) )
1075
        {
1076
            $copy_error++;
1077
            Message "Error copying $sfile";
1078
        }
1079
        else
1080
        {
1081
            my $perm = (stat $_)[2] & 07777;
1082
            chmod($perm, $tfile);
1083
 
1084
            $copy_count++;
1085
        }
1086
    }
1087
 
1088
    #
1089
    #   Locate all files to copy
1090
    #
1091
    $copy_error = 0;
1092
    $copy_count = 0;
1093
    File::Find::find ( \&copy_file_wanted, $src_dir );
1094
    return $copy_error;
1095
}
1096
 
1097
#-------------------------------------------------------------------------------
1098
# Function        : ClearTool
1099
#
1100
# Description     : Issue a cleartool command
1101
#                   Filter out many of the stupid messages
1102
#
1103
# Inputs          : Options and Command line
1104
#                   Options:
1105
#                       --Quiet     - Supress all command output
1106
#
1107
# Returns         : Error code
1108
#
1109
sub ClearTool
1110
{
1111
    my $quiet;
379 dpurdie 1112
    $load_count = 0;
263 dpurdie 1113
 
1114
    #
1115
    #   Scan for initial options
1116
    #       --Quiet
1117
    #
1118
    if ( $_[0] eq '--Quiet' )
1119
    {
1120
        $quiet = 1;
1121
        shift;
1122
    }
1123
 
1124
    my $cmd = ClearToolCmd(@_);
1125
    open(CMD, "$cmd 2>&1 |") || Error "can't run command: $!";
1126
    while (<CMD>)
1127
    {
1128
        #
1129
        #   Filter output from the user
1130
        #
379 dpurdie 1131
        $load_count++ if ( m'Loading ' );
263 dpurdie 1132
        next if ( $quiet );
379 dpurdie 1133
        if ( $opt_extract_files )
1134
        {
1135
            next if ( m'Loading ' );
1136
            next if ( m'Done loading ' );
1137
            next if ( m'Log has been written to ' );
1138
        }
263 dpurdie 1139
        unless ( $opt_verbose )
1140
        {
1141
            next if ( m~Making dir~ );
1142
            next if ( m~End dir~ );
1143
            next if ( m~Processing dir~ );
1144
            next if ( m~Error~ );
1145
        }
1146
        print $_;
1147
    }
1148
    close(CMD);
1149
 
1150
    Verbose2 "ClearTool Exit Status: $?";
1151
    return $? / 256;
1152
}
1153
 
1154
#-------------------------------------------------------------------------------
1155
# Function        : ClearCmd
1156
#
1157
# Description     : Execute a cleartool command
1158
#                   Capture error messages only
1159
#
1160
# Inputs          : Command to execute
1161
#                   Takes an array of command argumeents and will quote them
1162
#
1163
# Returns         : Exit code
1164
#                   Also the global @error_list
1165
#
1166
sub ClearCmd
1167
{
1168
    @error_list = ();
1169
 
1170
    my $cmd = ClearToolCmd(@_);
1171
    open(CMD, "$cmd  2>&1 |")    || Error "can't run command: $!";
1172
    while (<CMD>)
1173
    {
1174
        chomp;
1175
        Verbose ($_);
1176
        push @error_list, $_ if ( m~Error:~ );
1177
    }
1178
    close(CMD);
1179
 
1180
    Verbose2 "Exit Status: $?";
1181
    return $? / 256;
1182
}
1183
 
1184
#-------------------------------------------------------------------------------
1185
# Function        : ClearToolCmd
1186
#
1187
# Description     : Create a nice escaped cleartool command
1188
#
1189
# Inputs          : An array of cleartool command line arguments
1190
#
1191
# Returns         : A string that has been quoted
1192
#
1193
sub ClearToolCmd
1194
{
1195
    my $cmd = 'cleartool ' . QuoteCommand( @_);
1196
    Verbose2 $cmd;
1197
    return $cmd;
1198
}
1199
 
1200
#-------------------------------------------------------------------------------
1201
# Function        : unlock_on_error
1202
#
1203
# Description     : Error cleanup function.
1204
#                   Called by the error processing
1205
#                   Called to unlock all labels that have been locked by this
1206
#                   utility
1207
#
1208
# Inputs          : @label_locked           - Labels locked by this utility (Global)
1209
#
1210
# Returns         : 
1211
#
1212
sub unlock_on_error
1213
{
1214
    my @still_locked;
1215
    Message( "Releasing Locked labels" );
1216
    foreach my $spec ( @label_locked )
1217
    {
1218
        Verbose ("Unlocking:$spec");
1219
        ClearCmd ('unlock', "lbtype:$spec$root_vob_spec" );
1220
        push @still_locked, $spec if ( @error_list );
1221
    }
1222
    Error ("Not all labels unlocked: @still_locked") if ( @still_locked  );
1223
}
1224
 
1225
#-------------------------------------------------------------------------------
1226
# Function        : create_config_spec
1227
#
1228
# Description     : Creates a config spec
1229
#
1230
# Inputs          : $config     - Path to the config file
1231
#
1232
# Returns         : Path to the config spec
1233
#
1234
sub create_config_spec
1235
{
1236
    my ($config_file) = @_;
363 dpurdie 1237
 
263 dpurdie 1238
    #
363 dpurdie 1239
    #   Calc the path to a directory in the view which we really want to
1240
    #   consider as the base. Only want to see folders above this base.
1241
    #   Don't want to add elements above the base
1242
    #
1243
    my $basepath = ($opt_path) ? "\"${VOB_PREFIX}${opt_path}\""     : $ROOT_VOB;
1244
    my $elroot   = ($opt_path) ? "\"${VOB_PREFIX}${opt_path}/...\"" : '*';
369 dpurdie 1245
    my $elpath   = ($opt_path) ? $opt_path : '';
363 dpurdie 1246
 
1247
    #
263 dpurdie 1248
    #   Create a config spec to be used to populate the view
1249
    #       Do not branch directories
1250
    #       Do not extract files from lost+found
1251
    #
1252
    Verbose( "Create config spec");
1253
    my @config;
1254
    push @config, "element * CHECKEDOUT";
1255
    push @config, "element .../lost+found -none";
363 dpurdie 1256
 
1257
    #
1258
    #   Insert rules to prevent branching above the load path
1259
    #   This will be the root of the package
1260
    #
1261
    if ( $opt_path )
1262
    {
1263
        my $fulldir = $VOB_PREFIX;
1264
        my @parts = split ('/', $opt_path);
1265
        shift @parts;                                   # Skip first as its empty
1266
        pop @parts;                                     # Skip last as its the package
1267
        foreach my $dir ( @parts )
1268
        {
1269
            $fulldir .= "/$dir";
1270
            foreach (@opt_spec)
1271
            {
1272
                push @config, "element -dir \"$fulldir\" $_ -nocheckout";
1273
            }
1274
        }
1275
    }
1276
    else
1277
    {
1278
        foreach (@opt_spec)
1279
        {
1280
            push @config, "element -dir \"$ROOT_VOB\" $_ -nocheckout";
1281
        }
1282
    }
1283
 
1284
    #
1285
    #   General branching rules
1286
    #   Rule will apply to all following directives
1287
    #
1288
    if ( $opt_branch )
1289
    {
1290
        push @config, "element $elroot .../$opt_branch/LATEST";
1291
        push @config, "mkbranch $opt_branch";
1292
    }
1293
 
1294
    #
1295
    #   Rules to extract elements within the load path
1296
    #
263 dpurdie 1297
    foreach (@opt_spec)
1298
    {
363 dpurdie 1299
        push @config, "element $elroot $_";
263 dpurdie 1300
    }
1301
 
1302
    #
363 dpurdie 1303
    #   KLUDGE ALERT
263 dpurdie 1304
    #   Packages SHOULD be labled to the root.
1305
    #   Do not extend this list fix the package - fix the labels in the VOB.
1306
    #
1307
    if ( $opt_latest_root )
1308
    {
363 dpurdie 1309
        push @config, "element -dir $ROOT_VOB .../$opt_latest_root/LATEST";
1310
        push @config, "element -dir $ROOT_VOB .../mass_dev2/LATEST";
1311
        push @config, "element -dir $ROOT_VOB .../mass_dev/LATEST";
1312
        push @config, "element -dir $ROOT_VOB /main/LATEST";
263 dpurdie 1313
    }
1314
 
1315
    #
363 dpurdie 1316
    #   Handle file(directory) addition
1317
    #   Need a rule to allow /main/0 to be visible
1318
    #   Need to ensure that we don't "see" the entire VOB, just below the load path
263 dpurdie 1319
    #
379 dpurdie 1320
    unless ($GBE_ABT || $opt_extract_files)
263 dpurdie 1321
    {
363 dpurdie 1322
        #
1323
        #   Ensure that we have more than just the VOB root
1324
        #   If we only have the VOB root then we will get all top level entries
1325
        #   in the vob - and this is not good.
1326
        #
1327
        #   Comment out the rule so that the user can use if they must
1328
        #
369 dpurdie 1329
        my $count = ($elpath =~ tr~/~~);
1330
        my $prefix = ( $count <= 1 ) ? '# ' : '';
1331
        Verbose2 ("Config Spec: Suppress /main/0. Path too short)") if $prefix;
363 dpurdie 1332
        #
1333
        #   Ensure that element-0 is visible (unless autobuilder)
1334
        #   Note: mkbranch rule will modify this rule
1335
        #
1336
        push @config, $prefix . "element $elroot /main/0";
263 dpurdie 1337
    }
1338
 
1339
    #
1340
    #   Load rule
1341
    #   Quote the path so that spaces will be correcly handled
1342
    #
363 dpurdie 1343
    push @config, "load $basepath";
263 dpurdie 1344
 
369 dpurdie 1345
    Message ("Config Spec", @config )
1346
        if ( IsVerbose(1) );
363 dpurdie 1347
 
263 dpurdie 1348
    FileCreate ($config_file, \@config);
1349
    return $config_file;
1350
}
1351
 
1352
#-------------------------------------------------------------------------------
1353
#   Documentation
1354
#
1355
 
1356
=pod
1357
 
361 dpurdie 1358
=for htmltoc    GENERAL::ClearCase::
1359
 
263 dpurdie 1360
=head1 NAME
1361
 
1362
jats_ccrelease - Build a package given a clearcase label
1363
 
1364
=head1 SYNOPSIS
1365
 
1366
  jats ccrelease [options] [-label=]label | -config=config_spec
1367
 
1368
 Options:
1369
    -help              - brief help message
1370
    -help -help        - Detailed help message
1371
    -man               - Full documentation
1372
    -label=xxx         - Clearcase label
1373
    -spec=xxx          - Same as -label=xxx
1374
    -path=xxx          - Source Path
1375
    -view=xxx          - Modify the name of the created view
1376
    -vob=vobname       - VOB name
1377
    -build=xxx         - Package Name to build
1378
    -root=xxx          - Root directory for generated view
1379
    -latestroot=xxx    - Use the LATEST rootlevel directory 'xxx'
1380
    -[mk]branch=xxx    - Will create a view with a branch rule
1381
    -config=xxx        - Create a view with the provided config spec
1382
    -tag=xxx           - Alternate tag used with in the ViewTag
1383
    -extract           - Extract the view and exit
1384
    -extractfiles      - Extract files, without a view
1385
    -cache             - Refresh local dpkg_archive cache
1386
    -delete            - Remove any existing view and exit
1387
    -debugOnly         - Make only the debug version
1388
    -prodOnly          - Make only the production version
1389
    -[no]dpkg          - Transfer package into dpkg_archive
1390
    -[no]copy          - Transfer pkg directory to the current user directory
1391
    -[no]reuse         - Reuse the view
1392
    -[no]test          - Test package build. Implies nocopy and nodpkg
1393
    -[no]keep          - Keep the view after the build
1394
    -[no]lock          - Lock labels
1395
    -[no]beta          - Release a beta package
1396
    -[no]merge         - Merge packages into dpkg_archive
1397
    -[no]runtests      - Run units tests. Default is runtests
1398
    -[no]prefix        - Supress user prefix in view name. Default prefix is USER
1399
 
1400
=head1 OPTIONS
1401
 
1402
=over 8
1403
 
1404
=item B<-help>
1405
 
1406
Print a brief help message and exits.
1407
 
1408
=item B<-help -help>
1409
 
1410
Print a detailed help message with an explanation for each option.
1411
 
1412
=item B<-man>
1413
 
1414
Prints the manual page and exits.
1415
 
1416
=item B<-label> or B<-spec>
1417
 
1418
The ClearCase label to use as the base for the view.
1419
 
1420
Eg: daf_utils_math_3.2.1
1421
 
1422
=item B<-view name>
1423
 
1424
Specified an alternate view name and tag to be used. This option does not provide the
1425
full name of the view.
1426
 
361 dpurdie 1427
The view tag will be : "${USER}_${MACHINENAME}_${TAG}_${NAME}"
263 dpurdie 1428
 
361 dpurdie 1429
The view path will be: "${USER}_${NAME}"
1430
 
263 dpurdie 1431
The default "NAME" is the first label specified.
1432
The default "TAG" is build. See B<-tag=tagname>.
1433
 
1434
If the user provides a view "name" that is prefixed with their user name
1435
('${USER}_'), then the username will be stripped of for internal processing.
1436
This allows a user to provide a view path when deleting a view.
1437
 
1438
=item B<-path=xxx>
1439
 
1440
Specifies the source path to the root of the extracted file tree. This option has several uses:
1441
 
1442
=over 8
1443
 
1444
=item   *
1445
 
1446
Provide a sanity test of the "Source Path" item within Release Manager
1447
 
1448
=item   *
1449
 
1450
Specify the VOB that contains the source. The VOB name will be extracted and
1451
used as the B<-vob> parameter.
1452
 
1453
=item   *
1454
 
1455
Limit the work to do in extracting the file tree.
1456
 
1457
=back
1458
 
1459
=item B<-vob=xxx>
1460
 
1461
Specifies the Clearcase VOB in which the clearcase label will be located.
1462
This is used as the basis for locating and loading the files within the view.
1463
 
1464
By default this utility will examine all the VOBs for the label.
1465
 
1466
=item B<-build=xxx>
1467
 
1468
This option allows the user to specify the packages to be built and the
1469
order in which the packages are to be built.
1470
This is useful if the extracted view contains multiple build files
1471
 
1472
This option may be used multiple times.
1473
 
1474
There are two forms in which the build target can be specified. It can be
1475
specified as a full package name and vesrion, or as a package name and the
1476
project suffix.
1477
 
1478
By default the program will assume that there is only one build file in the
1479
view and will not build if multiple files are present, unless the package to be
1480
built can be resolved.
1481
 
1482
The location mechanism operates for both JATS and ANT build files.
1483
 
1484
Example: -build=jats-api.1.0.0000.cr
1485
 
1486
This will locate the build file that builds version 1.0.0000.cr of the jats-api
1487
package. The version numbers must match exactly.
1488
 
1489
Example: -build=jats-api.cr -build=jats-lib.cr
1490
 
1491
This will located the build files that build the jats_api (cr) package and the
1492
jats-lib (cr) package. The version of the packages will not be considered.
1493
 
1494
=item B<-root=xxx>
1495
 
1496
This option allows the location of the generated view to be specified on the
343 dpurdie 1497
command line. It overides the value of GBE_VIEWBASE.
263 dpurdie 1498
 
1499
If the comamnd is invoked within a development sandbox, then the default
1500
location will be the root directory of the development sandbox.
1501
 
1502
=item B<-latestroot=xxx>
1503
 
1504
This option enables a work around for a bad-labelling practice that has existed
1505
in the past. This LATEST version of the named (xxx) branch will be added to
1506
the config spec used to create the view.
1507
 
1508
This is a work around for a problem where the top-level directory in the VOB has
1509
not been labelled. This can result in unreproducible builds.
1510
 
1511
This option allows the utility to construct a view, but the user SHOULD label
1512
the root level directory to correct the problem.
1513
 
1514
The use of this switch will add the following lines to the config spec:
1515
 
1516
    element -directory /DPG_SWBase /main/xxxx/LATEST
1517
 
1518
=item B<-branch=xxx or -mkbranch=xxx>
1519
 
1520
This option will create a view such that files that are checked out will be
1521
checked out on the named branch. This is intended to facilitate the maintenance
1522
of existing packages - the creation of a patch.
1523
 
1524
The named branch must exist within the VOB containing the label. The script will
1525
check for its existence.
1526
 
1527
The use of this switch will add the following lines to the config spec:
1528
 
1529
    element * .../xxx/LATEST
361 dpurdie 1530
    element * label -mkbranch xxx
263 dpurdie 1531
    element * /main/0 -mkbranch xxx
1532
 
1533
=item B<-config=config_spec>
1534
 
1535
This option is an alternate mechanism to create a static view. The view will be
1536
based on the provided configuration spec. This view cannot be used to release a package.
1537
The option is intended to simplify development.
1538
 
1539
This option is incompatibale with:
1540
 
1541
    -release
1542
    -label
1543
    -branch
1544
    -path
1545
    -vob
1546
 
1547
=item B<-tag=text>
1548
 
1549
This option alters the ClearCase view tag created for the view. It allows
1550
the creation of multiple views based on the same label. Intended to be used in
1551
the automated build system to create unique views tags.
1552
 
1553
The default tag is 'build'.
1554
 
1555
=item B<-extract>
1556
 
1557
With this option the view is created and the left in place. The user may then
1558
access the files within the view. The view should not be used for a
1559
production release.
1560
 
1561
=item B<-extractfiles>
1562
 
1563
With this option the utility will create a dynamic view and transfer files from
1564
the view to the user's tararget. The dynamic view is then removed.
1565
 
1566
This command is intended to simplify the process of creating an escrow.
1567
 
1568
=item B<-cache>
1569
 
1570
Forces external packages to be placed in the local dpkg_archive cache.
1571
 
1572
The normal operation is to copy the packages, only if they do not already exist
1573
in the local cache. This option may be used to ensure that the local copy is
1574
correct and up to date.
1575
 
1576
=item B<-delete>
1577
 
1578
Delete the view used by the program, if it exists. This option may be used to
1579
cleanup after an error.
1580
 
1581
Note: Ensure that no files are open in the view and that the users current
1582
working directory is not in the view as these will prevent the view from being
1583
deleted.
1584
 
1585
=item B<-debugOnly>
1586
 
1587
Make only the debug version of the package. The default it to create both the
1588
debug and production version of the package. The type of build may be  further
1589
limited by options within the package.
1590
 
1591
=item B<-prodOnly>
1592
 
1593
Make only the production version of the package. The default it to create both the
1594
debug and production version of the package. The type of build may be  further
1595
limited by options within the package.
1596
 
1597
=item B<-[no]dpkg>
1598
 
1599
Copy the generated package into dpkg_archive. This is the default mode of
1600
operation.
1601
 
1602
=item B<-[no]copy>
1603
 
1604
Copy the built "pkg" directory to the users current directory. The entire
1605
"pkg" subdirectory includes the full package named directory for the package
1606
that has been built.
1607
 
1608
=item B<-[no]reuse>
1609
 
1610
This flag allows the view created by the program to be re-used.
1611
 
1612
=over 8
1613
 
361 dpurdie 1614
=item *
263 dpurdie 1615
 
361 dpurdie 1616
The view is not deleted before being populated.
263 dpurdie 1617
 
361 dpurdie 1618
=item *
263 dpurdie 1619
 
361 dpurdie 1620
The view will not be populated if it does exist.
1621
 
1622
=item *
1623
 
1624
The view will not be deleted at the end the process.
1625
 
263 dpurdie 1626
=back
1627
 
1628
This option is useful for debugging a build process.
1629
 
1630
=item B<-[no]test>
1631
 
1632
Test the building of the package. This option implies "nocopy" and "nodpkg".
1633
 
1634
=item B<-[no]keep>
1635
 
1636
Keep the clearcase view after the build. The default option is "nokeep"
1637
 
1638
This option is different to the "reuse" in that the view will be deleted, if
1639
it exists, before the build, but will be retained at the completion of the
1640
process. The user may then manually extract the created package.
1641
 
1642
The view may be deleted with the the "delete" option; taking care to ensure that
1643
no files are open in the view and that the users current working directory is
1644
not in the view.
1645
 
1646
=item B<-[no]lock>
1647
 
1648
Lock any unlocked labels before attempting the build. This operation may be used
1649
to ensure that a release build does not fail due to the labels not being locked.
1650
The label is locked before the view is constructed and populated.
1651
 
1652
This operation may fail if the user does not "own" the label.
1653
 
1654
=item B<-[no]beta>
1655
 
1656
This option overrides many of the package release tests to allow a beta package
1657
to be released.
1658
 
1659
=item B<-[no]merge>
1660
 
1661
This option will merge packages being built on multiple machines into
1662
dpkg_archive. By default, if a package already exists in the archive it will be
1663
deleted and replaced. With this option the package will be merged. The merge
1664
process does not over write files found in the archive.
1665
 
1666
=item B<-[no]runtests>
1667
 
1668
This option will allow the suppression of the running of the unit tests included
1669
with the component. By default the tests are run. This can be suppressed
1670
without affecting the release process.
1671
 
1672
=back
1673
 
1674
=head1 DESCRIPTION
1675
 
1676
This program is the primary tool for the creation, recreation and release of
1677
packages within the B<ERG> build environment, although the program can perform a
1678
number of very useful operations required during normal development and
1679
maintenance.
1680
 
1681
This program will build a system containing one or more inter-related build
1682
files using the JATS build tools.
1683
 
1684
In normal operation the program will:
1685
 
1686
=over 8
1687
 
1688
=item Remove View
1689
 
1690
Remove any existing view of the same name. The view will not be removed if it
1691
contains checked-out files.
1692
 
1693
The view removal may fail if there are any files B<open> within the view or if
1694
any shell has a subdirectory of the view set as a B<current working directory>.
1695
 
1696
=item Locate VOB
1697
 
1698
Locate the VOB that contains the specified label or labels. If multiple labels
1699
are specified they must all exist in the same VOB.
1700
 
1701
=item Lock Labels
1702
 
1703
Lock any unlocked labels, if required.
1704
 
1705
=item Create the view
1706
 
1707
Create a static view to containing the files describes by the Clearcase
1708
label being processed.
1709
 
1710
The program uses a fixed view name. If this view exists then item
1711
will be deleted before item is created again. Each build starts in a clean view.
1712
 
1713
=item Populate the View
1714
 
1715
Loads files into the static view. The user label and the VOB name are used to
1716
created a clearcase configuration specification. This configuration
1717
specification is then activated and all files within the specified VOB will be
1718
loaded into the view if they match the user supplied label.
1719
 
1720
This processed normally results in a lot of error messages that can be ignored.
1721
 
1722
I<Note:> The label placed on the component to be built must extend to the
1723
root of the VOB, otherwise the directory path will not be extracted nor will
1724
the files within the component.
1725
 
1726
I<Note:> If the view is simply being extracted, then this is the end of the
1727
program. The extracted view is left in place.
1728
 
1729
=item Sanity Test
1730
 
1731
If the build is being used as a release into dpkg_archive then
1732
various tests are performed to ensure the repeatability of the view and the
1733
build. These tests include:
1734
 
1735
=over 8
1736
 
361 dpurdie 1737
=item   *
263 dpurdie 1738
 
361 dpurdie 1739
The view must be constructed from one label
263 dpurdie 1740
 
361 dpurdie 1741
=item   *
263 dpurdie 1742
 
361 dpurdie 1743
That label must be locked
263 dpurdie 1744
 
361 dpurdie 1745
=item   *
1746
 
1747
The labelled view must contain exactly one build file
1748
 
1749
=item   *
1750
 
1751
The view cannot have been re-used.
1752
 
263 dpurdie 1753
=back
1754
 
1755
=item Locate build files
1756
 
1757
Locate the build file within the view.
1758
 
1759
It is an error to have multiple build files within the view, unless the
1760
B<-build> option is used. By default, only one package will be built.
1761
 
1762
=item Package the results
1763
 
1764
Use JATS to build and make the package.
1765
 
1766
The resultant package may be copied to a numbers of locations. These include
1767
 
1768
=over 8
1769
 
1770
=item 1
1771
 
1772
The master dpkg_archive as an official release. This is the default operation.
1773
 
1774
=item 2
1775
 
1776
The users current directory. The package directory from the built package is
1777
copied locally. The "pkg" directory is copied. This is only performed with the
1778
B<-copy> option.
1779
 
1780
=back
1781
 
1782
=item Delete the view
1783
 
1784
Delete the view and all related files.
1785
 
1786
The view will not be deleted if an error was detected in the build process, or
1787
the "reuse" or "keep" options are present.
1788
 
1789
=back
1790
 
1791
=cut
1792