Subversion Repositories DevTools

Rev

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