Subversion Repositories DevTools

Rev

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