Subversion Repositories DevTools

Rev

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