Subversion Repositories DevTools

Rev

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