Subversion Repositories DevTools

Rev

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