Subversion Repositories DevTools

Rev

Rev 2354 | 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
#
2354 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)
1356 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
1357 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
 
2354 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
#
392 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
    #
379 dpurdie 651
    chdir ( $user_cwd );
652
    ClearCmd ( 'rmview', '-force', '-tag', $VIEWTAG );
653
 
654
    #
655
    #   Remove view specific files
656
    #
381 dpurdie 657
    chdir ( $VIEWDIR ) || Error ("Cannot cd to $VIEWDIR");
379 dpurdie 658
    RmDirTree( 'local_dpkg_archive' );
659
    RmDirTree( '.view.dat' );
660
    foreach my $file ( glob ('update.*.updt') )
661
    {
662
        RmDirTree( $file );
663
    }
664
 
665
    #
381 dpurdie 666
    #   Ensure that the VOB root was extracted
667
    #
2354 dpurdie 668
    Error ('ExitCode=10', "Root directory not found: $VIEWDIR$ROOT_VOB")
381 dpurdie 669
        unless( -d $VIEWDIR . $ROOT_VOB );
2354 dpurdie 670
 
381 dpurdie 671
    #
2354 dpurdie 672
    #   Ensure some files were extracted
673
    #
674
    Error ('ExitCode=10', DisplayPath("View files in: $VIEWDIR, but no files were extracted"))
675
        unless ( $load_count );
676
 
677
 
678
    #
379 dpurdie 679
    #   If Unix based view, then get rid of the VOBS directory
680
    #
681
    if ( $UNIX )
682
    {
683
        foreach my $file ( glob ('vobs/*') )
684
        {
685
            my $target = $file;
686
            $target =~ s~^vobs/~~;
381 dpurdie 687
            rename $file, $target || Error ("Renaming $file. $!");
379 dpurdie 688
        }
689
 
381 dpurdie 690
        rmdir 'vobs' || Error ("Removing vobs directory from: $VIEWDIR");
379 dpurdie 691
    }
692
 
693
    Message DisplayPath("View files in: $VIEWDIR, Files: $load_count" );
694
    exit (0);
695
}
696
 
697
 
698
#
263 dpurdie 699
#   Locate the JATS build files within the populated view
700
#
701
chdir ($VIEWDIR) or Error( "Cannot chdir to $VIEWDIR");
702
Message( "Locating build files");
703
 
704
my $bscanner = BuildFileScanner( "$VIEWDIR$ROOT_VOB", 'build.pl', '--LocateAll' );
705
$bscanner->scan();
706
my @build_list = $bscanner->getInfo();
707
foreach my $be ( @build_list )
708
{
709
    Message( DisplayPath ("Build file: $be->{dir} Name: $be->{file}"));
710
}
711
 
