Subversion Repositories DevTools

Rev

Rev 5710 | Details | Compare with Previous | Last modification | View Log | RSS feed

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