712
#
713
#   If we are extracting the view then we are done
714
#   Display useful information for the user
715
#
716
if ( $opt_extract )
717
{
718
    Message  DisplayPath "View in: $VIEWDIR";
719
    Warning ("No build files found" )   if ( $#build_list < 0 );
720
    Warning( "Multiple build files found" )if ( $#build_list > 0 );
721
    Message ("Not all labels are locked") if ( @label_not_locked  );
722
    Message ("All labels are locked") unless ( @label_not_locked  );
723
    Message ("Development Sandbox") if ( $GBE_SANDBOX );
724
 
725
    exit 0;
726
}
727
 
728
Error ("No build files found")  if ( $#build_list < 0 );
729
 
730
#
731
#   Determine the list of builds to perform
732
#   Ensure that the user-requested build files are present
733
#
734
#   The user specifies the build file, via the mangled package name
735
#   This is package_name . project extension (daf_utils.cr)
736
#
737
if ( $#opt_build  >= 0)
738
{
739
    Verbose( "Check and locate the build files");
740
    @build_list = ();
741
    foreach my $bentry ( @opt_build )
742
    {
743
        if ($bscanner->match( $bentry) )
744
        {
745
            UniquePush (\@build_list, $bscanner->getMatchList() );
746
            Verbose ("Found: $bentry");
747
        }
748
        else
749
        {
750
            Error ("Cannot locate requested build files for: $bentry")
751
        }
752
    }
753
}
754
 
755
#
756
#   Sanity test if we will transfer the generated package to dpkg_archive
757
#   There are some limits
758
#       1) Must have built from one label
759
#       2) That label must be locked
760
#       3) Only one build file
761
#       4) The view must not have been reused
762
#       5) The view has a branch rule
763
#       6) Building from a config spec
764
#       7) Cannot release from a sandbox
765
#
766
my @elist;
767
push @elist, "Package built from multiple labels" unless ( $label_count == 1 || $opt_config_spec );
768
push @elist, "Package built from an unlocked label" if ( @label_not_locked  );
769
push @elist, "Package built with multiple build files" if ( scalar @build_list > 1 );
770
push @elist, "Package from a reused view" if ( $opt_reuse && ! $opt_beta );
771
push @elist, "Package from a development sandbox" if ( $GBE_SANDBOX );
772
push @elist, "View contains a branch" if ( $opt_branch );
773
push @elist, "Package based on a config spec" if ( $opt_config_spec );
774
push @elist, "User has specified build files" if ( $#opt_build > 0 );
775
 
776
if ( @elist )
777
{
778
    Warning ("Cannot officially release the package.", @elist);
779
    Error ("Build terminated as it cannot be released") if ($opt_dpkg && ! $opt_beta);
780
}
781
Warning ("Beta Release") if $opt_beta;
782
 
783
#
784
#   Process each of the build files in the specified order
785
#
786
foreach my $be (@build_list)
787
{
788
 
789
    #
790
    #   We need to change to the build directory
791
    #   Moreover we need the local name of the build directory.
792
    #   Windows does not handle a UNC pathname to well (at all)
793
    #
794
    my $build_dir = $be->{dir};
795
    chdir ("$build_dir") or Error( "Cannot chdir to build directory: $build_dir");
796
 
797
    if ( $be->{file} =~ m/^build.pl$/ )
798
    {
799
        Message ("Using JATS: $build_dir");
800
        #
801
        #   Invoke JATS to build the package and make the package
802
        #
803
        my @build_args = qw(--expert --cache);
804
        push @build_args, '--cache' if $opt_cache;
805
 
806
        my $make_type = 'all';
807
        $make_type = 'all_prod'  if ( $opt_prod_build );
808
        $make_type = 'all_debug' if ( $opt_debug_build );
809
 
810
 
811
        JatsCmd('build', @build_args)               and Error("Package did not build");
812
        JatsCmd('make', $make_type, 'NODEPEND=1')   and Error("Package did not make");
813
        JatsCmd('install');
814
 
815
        if ( $opt_runtests )
816
        {
321 dpurdie 817
            JatsCmd('make', 'run_unit_tests')      and Error("Tests did not run correctly");
263 dpurdie 818
        }
819
    }
820
    else
821
    {
822
        #
823
        #   Ant build files
824
        #
825
        my $pname =  $be->{file};
826
        Message ("Using ANT: $build_dir, $pname");
827
        $pname =~ s~depends.xml$~.xml~;
828
        copy($be->{file}, "auto.xml");
829
        JatsCmd('-buildfile', $pname, 'ant', 'build')        and Error("Package did not build");
830
        JatsCmd('-buildfile', $pname, 'ant', 'make_package') and Error("Package did not make_package");
831
    }
832
}
833
 
834
#
835
#   Copy the generated packages
836
#       1) dpkg_archive
837
#       2) Users local directory
838
#
839
foreach my $be (@build_list)
840
{
841
    my $build_dir = $be->{dir};
842
    chdir ("$build_dir") or Error( "Cannot chdir to build directory: $build_dir");
843
    if ( $opt_dpkg )
844
    {
845
        Message ("Using: $build_dir");
279 dpurdie 846
        my @create_opts = "-o";
847
        push @create_opts ,"-m" if ( $opt_merge );
848
        JatsCmd('-here', 'create_dpkg', @create_opts, '-pname', $be->{name}, '-pversion', $be->{version}) and $error++;
263 dpurdie 849
    }
850
 
851
    if ( $opt_copy )
852
    {
853
        Message ("Copy package to $user_cwd");
854
        copy_directory( 'pkg', $user_cwd, '' );
855
    }
856
 
857
    #
858
    #   Test structure of the package
859
    #   Ensure that it has a descpkg file
860
    #   Validate the package name and version
861
    #   More important for ANT projects than JATS as JATS has a sanity test
862
    #
863
    if ( $opt_test )
864
    {
865
        JatsCmd('-here', 'create_dpkg', '-test', '-pname', $be->{name}, '-pversion', $be->{version}) and $error++;
866
    }
867
 
868
}
869
Error ("Package not transferred")
870
    if ( $error );
871
 
872
 
873
#
874
#   Delete the view
875
#
876
if ( ! $opt_reuse && ! $error && ! $opt_keep )
877
{
878
    delete_view();
879
}
880
else
881
{
882
    Message( "View left in: $VIEWDIR" );
883
}
884
 
885
Message ("End program");
886
exit 0;
887
 
888
#-------------------------------------------------------------------------------
889
# Function        : delete_view
890
#
891
# Description     : Delete a view
892
#
893
# Inputs          : None
894
#                   $VIEWTAG - name of the view
895
#                   $VIEWDIR - path of the view
896
#
897
# Returns         :
898
#
899
sub delete_view
900
{
901
    my $cofound = 0;
902
    my $uuid;
903
 
904
    #
299 dpurdie 905
    #   Simple delete
263 dpurdie 906
    #
299 dpurdie 907
    if ( $opt_extract_files )
263 dpurdie 908
    {
299 dpurdie 909
        if ( -d $VIEWDIR )
910
        {
911
            Message("Remove extracted files: $VIEWTAG");
361 dpurdie 912
            RmDirTree( $VIEWDIR );
299 dpurdie 913
        }
914
    }
915
    else
916
    {
263 dpurdie 917
        #
299 dpurdie 918
        #   If the view physically exists then attempt to phyically remove it
263 dpurdie 919
        #
299 dpurdie 920
        if ( -d $VIEWDIR )
921
        {
922
            #
923
            #   Determine if there are any checked out files in the view
924
            #
925
            Message("Remove the view: $VIEWTAG");
926
            Verbose("Look for checked out files");
263 dpurdie 927
 
299 dpurdie 928
            chdir ( $VIEWDIR );
929
            foreach my $file ( glob ('*') )
263 dpurdie 930
            {
299 dpurdie 931
                next if ( $file =~ m~local_dpkg_archive~ );
932
                next if ( $file =~ m~^view\.~ );
933
                if ( -d $file )
934
                {
935
                    Verbose ("Examine $file for checked out files");
936
                    chdir "$VIEWDIR/$file";
263 dpurdie 937
 
299 dpurdie 938
                    my $cmd = ClearToolCmd('lsco', '-cview', '-rec' );
939
                    open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
940
                    while (<CMD>)
263 dpurdie 941
                    {
299 dpurdie 942
                        #
943
                        #   Filter output from the user
944
                        #
945
                        chomp;
946
                        Verbose("lsco: $_");
947
                        if ( m~checkout version~ )
948
                        {
949
                            $cofound++ ;
950
                            Warning ("Checked out file: $_");
951
                        }
263 dpurdie 952
                    }
299 dpurdie 953
                    close(CMD);
263 dpurdie 954
                }
955
            }
956
 
299 dpurdie 957
            Error ("Will not delete view. Checked out files exist")
958
                if ( $cofound );
263 dpurdie 959
 
299 dpurdie 960
            #
961
            #   Get out of the view
962
            #   Cannot delete the view if we are in it.
963
            #
964
            chdir ( $user_cwd );
263 dpurdie 965
 
299 dpurdie 966
            #
967
            #   Static views should be removed by dirname, not by tag
968
            #
969
            ClearTool( 'rmview', $VIEWDIR );
263 dpurdie 970
 
299 dpurdie 971
            #
972
            #   Now try to delete the directory
973
            #
361 dpurdie 974
            RmDirTree( $VIEWDIR );
299 dpurdie 975
        }
263 dpurdie 976
 
977
        #
299 dpurdie 978
        #   If the view tag still exists then delete the view the hard way
979
        #   Use 'lsview' to locate the views uuid
263 dpurdie 980
        #
299 dpurdie 981
        Verbose("Look for View Tag");
982
        my $cmd = ClearToolCmd ('lsview', '-long', $VIEWTAG );
983
        open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
984
        while (<CMD>)
985
        {
986
            #
987
            #   Filter output from the user
988
            #
989
            chomp;
990
            Verbose("lsview: $_");
991
            $uuid = $1 if ( m~^View uuid:\s+(.*)~ );
992
        }
993
        close(CMD);
994
        if ( $uuid )
995
        {
996
            Warning ("Deleting view - the hard way");
997
            ClearTool( '--Quiet', 'rmview', '-force', '-all', '-uuid', $uuid );
998
            ClearTool( '--Quiet', 'unregister', '-view', '-uuid', $uuid );
999
            ClearTool( '--Quiet', 'rmtag','-view', '-all', $VIEWTAG );
1000
        }
263 dpurdie 1001
    }
1002
 
1003
    Error ("View was not deleted")
1004
        if ( -d $VIEWDIR );
1005
}
1006
 
1007
#-------------------------------------------------------------------------------
1008
# Function        : copy_directory
1009
#
1010
# Description     : Copy a directory tree
1011
#
1012
# Inputs          : Source directory
1013
#                   Target directory
1014
#                   Strip
1015
#
1016
#                   Should be full pathnames
1017
#
1018
# Returns         :
1019
#
1020
my $copy_error;
1021
my $copy_count;
1022
sub copy_directory
1023
{
1024
    our ($src_dir, $dest_dir, $strip) = @_;
1025
    our $slength = length ($strip);
1026
 
1027
    #
1028
    #   Prevent File::Find from generating warnings
1029
    #
1030
    no warnings 'File::Find';
1031
 
1032
 
1033
    #
1034
    #   Helper routine to copy files
1035
    #
1036
    sub copy_file_wanted
1037
    {
1038
        #
1039
        #   Do not copy directories
1040
        #   Just make the directory entry. May result in empty directories
1041
        #
1042
        if ( -d $_ )
1043
        {
1044
            my $tdir = "$dest_dir/" . substr( $File::Find::dir, $slength);
1045
            $tdir .= "/$_";
1046
            File::Path::mkpath( $tdir )
1047
                unless ( -d $tdir);
1048
            return;
1049
        }
1050
 
1051
        #
1052
        #   When used to copy file from within a clearcase dynamic view the
1053
        #   files may not actually exist. This will generate an error later
1054
        #   so check for existance of file file now.
1055
        #
1056
        return unless ( -e $_ );
1057
 
1058
        #
1059
        #   Have been chdir'ed to the source directory
1060
        #   when invoked
1061
        #
1062
        my $tdir = "$dest_dir/" . substr( $File::Find::dir, $slength);
1063
        my $tfile = "$tdir/$_";
1064
        my $sfile = "$File::Find::dir/$_";
1065
        Verbose ("Copy: $sfile -> $tfile");
1066
 
1067
        File::Path::mkpath( $tdir )
1068
            unless ( -d $tdir);
1069
 
1070
        unlink ( $tfile )
1071
            if ( -f $tfile );
1072
 
1073
        if( ! File::Copy::copy ( $_ , $tfile ) )
1074
        {
1075
            $copy_error++;
1076
            Message "Error copying $sfile";
1077
        }
1078
        else
1079
        {
1080
            my $perm = (stat $_)[2] & 07777;
1081
            chmod($perm, $tfile);
1082
 
1083
            $copy_count++;
1084
        }
1085
    }
1086
 
1087
    #
1088
    #   Locate all files to copy
1089
    #
1090
    $copy_error = 0;
1091
    $copy_count = 0;
1092
    File::Find::find ( \&copy_file_wanted, $src_dir );
1093
    return $copy_error;
1094
}
1095
 
1096
#-------------------------------------------------------------------------------
1097
# Function        : ClearTool
1098
#
1099
# Description     : Issue a cleartool command
1100
#                   Filter out many of the stupid messages
1101
#
1102
# Inputs          : Options and Command line
1103
#                   Options:
1104
#                       --Quiet     - Supress all command output
1105
#
1106
# Returns         : Error code
1107
#
1108
sub ClearTool
1109
{
1110
    my $quiet;
379 dpurdie 1111
    $load_count = 0;
263 dpurdie 1112
 
1113
    #
1114
    #   Scan for initial options
1115
    #       --Quiet
1116
    #
1117
    if ( $_[0] eq '--Quiet' )
1118
    {
1119
        $quiet = 1;
1120
        shift;
1121
    }
1122
 
1123
    my $cmd = ClearToolCmd(@_);
1124
    open(CMD, "$cmd 2>&1 |") || Error "can't run command: $!";
1125
    while (<CMD>)
1126
    {
1127
        #
1128
        #   Filter output from the user
1129
        #
379 dpurdie 1130
        $load_count++ if ( m'Loading ' );
263 dpurdie 1131
        next if ( $quiet );
379 dpurdie 1132
        if ( $opt_extract_files )
1133
        {
1134
            next if ( m'Loading ' );
1135
            next if ( m'Done loading ' );
1136
            next if ( m'Log has been written to ' );
1137
        }
263 dpurdie 1138
        unless ( $opt_verbose )
1139
        {
1140
            next if ( m~Making dir~ );
1141
            next if ( m~End dir~ );
1142
            next if ( m~Processing dir~ );
1143
            next if ( m~Error~ );
1144
        }
1145
        print $_;
1146
    }
1147
    close(CMD);
1148
 
1149
    Verbose2 "ClearTool Exit Status: $?";
1150
    return $? / 256;
1151
}
1152
 
1153
#-------------------------------------------------------------------------------
1154
# Function        : ClearCmd
1155
#
1156
# Description     : Execute a cleartool command
1157
#                   Capture error messages only
1158
#
1159
# Inputs          : Command to execute
1160
#                   Takes an array of command argumeents and will quote them
1161
#
1162
# Returns         : Exit code
1163
#                   Also the global @error_list
1164
#
1165
sub ClearCmd
1166
{
1167
    @error_list = ();
1168
 
1169
    my $cmd = ClearToolCmd(@_);
1170
    open(CMD, "$cmd  2>&1 |")    || Error "can't run command: $!";
1171
    while (<CMD>)
1172
    {
1173
        chomp;
1174
        Verbose ($_);
1175
        push @error_list, $_ if ( m~Error:~ );
1176
    }
1177
    close(CMD);
1178
 
1179
    Verbose2 "Exit Status: $?";
1180
    return $? / 256;
1181
}
1182
 
1183
#-------------------------------------------------------------------------------
1184
# Function        : ClearToolCmd
1185
#
1186
# Description     : Create a nice escaped cleartool command
1187
#
1188
# Inputs          : An array of cleartool command line arguments
1189
#
1190
# Returns         : A string that has been quoted
1191
#
1192
sub ClearToolCmd
1193
{
1194
    my $cmd = 'cleartool ' . QuoteCommand( @_);
1195
    Verbose2 $cmd;
1196
    return $cmd;
1197
}
1198
 
1199
#-------------------------------------------------------------------------------
1200
# Function        : unlock_on_error
1201
#
1202
# Description     : Error cleanup function.
1203
#                   Called by the error processing
1204
#                   Called to unlock all labels that have been locked by this
1205
#                   utility
1206
#
1207
# Inputs          : @label_locked           - Labels locked by this utility (Global)
1208
#
1209
# Returns         : 
1210
#
1211
sub unlock_on_error
1212
{
1213
    my @still_locked;
1214
    Message( "Releasing Locked labels" );
1215
    foreach my $spec ( @label_locked )
1216
    {
1217
        Verbose ("Unlocking:$spec");
1218
        ClearCmd ('unlock', "lbtype:$spec$root_vob_spec" );
1219
        push @still_locked, $spec if ( @error_list );
1220
    }
1221
    Error ("Not all labels unlocked: @still_locked") if ( @still_locked  );
1222
}
1223
 
1224
#-------------------------------------------------------------------------------
1225
# Function        : create_config_spec
1226
#
1227
# Description     : Creates a config spec
1228
#
1229
# Inputs          : $config     - Path to the config file
1230
#
1231
# Returns         : Path to the config spec
1232
#
1233
sub create_config_spec
1234
{
1235
    my ($config_file) = @_;
363 dpurdie 1236
 
263 dpurdie 1237
    #
363 dpurdie 1238
    #   Calc the path to a directory in the view which we really want to
1239
    #   consider as the base. Only want to see folders above this base.
1240
    #   Don't want to add elements above the base
1241
    #
1242
    my $basepath = ($opt_path) ? "\"${VOB_PREFIX}${opt_path}\""     : $ROOT_VOB;
1243
    my $elroot   = ($opt_path) ? "\"${VOB_PREFIX}${opt_path}/...\"" : '*';
369 dpurdie 1244
    my $elpath   = ($opt_path) ? $opt_path : '';
363 dpurdie 1245
 
1246
    #
263 dpurdie 1247
    #   Create a config spec to be used to populate the view
1248
    #       Do not branch directories
1249
    #       Do not extract files from lost+found
1250
    #
1251
    Verbose( "Create config spec");
1252
    my @config;
1253
    push @config, "element * CHECKEDOUT";
1254
    push @config, "element .../lost+found -none";
363 dpurdie 1255
 
1256
    #
1257
    #   Insert rules to prevent branching above the load path
1258
    #   This will be the root of the package
1259
    #
1260
    if ( $opt_path )
1261
    {
1262
        my $fulldir = $VOB_PREFIX;
1263
        my @parts = split ('/', $opt_path);
1264
        shift @parts;                                   # Skip first as its empty
1265
        pop @parts;                                     # Skip last as its the package
1266
        foreach my $dir ( @parts )
1267
        {
1268
            $fulldir .= "/$dir";
1269
            foreach (@opt_spec)
1270
            {
1271
                push @config, "element -dir \"$fulldir\" $_ -nocheckout";
1272
            }
1273
        }
1274
    }
1275
    else
1276
    {
1277
        foreach (@opt_spec)
1278
        {
1279
            push @config, "element -dir \"$ROOT_VOB\" $_ -nocheckout";
1280
        }
1281
    }
1282
 
1283
    #
1284
    #   General branching rules
1285
    #   Rule will apply to all following directives
1286
    #
1287
    if ( $opt_branch )
1288
    {
1289
        push @config, "element $elroot .../$opt_branch/LATEST";
1290
        push @config, "mkbranch $opt_branch";
1291
    }
1292
 
1293
    #
1294
    #   Rules to extract elements within the load path
1295
    #
263 dpurdie 1296
    foreach (@opt_spec)
1297
    {
363 dpurdie 1298
        push @config, "element $elroot $_";
263 dpurdie 1299
    }
1300
 
1301
    #
363 dpurdie 1302
    #   KLUDGE ALERT
263 dpurdie 1303
    #   Packages SHOULD be labled to the root.
1304
    #   Do not extend this list fix the package - fix the labels in the VOB.
1305
    #
1306
    if ( $opt_latest_root )
1307
    {
363 dpurdie 1308
        push @config, "element -dir $ROOT_VOB .../$opt_latest_root/LATEST";
1309
        push @config, "element -dir $ROOT_VOB .../mass_dev2/LATEST";
1310
        push @config, "element -dir $ROOT_VOB .../mass_dev/LATEST";
1311
        push @config, "element -dir $ROOT_VOB /main/LATEST";
263 dpurdie 1312
    }
1313
 
1314
    #
363 dpurdie 1315
    #   Handle file(directory) addition
1316
    #   Need a rule to allow /main/0 to be visible
1317
    #   Need to ensure that we don't "see" the entire VOB, just below the load path
263 dpurdie 1318
    #
379 dpurdie 1319
    unless ($GBE_ABT || $opt_extract_files)
263 dpurdie 1320
    {
363 dpurdie 1321
        #
1322
        #   Ensure that we have more than just the VOB root
1323
        #   If we only have the VOB root then we will get all top level entries
1324
        #   in the vob - and this is not good.
1325
        #
1326
        #   Comment out the rule so that the user can use if they must
1327
        #
369 dpurdie 1328
        my $count = ($elpath =~ tr~/~~);
1329
        my $prefix = ( $count <= 1 ) ? '# ' : '';
1330
        Verbose2 ("Config Spec: Suppress /main/0. Path too short)") if $prefix;
363 dpurdie 1331
        #
1332
        #   Ensure that element-0 is visible (unless autobuilder)
1333
        #   Note: mkbranch rule will modify this rule
1334
        #
1335
        push @config, $prefix . "element $elroot /main/0";
263 dpurdie 1336
    }
1337
 
1338
    #
1339
    #   Load rule
1340
    #   Quote the path so that spaces will be correcly handled
1341
    #
363 dpurdie 1342
    push @config, "load $basepath";
263 dpurdie 1343
 
369 dpurdie 1344
    Message ("Config Spec", @config )
1345
        if ( IsVerbose(1) );
363 dpurdie 1346
 
263 dpurdie 1347
    FileCreate ($config_file, \@config);
1348
    return $config_file;
1349
}
1350
 
1351
#-------------------------------------------------------------------------------
1352
#   Documentation
1353
#
1354
 
1355
=pod
1356
 
361 dpurdie 1357
=for htmltoc    GENERAL::ClearCase::
1358
 
263 dpurdie 1359
=head1 NAME
1360
 
1361
jats_ccrelease - Build a package given a clearcase label
1362
 
1363
=head1 SYNOPSIS
1364
 
1365
  jats ccrelease [options] [-label=]label | -config=config_spec
1366
 
1367
 Options:
1368
    -help              - brief help message
1369
    -help -help        - Detailed help message
1370
    -man               - Full documentation
1371
    -label=xxx         - Clearcase label
1372
    -spec=xxx          - Same as -label=xxx
1373
    -path=xxx          - Source Path
1374
    -view=xxx          - Modify the name of the created view
1375
    -vob=vobname       - VOB name
1376
    -build=xxx         - Package Name to build
1377
    -root=xxx          - Root directory for generated view
1378
    -latestroot=xxx    - Use the LATEST rootlevel directory 'xxx'
1379
    -[mk]branch=xxx    - Will create a view with a branch rule
1380
    -config=xxx        - Create a view with the provided config spec
1381
    -tag=xxx           - Alternate tag used with in the ViewTag
1382
    -extract           - Extract the view and exit
1383
    -extractfiles      - Extract files, without a view
1384
    -cache             - Refresh local dpkg_archive cache
1385
    -delete            - Remove any existing view and exit
1386
    -debugOnly         - Make only the debug version
1387
    -prodOnly          - Make only the production version
1388
    -[no]dpkg          - Transfer package into dpkg_archive
1389
    -[no]copy          - Transfer pkg directory to the current user directory
1390
    -[no]reuse         - Reuse the view
1391
    -[no]test          - Test package build. Implies nocopy and nodpkg
1392
    -[no]keep          - Keep the view after the build
1393
    -[no]lock          - Lock labels
1394
    -[no]beta          - Release a beta package
1395
    -[no]merge         - Merge packages into dpkg_archive
1396
    -[no]runtests      - Run units tests. Default is runtests
1397
    -[no]prefix        - Supress user prefix in view name. Default prefix is USER
1398
 
1399
=head1 OPTIONS
1400
 
1401
=over 8
1402
 
1403
=item B<-help>
1404
 
1405
Print a brief help message and exits.
1406
 
1407
=item B<-help -help>
1408
 
1409
Print a detailed help message with an explanation for each option.
1410
 
1411
=item B<-man>
1412
 
1413
Prints the manual page and exits.
1414
 
1415
=item B<-label> or B<-spec>
1416
 
1417
The ClearCase label to use as the base for the view.
1418
 
1419
Eg: daf_utils_math_3.2.1
1420
 
1421
=item B<-view name>
1422
 
1423
Specified an alternate view name and tag to be used. This option does not provide the
1424
full name of the view.
1425
 
361 dpurdie 1426
The view tag will be : "${USER}_${MACHINENAME}_${TAG}_${NAME}"
263 dpurdie 1427
 
361 dpurdie 1428
The view path will be: "${USER}_${NAME}"
1429
 
263 dpurdie 1430
The default "NAME" is the first label specified.
1431
The default "TAG" is build. See B<-tag=tagname>.
1432
 
1433
If the user provides a view "name" that is prefixed with their user name
1434
('${USER}_'), then the username will be stripped of for internal processing.
1435
This allows a user to provide a view path when deleting a view.
1436
 
1437
=item B<-path=xxx>
1438
 
1439
Specifies the source path to the root of the extracted file tree. This option has several uses:
1440
 
1441
=over 8
1442
 
1443
=item   *
1444
 
1445
Provide a sanity test of the "Source Path" item within Release Manager
1446
 
1447
=item   *
1448
 
1449
Specify the VOB that contains the source. The VOB name will be extracted and
1450
used as the B<-vob> parameter.
1451
 
1452
=item   *
1453
 
1454
Limit the work to do in extracting the file tree.
1455
 
1456
=back
1457
 
1458
=item B<-vob=xxx>
1459
 
1460
Specifies the Clearcase VOB in which the clearcase label will be located.
1461
This is used as the basis for locating and loading the files within the view.
1462
 
1463
By default this utility will examine all the VOBs for the label.
1464
 
1465
=item B<-build=xxx>
1466
 
1467
This option allows the user to specify the packages to be built and the
1468
order in which the packages are to be built.
1469
This is useful if the extracted view contains multiple build files
1470
 
1471
This option may be used multiple times.
1472
 
1473
There are two forms in which the build target can be specified. It can be
1474
specified as a full package name and vesrion, or as a package name and the
1475
project suffix.
1476
 
1477
By default the program will assume that there is only one build file in the
1478
view and will not build if multiple files are present, unless the package to be
1479
built can be resolved.
1480
 
1481
The location mechanism operates for both JATS and ANT build files.
1482
 
1483
Example: -build=jats-api.1.0.0000.cr
1484
 
1485
This will locate the build file that builds version 1.0.0000.cr of the jats-api
1486
package. The version numbers must match exactly.
1487
 
1488
Example: -build=jats-api.cr -build=jats-lib.cr
1489
 
1490
This will located the build files that build the jats_api (cr) package and the
1491
jats-lib (cr) package. The version of the packages will not be considered.
1492
 
1493
=item B<-root=xxx>
1494
 
1495
This option allows the location of the generated view to be specified on the
343 dpurdie 1496
command line. It overides the value of GBE_VIEWBASE.
263 dpurdie 1497
 
1498
If the comamnd is invoked within a development sandbox, then the default
1499
location will be the root directory of the development sandbox.
1500
 
1501
=item B<-latestroot=xxx>
1502
 
1503
This option enables a work around for a bad-labelling practice that has existed
1504
in the past. This LATEST version of the named (xxx) branch will be added to
1505
the config spec used to create the view.
1506
 
1507
This is a work around for a problem where the top-level directory in the VOB has
1508
not been labelled. This can result in unreproducible builds.
1509
 
1510
This option allows the utility to construct a view, but the user SHOULD label
1511
the root level directory to correct the problem.
1512
 
1513
The use of this switch will add the following lines to the config spec:
1514
 
1515
    element -directory /DPG_SWBase /main/xxxx/LATEST
1516
 
1517
=item B<-branch=xxx or -mkbranch=xxx>
1518
 
1519
This option will create a view such that files that are checked out will be
1520
checked out on the named branch. This is intended to facilitate the maintenance
1521
of existing packages - the creation of a patch.
1522
 
1523
The named branch must exist within the VOB containing the label. The script will
1524
check for its existence.
1525
 
1526
The use of this switch will add the following lines to the config spec:
1527
 
1528
    element * .../xxx/LATEST
361 dpurdie 1529
    element * label -mkbranch xxx
263 dpurdie 1530
    element * /main/0 -mkbranch xxx
1531
 
1532
=item B<-config=config_spec>
1533
 
1534
This option is an alternate mechanism to create a static view. The view will be
1535
based on the provided configuration spec. This view cannot be used to release a package.
1536
The option is intended to simplify development.
1537
 
1538
This option is incompatibale with:
1539
 
1540
    -release
1541
    -label
1542
    -branch
1543
    -path
1544
    -vob
1545
 
1546
=item B<-tag=text>
1547
 
1548
This option alters the ClearCase view tag created for the view. It allows
1549
the creation of multiple views based on the same label. Intended to be used in
1550
the automated build system to create unique views tags.
1551
 
1552
The default tag is 'build'.
1553
 
1554
=item B<-extract>
1555
 
1556
With this option the view is created and the left in place. The user may then
1557
access the files within the view. The view should not be used for a
1558
production release.
1559
 
1560
=item B<-extractfiles>
1561
 
1562
With this option the utility will create a dynamic view and transfer files from
1563
the view to the user's tararget. The dynamic view is then removed.
1564
 
1565
This command is intended to simplify the process of creating an escrow.
1566
 
1567
=item B<-cache>
1568
 
1569
Forces external packages to be placed in the local dpkg_archive cache.
1570
 
1571
The normal operation is to copy the packages, only if they do not already exist
1572
in the local cache. This option may be used to ensure that the local copy is
1573
correct and up to date.
1574
 
1575
=item B<-delete>
1576
 
1577
Delete the view used by the program, if it exists. This option may be used to
1578
cleanup after an error.
1579
 
1580
Note: Ensure that no files are open in the view and that the users current
1581
working directory is not in the view as these will prevent the view from being
1582
deleted.
1583
 
1584
=item B<-debugOnly>
1585
 
1586
Make only the debug version of the package. The default it to create both the
1587
debug and production version of the package. The type of build may be  further
1588
limited by options within the package.
1589
 
1590
=item B<-prodOnly>
1591
 
1592
Make only the production version of the package. The default it to create both the
1593
debug and production version of the package. The type of build may be  further
1594
limited by options within the package.
1595
 
1596
=item B<-[no]dpkg>
1597
 
1598
Copy the generated package into dpkg_archive. This is the default mode of
1599
operation.
1600
 
1601
=item B<-[no]copy>
1602
 
1603
Copy the built "pkg" directory to the users current directory. The entire
1604
"pkg" subdirectory includes the full package named directory for the package
1605
that has been built.
1606
 
1607
=item B<-[no]reuse>
1608
 
1609
This flag allows the view created by the program to be re-used.
1610
 
1611
=over 8
1612
 
361 dpurdie 1613
=item *
263 dpurdie 1614
 
361 dpurdie 1615
The view is not deleted before being populated.
263 dpurdie 1616
 
361 dpurdie 1617
=item *
263 dpurdie 1618
 
361 dpurdie 1619
The view will not be populated if it does exist.
1620
 
1621
=item *
1622
 
1623
The view will not be deleted at the end the process.
1624
 
263 dpurdie 1625
=back
1626
 
1627
This option is useful for debugging a build process.
1628
 
1629
=item B<-[no]test>
1630
 
1631
Test the building of the package. This option implies "nocopy" and "nodpkg".
1632
 
1633
=item B<-[no]keep>
1634
 
1635
Keep the clearcase view after the build. The default option is "nokeep"
1636
 
1637
This option is different to the "reuse" in that the view will be deleted, if
1638
it exists, before the build, but will be retained at the completion of the
1639
process. The user may then manually extract the created package.
1640
 
1641
The view may be deleted with the the "delete" option; taking care to ensure that
1642
no files are open in the view and that the users current working directory is
1643
not in the view.
1644
 
1645
=item B<-[no]lock>
1646
 
1647
Lock any unlocked labels before attempting the build. This operation may be used
1648
to ensure that a release build does not fail due to the labels not being locked.
1649
The label is locked before the view is constructed and populated.
1650
 
1651
This operation may fail if the user does not "own" the label.
1652
 
1653
=item B<-[no]beta>
1654
 
1655
This option overrides many of the package release tests to allow a beta package
1656
to be released.
1657
 
1658
=item B<-[no]merge>
1659
 
1660
This option will merge packages being built on multiple machines into
1661
dpkg_archive. By default, if a package already exists in the archive it will be
1662
deleted and replaced. With this option the package will be merged. The merge
1663
process does not over write files found in the archive.
1664
 
1665
=item B<-[no]runtests>
1666
 
1667
This option will allow the suppression of the running of the unit tests included
1668
with the component. By default the tests are run. This can be suppressed
1669
without affecting the release process.
1670
 
1671
=back
1672
 
1673
=head1 DESCRIPTION
1674
 
1675
This program is the primary tool for the creation, recreation and release of
1676
packages within the B<ERG> build environment, although the program can perform a
1677
number of very useful operations required during normal development and
1678
maintenance.
1679
 
1680
This program will build a system containing one or more inter-related build
1681
files using the JATS build tools.
1682
 
1683
In normal operation the program will:
1684
 
1685
=over 8
1686
 
1687
=item Remove View
1688
 
1689
Remove any existing view of the same name. The view will not be removed if it
1690
contains checked-out files.
1691
 
1692
The view removal may fail if there are any files B<open> within the view or if
1693
any shell has a subdirectory of the view set as a B<current working directory>.
1694
 
1695
=item Locate VOB
1696
 
1697
Locate the VOB that contains the specified label or labels. If multiple labels
1698
are specified they must all exist in the same VOB.
1699
 
1700
=item Lock Labels
1701
 
1702
Lock any unlocked labels, if required.
1703
 
1704
=item Create the view
1705
 
1706
Create a static view to containing the files describes by the Clearcase
1707
label being processed.
1708
 
1709
The program uses a fixed view name. If this view exists then item
1710
will be deleted before item is created again. Each build starts in a clean view.
1711
 
1712
=item Populate the View
1713
 
1714
Loads files into the static view. The user label and the VOB name are used to
1715
created a clearcase configuration specification. This configuration
1716
specification is then activated and all files within the specified VOB will be
1717
loaded into the view if they match the user supplied label.
1718
 
1719
This processed normally results in a lot of error messages that can be ignored.
1720
 
1721
I<Note:> The label placed on the component to be built must extend to the
1722
root of the VOB, otherwise the directory path will not be extracted nor will
1723
the files within the component.
1724
 
1725
I<Note:> If the view is simply being extracted, then this is the end of the
1726
program. The extracted view is left in place.
1727
 
1728
=item Sanity Test
1729
 
1730
If the build is being used as a release into dpkg_archive then
1731
various tests are performed to ensure the repeatability of the view and the
1732
build. These tests include:
1733
 
1734
=over 8
1735
 
361 dpurdie 1736
=item   *
263 dpurdie 1737
 
361 dpurdie 1738
The view must be constructed from one label
263 dpurdie 1739
 
361 dpurdie 1740
=item   *
263 dpurdie 1741
 
361 dpurdie 1742
That label must be locked
263 dpurdie 1743
 
361 dpurdie 1744
=item   *
1745
 
1746
The labelled view must contain exactly one build file
1747
 
1748
=item   *
1749
 
1750
The view cannot have been re-used.
1751
 
263 dpurdie 1752
=back
1753
 
1754
=item Locate build files
1755
 
1756
Locate the build file within the view.
1757
 
1758
It is an error to have multiple build files within the view, unless the
1759
B<-build> option is used. By default, only one package will be built.
1760
 
1761
=item Package the results
1762
 
1763
Use JATS to build and make the package.
1764
 
1765
The resultant package may be copied to a numbers of locations. These include
1766
 
1767
=over 8
1768
 
1769
=item 1
1770
 
1771
The master dpkg_archive as an official release. This is the default operation.
1772
 
1773
=item 2
1774
 
1775
The users current directory. The package directory from the built package is
1776
copied locally. The "pkg" directory is copied. This is only performed with the
1777
B<-copy> option.
1778
 
1779
=back
1780
 
1781
=item Delete the view
1782
 
1783
Delete the view and all related files.
1784
 
1785
The view will not be deleted if an error was detected in the build process, or
1786
the "reuse" or "keep" options are present.
1787
 
1788
=back
1789
 
1790
=cut
1791