Subversion Repositories DevTools

Rev

Rev 263 | Rev 279 | 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
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
 
269 dpurdie 635
#   Place a tag-file in the user-specified source path
636
#   This will be used by the build-tool to locate the 'source-path' of the
637
#   view, primarily for determining metrics.
263 dpurdie 638
#
269 dpurdie 639
#   Calculate where the dynmaic view will be
640
#   This differ between UNIX/WINDOWS
641
#
642
if ( $opt_path )
643
{
644
    Message( "Create Build tagfile");
645
    my $cpath = $VIEWDIR . $VOB_PREFIX . $opt_path;
646
    if ( -d $cpath )
647
    {
648
        TouchFile ( "$cpath/.jats.packageroot" );
649
    }
650
}
651
 
652
#
263 dpurdie 653
#   Locate the JATS build files within the populated view
654
#
655
chdir ($VIEWDIR) or Error( "Cannot chdir to $VIEWDIR");
656
Message( "Locating build files");
657
 
658
my $bscanner = BuildFileScanner( "$VIEWDIR$ROOT_VOB", 'build.pl', '--LocateAll' );
659
$bscanner->scan();
660
my @build_list = $bscanner->getInfo();
661
foreach my $be ( @build_list )
662
{
663
    Message( DisplayPath ("Build file: $be->{dir} Name: $be->{file}"));
664
}
665
 
666
#
667
#   If we are extracting the view then we are done
668
#   Display useful information for the user
669
#
670
if ( $opt_extract )
671
{
672
    Message  DisplayPath "View in: $VIEWDIR";
673
    Warning ("No build files found" )   if ( $#build_list < 0 );
674
    Warning( "Multiple build files found" )if ( $#build_list > 0 );
675
    Message ("Not all labels are locked") if ( @label_not_locked  );
676
    Message ("All labels are locked") unless ( @label_not_locked  );
677
    Message ("Development Sandbox") if ( $GBE_SANDBOX );
678
 
679
    exit 0;
680
}
681
 
682
Error ("No build files found")  if ( $#build_list < 0 );
683
 
684
#
685
#   Determine the list of builds to perform
686
#   Ensure that the user-requested build files are present
687
#
688
#   The user specifies the build file, via the mangled package name
689
#   This is package_name . project extension (daf_utils.cr)
690
#
691
if ( $#opt_build  >= 0)
692
{
693
    Verbose( "Check and locate the build files");
694
    @build_list = ();
695
    foreach my $bentry ( @opt_build )
696
    {
697
        if ($bscanner->match( $bentry) )
698
        {
699
            UniquePush (\@build_list, $bscanner->getMatchList() );
700
            Verbose ("Found: $bentry");
701
        }
702
        else
703
        {
704
            Error ("Cannot locate requested build files for: $bentry")
705
        }
706
    }
707
}
708
 
709
#
710
#   Sanity test if we will transfer the generated package to dpkg_archive
711
#   There are some limits
712
#       1) Must have built from one label
713
#       2) That label must be locked
714
#       3) Only one build file
715
#       4) The view must not have been reused
716
#       5) The view has a branch rule
717
#       6) Building from a config spec
718
#       7) Cannot release from a sandbox
719
#
720
my @elist;
721
push @elist, "Package built from multiple labels" unless ( $label_count == 1 || $opt_config_spec );
722
push @elist, "Package built from an unlocked label" if ( @label_not_locked  );
723
push @elist, "Package built with multiple build files" if ( scalar @build_list > 1 );
724
push @elist, "Package from a reused view" if ( $opt_reuse && ! $opt_beta );
725
push @elist, "Package from a development sandbox" if ( $GBE_SANDBOX );
726
push @elist, "View contains a branch" if ( $opt_branch );
727
push @elist, "Package based on a config spec" if ( $opt_config_spec );
728
push @elist, "User has specified build files" if ( $#opt_build > 0 );
729
 
730
if ( @elist )
731
{
732
    Warning ("Cannot officially release the package.", @elist);
733
    Error ("Build terminated as it cannot be released") if ($opt_dpkg && ! $opt_beta);
734
}
735
Warning ("Beta Release") if $opt_beta;
736
 
737
#
738
#   Process each of the build files in the specified order
739
#
740
foreach my $be (@build_list)
741
{
742
 
743
    #
744
    #   We need to change to the build directory
745
    #   Moreover we need the local name of the build directory.
746
    #   Windows does not handle a UNC pathname to well (at all)
747
    #
748
    my $build_dir = $be->{dir};
749
    chdir ("$build_dir") or Error( "Cannot chdir to build directory: $build_dir");
750
 
751
    if ( $be->{file} =~ m/^build.pl$/ )
752
    {
753
        Message ("Using JATS: $build_dir");
754
        #
755
        #   Invoke JATS to build the package and make the package
756
        #
757
        my @build_args = qw(--expert --cache);
758
        push @build_args, '--cache' if $opt_cache;
759
 
760
        my $make_type = 'all';
761
        $make_type = 'all_prod'  if ( $opt_prod_build );
762
        $make_type = 'all_debug' if ( $opt_debug_build );
763
 
764
 
765
        JatsCmd('build', @build_args)               and Error("Package did not build");
766
        JatsCmd('make', $make_type, 'NODEPEND=1')   and Error("Package did not make");
767
        JatsCmd('install');
768
 
769
        if ( $opt_runtests )
770
        {
771
            JatsCmd('make', 'run_unit_tests')      and Error("Tests did not run corectly");
772
        }
773
    }
774
    else
775
    {
776
        #
777
        #   Ant build files
778
        #
779
        my $pname =  $be->{file};
780
        Message ("Using ANT: $build_dir, $pname");
781
        $pname =~ s~depends.xml$~.xml~;
782
        copy($be->{file}, "auto.xml");
783
        JatsCmd('-buildfile', $pname, 'ant', 'build')        and Error("Package did not build");
784
        JatsCmd('-buildfile', $pname, 'ant', 'make_package') and Error("Package did not make_package");
785
    }
786
}
787
 
788
#
789
#   Copy the generated packages
790
#       1) dpkg_archive
791
#       2) Users local directory
792
#
793
foreach my $be (@build_list)
794
{
795
    my $build_dir = $be->{dir};
796
    chdir ("$build_dir") or Error( "Cannot chdir to build directory: $build_dir");
797
    if ( $opt_dpkg )
798
    {
799
        Message ("Using: $build_dir");
800
        my $create_opts = "-o";
801
        $create_opts .= " -m" if ( $opt_merge );
802
        JatsCmd('-here', 'create_dpkg', $create_opts, '-pname', $be->{name}, '-pversion', $be->{version}) and $error++;
803
    }
804
 
805
    if ( $opt_copy )
806
    {
807
        Message ("Copy package to $user_cwd");
808
        copy_directory( 'pkg', $user_cwd, '' );
809
    }
810
 
811
    #
812
    #   Test structure of the package
813
    #   Ensure that it has a descpkg file
814
    #   Validate the package name and version
815
    #   More important for ANT projects than JATS as JATS has a sanity test
816
    #
817
    if ( $opt_test )
818
    {
819
        JatsCmd('-here', 'create_dpkg', '-test', '-pname', $be->{name}, '-pversion', $be->{version}) and $error++;
820
    }
821
 
822
}
823
Error ("Package not transferred")
824
    if ( $error );
825
 
826
 
827
#
828
#   Delete the view
829
#
830
if ( ! $opt_reuse && ! $error && ! $opt_keep )
831
{
832
    delete_view();
833
}
834
else
835
{
836
    Message( "View left in: $VIEWDIR" );
837
}
838
 
839
Message ("End program");
840
exit 0;
841
 
842
#-------------------------------------------------------------------------------
843
# Function        : delete_view
844
#
845
# Description     : Delete a view
846
#
847
# Inputs          : None
848
#                   $VIEWTAG - name of the view
849
#                   $VIEWDIR - path of the view
850
#
851
# Returns         :
852
#
853
sub delete_view
854
{
855
    my $cofound = 0;
856
    my $uuid;
857
 
858
    #
859
    #   If the view physically exists then attempt to phyically remove it
860
    #
861
    if ( -d $VIEWDIR )
862
    {
863
        #
864
        #   Determine if there are any checked out files in the view
865
        #
866
        Message("Remove the view: $VIEWTAG");
867
        Verbose("Look for checked out files");
868
 
869
        chdir ( $VIEWDIR );
870
        foreach my $file ( glob ('*') )
871
        {
872
            next if ( $file =~ m~local_dpkg_archive~ );
873
            next if ( $file =~ m~^view\.~ );
874
            if ( -d $file )
875
            {
876
                Verbose ("Examine $file for checked out files");
877
                chdir "$VIEWDIR/$file";
878
 
879
                my $cmd = ClearToolCmd('lsco', '-cview', '-rec' );
880
                open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
881
                while (<CMD>)
882
                {
883
                    #
884
                    #   Filter output from the user
885
                    #
886
                    chomp;
887
                    Verbose("lsco: $_");
888
                    if ( m~checkout version~ )
889
                    {
890
                        $cofound++ ;
891
                        Warning ("Checked out file: $_");
892
                    }
893
                }
894
                close(CMD);
895
            }
896
        }
897
 
898
        Error ("Will not delete view. Checked out files exist")
899
            if ( $cofound );
900
 
901
        #
902
        #   Get out of the view
903
        #   Cannot delete the view if we are in it.
904
        #
905
        chdir ( $user_cwd );
906
 
907
        #
908
        #   Static views should be removed by dirname, not by tag
909
        #
910
        ClearTool( 'rmview', $VIEWDIR );
911
 
912
        #
913
        #   Now try to delete the directory
914
        #
915
        rmtree( $VIEWDIR );
916
    }
917
 
918
    #
919
    #   If the view tag still exists then delete the view the hard way
920
    #   Use 'lsview' to locate the views uuid
921
    #
922
    Verbose("Look for View Tag");
923
    my $cmd = ClearToolCmd ('lsview', '-long', $VIEWTAG );
924
    open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
925
    while (<CMD>)
926
    {
927
        #
928
        #   Filter output from the user
929
        #
930
        chomp;
931
        Verbose("lsview: $_");
932
        $uuid = $1 if ( m~^View uuid:\s+(.*)~ );
933
    }
934
    close(CMD);
935
 
936
    if ( $uuid )
937
    {
938
        Warning ("Deleting view - the hard way");
939
        ClearTool( '--Quiet', 'rmview', '-force', '-all', '-uuid', $uuid );
940
        ClearTool( '--Quiet', 'unregister', '-view', '-uuid', $uuid );
941
        ClearTool( '--Quiet', 'rmtag','-view', '-all', $VIEWTAG );
942
    }
943
 
944
 
945
    Error ("View was not deleted")
946
        if ( -d $VIEWDIR );
947
}
948
 
949
#-------------------------------------------------------------------------------
950
# Function        : copy_directory
951
#
952
# Description     : Copy a directory tree
953
#
954
# Inputs          : Source directory
955
#                   Target directory
956
#                   Strip
957
#
958
#                   Should be full pathnames
959
#
960
# Returns         :
961
#
962
my $copy_error;
963
my $copy_count;
964
sub copy_directory
965
{
966
    our ($src_dir, $dest_dir, $strip) = @_;
967
    our $slength = length ($strip);
968
 
969
    #
970
    #   Prevent File::Find from generating warnings
971
    #
972
    no warnings 'File::Find';
973
 
974
 
975
    #
976
    #   Helper routine to copy files
977
    #
978
    sub copy_file_wanted
979
    {
980
        #
981
        #   Do not copy directories
982
        #   Just make the directory entry. May result in empty directories
983
        #
984
        if ( -d $_ )
985
        {
986
            my $tdir = "$dest_dir/" . substr( $File::Find::dir, $slength);
987
            $tdir .= "/$_";
988
            File::Path::mkpath( $tdir )
989
                unless ( -d $tdir);
990
            return;
991
        }
992
 
993
        #
994
        #   When used to copy file from within a clearcase dynamic view the
995
        #   files may not actually exist. This will generate an error later
996
        #   so check for existance of file file now.
997
        #
998
        return unless ( -e $_ );
999
 
1000
        #
1001
        #   Have been chdir'ed to the source directory
1002
        #   when invoked
1003
        #
1004
        my $tdir = "$dest_dir/" . substr( $File::Find::dir, $slength);
1005
        my $tfile = "$tdir/$_";
1006
        my $sfile = "$File::Find::dir/$_";
1007
        Verbose ("Copy: $sfile -> $tfile");
1008
 
1009
        File::Path::mkpath( $tdir )
1010
            unless ( -d $tdir);
1011
 
1012
        unlink ( $tfile )
1013
            if ( -f $tfile );
1014
 
1015
        if( ! File::Copy::copy ( $_ , $tfile ) )
1016
        {
1017
            $copy_error++;
1018
            Message "Error copying $sfile";
1019
        }
1020
        else
1021
        {
1022
            my $perm = (stat $_)[2] & 07777;
1023
            chmod($perm, $tfile);
1024
 
1025
            $copy_count++;
1026
        }
1027
    }
1028
 
1029
    #
1030
    #   Locate all files to copy
1031
    #
1032
    $copy_error = 0;
1033
    $copy_count = 0;
1034
    File::Find::find ( \&copy_file_wanted, $src_dir );
1035
    return $copy_error;
1036
}
1037
 
1038
#-------------------------------------------------------------------------------
1039
# Function        : ClearTool
1040
#
1041
# Description     : Issue a cleartool command
1042
#                   Filter out many of the stupid messages
1043
#
1044
# Inputs          : Options and Command line
1045
#                   Options:
1046
#                       --Quiet     - Supress all command output
1047
#
1048
# Returns         : Error code
1049
#
1050
sub ClearTool
1051
{
1052
    my $quiet;
1053
 
1054
    #
1055
    #   Scan for initial options
1056
    #       --Quiet
1057
    #
1058
    if ( $_[0] eq '--Quiet' )
1059
    {
1060
        $quiet = 1;
1061
        shift;
1062
    }
1063
 
1064
    my $cmd = ClearToolCmd(@_);
1065
    open(CMD, "$cmd 2>&1 |") || Error "can't run command: $!";
1066
    while (<CMD>)
1067
    {
1068
        #
1069
        #   Filter output from the user
1070
        #
1071
        next if ( $quiet );
1072
        unless ( $opt_verbose )
1073
        {
1074
            next if ( m~Making dir~ );
1075
            next if ( m~End dir~ );
1076
            next if ( m~Processing dir~ );
1077
            next if ( m~Error~ );
1078
        }
1079
        print $_;
1080
    }
1081
    close(CMD);
1082
 
1083
    Verbose2 "ClearTool Exit Status: $?";
1084
    return $? / 256;
1085
}
1086
 
1087
#-------------------------------------------------------------------------------
1088
# Function        : ClearCmd
1089
#
1090
# Description     : Execute a cleartool command
1091
#                   Capture error messages only
1092
#
1093
# Inputs          : Command to execute
1094
#                   Takes an array of command argumeents and will quote them
1095
#
1096
# Returns         : Exit code
1097
#                   Also the global @error_list
1098
#
1099
sub ClearCmd
1100
{
1101
    @error_list = ();
1102
 
1103
    my $cmd = ClearToolCmd(@_);
1104
    open(CMD, "$cmd  2>&1 |")    || Error "can't run command: $!";
1105
    while (<CMD>)
1106
    {
1107
        chomp;
1108
        Verbose ($_);
1109
        push @error_list, $_ if ( m~Error:~ );
1110
    }
1111
    close(CMD);
1112
 
1113
    Verbose2 "Exit Status: $?";
1114
    return $? / 256;
1115
}
1116
 
1117
#-------------------------------------------------------------------------------
1118
# Function        : ClearToolCmd
1119
#
1120
# Description     : Create a nice escaped cleartool command
1121
#
1122
# Inputs          : An array of cleartool command line arguments
1123
#
1124
# Returns         : A string that has been quoted
1125
#
1126
sub ClearToolCmd
1127
{
1128
    my $cmd = 'cleartool ' . QuoteCommand( @_);
1129
    Verbose2 $cmd;
1130
    return $cmd;
1131
}
1132
 
1133
#-------------------------------------------------------------------------------
1134
# Function        : unlock_on_error
1135
#
1136
# Description     : Error cleanup function.
1137
#                   Called by the error processing
1138
#                   Called to unlock all labels that have been locked by this
1139
#                   utility
1140
#
1141
# Inputs          : @label_locked           - Labels locked by this utility (Global)
1142
#
1143
# Returns         : 
1144
#
1145
sub unlock_on_error
1146
{
1147
    my @still_locked;
1148
    Message( "Releasing Locked labels" );
1149
    foreach my $spec ( @label_locked )
1150
    {
1151
        Verbose ("Unlocking:$spec");
1152
        ClearCmd ('unlock', "lbtype:$spec$root_vob_spec" );
1153
        push @still_locked, $spec if ( @error_list );
1154
    }
1155
    Error ("Not all labels unlocked: @still_locked") if ( @still_locked  );
1156
}
1157
 
1158
#-------------------------------------------------------------------------------
1159
# Function        : extract_files_from_view
1160
#
1161
# Description     : This function will
1162
#                       Create a dynamic view
1163
#                       Copy all the files out of the view
1164
#                       Delete the view
1165
#
1166
#                   Its used in the creation of escrow directories
1167
#
1168
# Inputs          : None
1169
#                   All done via globals
1170
#
1171
# Returns         : 
1172
#
1173
sub extract_files_from_view
1174
{
1175
    my $vob_mounted = 1;
1176
    my $vob_name;
1177
 
1178
    #
1179
    #   Determine the target directory for the extracted files
1180
    #       Delete the output subdir
1181
    #       Create the config spec in that directory
1182
    #
1183
    Verbose("Extracting files into $VIEWDIR");
1184
    if ( -d $VIEWDIR )
1185
    {
1186
        Verbose "Delete Directory: $VIEWDIR\n";
1187
        rmtree( $VIEWDIR );
1188
    }
1189
 
1190
    #
1191
    #   Which config spec
1192
    #   If we need to create it, do it within the final view
1193
    #
1194
    my $config;
1195
    $config = $opt_config_spec;
1196
    unless ( $opt_config_spec )
1197
    {
1198
        File::Path::mkpath( $VIEWDIR );
1199
        $config = create_config_spec( "$VIEWDIR/config_spec.txt" );
1200
    }
1201
 
1202
    #
1203
    #   Create the view and insert the config spec
1204
    #
1205
    ClearCmd ( 'rmview', '-tag', $VIEWTAG );
1206
    ClearCmd ( 'mkview', '-tag', $VIEWTAG, '-stgloc', '-auto' );
1207
    ClearCmd ( 'setcs',  '-tag', $VIEWTAG, $config );
1208
 
1209
    #
1210
    #   Ensure that the base VOB has been 'mounted'
1211
    #   Dynamic views require vobs to be mounted
1212
    #
1213
    ($vob_name = $ROOT_VOB) =~ s~/~$VOB_SEP~g;
1214
    $vob_mounted = ClearCmd ('mount', $vob_name);
1215
 
1216
    #
1217
    #   Calculate where the dynmaic view will be
1218
    #   This differ between UNIX/WINDOWS
1219
    #
1220
    my $vpath = $VIEW_PREFIX . $VIEWTAG . $VOB_PREFIX;
1221
    my $cpath = $vpath;
1222
       $cpath .= $opt_path if ( $opt_path );
1223
    #
1224
    #   Is the view where we expect it to be
1225
    #
1226
    Error ("Cannot locate dynamic view",
1227
            "Looking in: $vpath" ) unless -d $vpath;
1228
 
1229
    #
1230
    #   Copy all the files out of the view
1231
    #
1232
    Verbose ("Copy View contents");
1233
    my $rv = copy_directory ($cpath, $VIEWDIR, $vpath );
1234
    Message ("View files in: $VIEWDIR, Files: $copy_count" );
1235
 
1236
    #
1237
    #   Remove the view
1238
    #
1239
    ClearCmd ( 'rmview', '-tag', $VIEWTAG );
1240
 
1241
    #
1242
    #   Unmount the vob - if mounted
1243
    #
1244
    ClearCmd ('umount', $vob_name) unless $vob_mounted;
1245
 
1246
    Error ("Copy did not complete without error")
1247
        if ( $rv );
1248
 
1249
}
1250
 
1251
#-------------------------------------------------------------------------------
1252
# Function        : create_config_spec
1253
#
1254
# Description     : Creates a config spec
1255
#
1256
# Inputs          : $config     - Path to the config file
1257
#
1258
# Returns         : Path to the config spec
1259
#
1260
sub create_config_spec
1261
{
1262
    my ($config_file) = @_;
1263
    #
1264
    #   Create a config spec to be used to populate the view
1265
    #       Do not branch directories
1266
    #       Do not extract files from lost+found
1267
    #
1268
    Verbose( "Create config spec");
1269
    my @config;
1270
    push @config, "element * CHECKEDOUT";
1271
    push @config, "element .../lost+found -none";
1272
    push @config, "element * .../$opt_branch/LATEST" if $opt_branch;
1273
    foreach (@opt_spec)
1274
    {
1275
        my $data = "element * $_";
1276
        $data .= " -mkbranch $opt_branch" if $opt_branch;
1277
        push @config, $data;
1278
    }
1279
 
1280
    #
1281
    #   Packages SHOULD be labled to the root.
1282
    #   Do not extend this list fix the package - fix the labels in the VOB.
1283
    #
1284
    if ( $opt_latest_root )
1285
    {
1286
        push @config, "element -directory $ROOT_VOB .../$opt_latest_root/LATEST";
1287
        push @config, "element -directory $ROOT_VOB .../mass_dev/LATEST";
1288
        push @config, "element -directory $ROOT_VOB /main/LATEST";
1289
    }
1290
 
1291
    #
1292
    #   Do not branch directories above the load path
1293
    #   Load only the version on /main
1294
    #       UNIX: Don't play with the /vobs (won't work)
1295
    #
1296
    if ( $opt_branch )
1297
    {
1298
        if ( $opt_path )
1299
        {
1300
            my $fulldir = $VOB_PREFIX;
1301
            my @parts = split ('/', $opt_path);
1302
            shift @parts;
1303
            foreach my $dir ( @parts )
1304
            {
1305
                $fulldir .= "/$dir";
1306
                push @config, "element -dir $fulldir /main/LATEST"
1307
            }
1308
        }
1309
        else
1310
        {
1311
            push @config, "element -dir $ROOT_VOB /main/LATEST";
1312
        }
1313
    }
1314
 
1315
    #
1316
    #   Branch rule:
1317
    #   Need /main/0 to allow files to be added to the view
1318
    #   Will get a lot of stuff, so take care not to label it all
1319
    #
1320
    push @config, "element * /main/0 -mkbranch $opt_branch" if $opt_branch;
1321
 
1322
    #
1323
    #   Load rule
1324
    #   Use ROOT_VOB, unless the user has specified a path
1325
    #   Quote the path so that spaces will be correcly handled
1326
    #
1327
    push @config, "load $ROOT_VOB" unless $opt_path;
1328
    push @config, "load \"$VOB_PREFIX$opt_path\"" if $opt_path;
1329
 
1330
    FileCreate ($config_file, \@config);
1331
    return $config_file;
1332
}
1333
 
1334
#-------------------------------------------------------------------------------
1335
#   Documentation
1336
#
1337
 
1338
=pod
1339
 
1340
=head1 NAME
1341
 
1342
jats_ccrelease - Build a package given a clearcase label
1343
 
1344
=head1 SYNOPSIS
1345
 
1346
  jats ccrelease [options] [-label=]label | -config=config_spec
1347
 
1348
 Options:
1349
    -help              - brief help message
1350
    -help -help        - Detailed help message
1351
    -man               - Full documentation
1352
    -label=xxx         - Clearcase label
1353
    -spec=xxx          - Same as -label=xxx
1354
    -path=xxx          - Source Path
1355
    -view=xxx          - Modify the name of the created view
1356
    -vob=vobname       - VOB name
1357
    -build=xxx         - Package Name to build
1358
    -root=xxx          - Root directory for generated view
1359
    -latestroot=xxx    - Use the LATEST rootlevel directory 'xxx'
1360
    -[mk]branch=xxx    - Will create a view with a branch rule
1361
    -config=xxx        - Create a view with the provided config spec
1362
    -tag=xxx           - Alternate tag used with in the ViewTag
1363
    -extract           - Extract the view and exit
1364
    -extractfiles      - Extract files, without a view
1365
    -cache             - Refresh local dpkg_archive cache
1366
    -delete            - Remove any existing view and exit
1367
    -debugOnly         - Make only the debug version
1368
    -prodOnly          - Make only the production version
1369
    -[no]dpkg          - Transfer package into dpkg_archive
1370
    -[no]copy          - Transfer pkg directory to the current user directory
1371
    -[no]reuse         - Reuse the view
1372
    -[no]test          - Test package build. Implies nocopy and nodpkg
1373
    -[no]keep          - Keep the view after the build
1374
    -[no]lock          - Lock labels
1375
    -[no]beta          - Release a beta package
1376
    -[no]merge         - Merge packages into dpkg_archive
1377
    -[no]runtests      - Run units tests. Default is runtests
1378
    -[no]prefix        - Supress user prefix in view name. Default prefix is USER
1379
 
1380
=head1 OPTIONS
1381
 
1382
=over 8
1383
 
1384
=item B<-help>
1385
 
1386
Print a brief help message and exits.
1387
 
1388
=item B<-help -help>
1389
 
1390
Print a detailed help message with an explanation for each option.
1391
 
1392
=item B<-man>
1393
 
1394
Prints the manual page and exits.
1395
 
1396
=item B<-label> or B<-spec>
1397
 
1398
The ClearCase label to use as the base for the view.
1399
 
1400
Eg: daf_utils_math_3.2.1
1401
 
1402
=item B<-view name>
1403
 
1404
Specified an alternate view name and tag to be used. This option does not provide the
1405
full name of the view.
1406
 
1407
    The view tag will be : "${USER}_${MACHINENAME}_${TAG}_${NAME}"
1408
    The view path will be: "${USER}_${NAME}"
1409
 
1410
The default "NAME" is the first label specified.
1411
The default "TAG" is build. See B<-tag=tagname>.
1412
 
1413
If the user provides a view "name" that is prefixed with their user name
1414
('${USER}_'), then the username will be stripped of for internal processing.
1415
This allows a user to provide a view path when deleting a view.
1416
 
1417
=item B<-path=xxx>
1418
 
1419
Specifies the source path to the root of the extracted file tree. This option has several uses:
1420
 
1421
=over 8
1422
 
1423
=item   *
1424
 
1425
Provide a sanity test of the "Source Path" item within Release Manager
1426
 
1427
=item   *
1428
 
1429
Specify the VOB that contains the source. The VOB name will be extracted and
1430
used as the B<-vob> parameter.
1431
 
1432
=item   *
1433
 
1434
Limit the work to do in extracting the file tree.
1435
 
1436
=back
1437
 
1438
=item B<-vob=xxx>
1439
 
1440
Specifies the Clearcase VOB in which the clearcase label will be located.
1441
This is used as the basis for locating and loading the files within the view.
1442
 
1443
By default this utility will examine all the VOBs for the label.
1444
 
1445
=item B<-build=xxx>
1446
 
1447
This option allows the user to specify the packages to be built and the
1448
order in which the packages are to be built.
1449
This is useful if the extracted view contains multiple build files
1450
 
1451
This option may be used multiple times.
1452
 
1453
There are two forms in which the build target can be specified. It can be
1454
specified as a full package name and vesrion, or as a package name and the
1455
project suffix.
1456
 
1457
By default the program will assume that there is only one build file in the
1458
view and will not build if multiple files are present, unless the package to be
1459
built can be resolved.
1460
 
1461
The location mechanism operates for both JATS and ANT build files.
1462
 
1463
Example: -build=jats-api.1.0.0000.cr
1464
 
1465
This will locate the build file that builds version 1.0.0000.cr of the jats-api
1466
package. The version numbers must match exactly.
1467
 
1468
Example: -build=jats-api.cr -build=jats-lib.cr
1469
 
1470
This will located the build files that build the jats_api (cr) package and the
1471
jats-lib (cr) package. The version of the packages will not be considered.
1472
 
1473
=item B<-root=xxx>
1474
 
1475
This option allows the location of the generated view to be specified on the
1476
command line. The environment variable GBE_VIEWBASE provides the same feature,
1477
but it will affect all the view created.
1478
 
1479
The default location is:
1480
 
1481
=over 8
1482
 
1483
=item WINDOWS
1484
 
1485
c:\clearcase
1486
 
1487
=item Unix
1488
 
1489
$(HOME)/jats_cbuilder
1490
 
1491
If the comamnd is invoked within a development sandbox, then the default
1492
location will be the root directory of the development sandbox.
1493
 
1494
=back
1495
 
1496
=item B<-latestroot=xxx>
1497
 
1498
This option enables a work around for a bad-labelling practice that has existed
1499
in the past. This LATEST version of the named (xxx) branch will be added to
1500
the config spec used to create the view.
1501
 
1502
This is a work around for a problem where the top-level directory in the VOB has
1503
not been labelled. This can result in unreproducible builds.
1504
 
1505
This option allows the utility to construct a view, but the user SHOULD label
1506
the root level directory to correct the problem.
1507
 
1508
The use of this switch will add the following lines to the config spec:
1509
 
1510
    element -directory /DPG_SWBase /main/xxxx/LATEST
1511
 
1512
=item B<-branch=xxx or -mkbranch=xxx>
1513
 
1514
This option will create a view such that files that are checked out will be
1515
checked out on the named branch. This is intended to facilitate the maintenance
1516
of existing packages - the creation of a patch.
1517
 
1518
The named branch must exist within the VOB containing the label. The script will
1519
check for its existence.
1520
 
1521
The use of this switch will add the following lines to the config spec:
1522
 
1523
    element * .../xxx/LATEST
1524
    element * {label} -mkbranch xxx
1525
    element * /main/0 -mkbranch xxx
1526
 
1527
=item B<-config=config_spec>
1528
 
1529
This option is an alternate mechanism to create a static view. The view will be
1530
based on the provided configuration spec. This view cannot be used to release a package.
1531
The option is intended to simplify development.
1532
 
1533
This option is incompatibale with:
1534
 
1535
    -release
1536
    -label
1537
    -branch
1538
    -path
1539
    -vob
1540
 
1541
 
1542
=item B<-tag=text>
1543
 
1544
This option alters the ClearCase view tag created for the view. It allows
1545
the creation of multiple views based on the same label. Intended to be used in
1546
the automated build system to create unique views tags.
1547
 
1548
The default tag is 'build'.
1549
 
1550
=item B<-extract>
1551
 
1552
With this option the view is created and the left in place. The user may then
1553
access the files within the view. The view should not be used for a
1554
production release.
1555
 
1556
=item B<-extractfiles>
1557
 
1558
With this option the utility will create a dynamic view and transfer files from
1559
the view to the user's tararget. The dynamic view is then removed.
1560
 
1561
This command is intended to simplify the process of creating an escrow.
1562
 
1563
=item B<-cache>
1564
 
1565
Forces external packages to be placed in the local dpkg_archive cache.
1566
 
1567
The normal operation is to copy the packages, only if they do not already exist
1568
in the local cache. This option may be used to ensure that the local copy is
1569
correct and up to date.
1570
 
1571
=item B<-delete>
1572
 
1573
Delete the view used by the program, if it exists. This option may be used to
1574
cleanup after an error.
1575
 
1576
Note: Ensure that no files are open in the view and that the users current
1577
working directory is not in the view as these will prevent the view from being
1578
deleted.
1579
 
1580
 
1581
=item B<-debugOnly>
1582
 
1583
Make only the debug version of the package. The default it to create both the
1584
debug and production version of the package. The type of build may be  further
1585
limited by options within the package.
1586
 
1587
=item B<-prodOnly>
1588
 
1589
Make only the production version of the package. The default it to create both the
1590
debug and production version of the package. The type of build may be  further
1591
limited by options within the package.
1592
 
1593
=item B<-[no]dpkg>
1594
 
1595
Copy the generated package into dpkg_archive. This is the default mode of
1596
operation.
1597
 
1598
=item B<-[no]copy>
1599
 
1600
Copy the built "pkg" directory to the users current directory. The entire
1601
"pkg" subdirectory includes the full package named directory for the package
1602
that has been built.
1603
 
1604
=item B<-[no]reuse>
1605
 
1606
This flag allows the view created by the program to be re-used.
1607
 
1608
=over 8
1609
 
1610
=item 1. The view is not deleted before being populated.
1611
 
1612
=item 2. The view will not be populated if it does exist.
1613
 
1614
=item 3. The view will not be deleted at the end the process.
1615
 
1616
=back
1617
 
1618
This option is useful for debugging a build process.
1619
 
1620
=item B<-[no]test>
1621
 
1622
Test the building of the package. This option implies "nocopy" and "nodpkg".
1623
 
1624
=item B<-[no]keep>
1625
 
1626
Keep the clearcase view after the build. The default option is "nokeep"
1627
 
1628
This option is different to the "reuse" in that the view will be deleted, if
1629
it exists, before the build, but will be retained at the completion of the
1630
process. The user may then manually extract the created package.
1631
 
1632
The view may be deleted with the the "delete" option; taking care to ensure that
1633
no files are open in the view and that the users current working directory is
1634
not in the view.
1635
 
1636
=item B<-[no]lock>
1637
 
1638
Lock any unlocked labels before attempting the build. This operation may be used
1639
to ensure that a release build does not fail due to the labels not being locked.
1640
The label is locked before the view is constructed and populated.
1641
 
1642
This operation may fail if the user does not "own" the label.
1643
 
1644
=item B<-[no]beta>
1645
 
1646
This option overrides many of the package release tests to allow a beta package
1647
to be released.
1648
 
1649
=item B<-[no]merge>
1650
 
1651
This option will merge packages being built on multiple machines into
1652
dpkg_archive. By default, if a package already exists in the archive it will be
1653
deleted and replaced. With this option the package will be merged. The merge
1654
process does not over write files found in the archive.
1655
 
1656
=item B<-[no]runtests>
1657
 
1658
This option will allow the suppression of the running of the unit tests included
1659
with the component. By default the tests are run. This can be suppressed
1660
without affecting the release process.
1661
 
1662
=back
1663
 
1664
=head1 DESCRIPTION
1665
 
1666
This program is the primary tool for the creation, recreation and release of
1667
packages within the B<ERG> build environment, although the program can perform a
1668
number of very useful operations required during normal development and
1669
maintenance.
1670
 
1671
This program will build a system containing one or more inter-related build
1672
files using the JATS build tools.
1673
 
1674
In normal operation the program will:
1675
 
1676
=over 8
1677
 
1678
=item Remove View
1679
 
1680
Remove any existing view of the same name. The view will not be removed if it
1681
contains checked-out files.
1682
 
1683
The view removal may fail if there are any files B<open> within the view or if
1684
any shell has a subdirectory of the view set as a B<current working directory>.
1685
 
1686
=item Locate VOB
1687
 
1688
Locate the VOB that contains the specified label or labels. If multiple labels
1689
are specified they must all exist in the same VOB.
1690
 
1691
=item Lock Labels
1692
 
1693
Lock any unlocked labels, if required.
1694
 
1695
=item Create the view
1696
 
1697
Create a static view to containing the files describes by the Clearcase
1698
label being processed.
1699
 
1700
The program uses a fixed view name. If this view exists then item
1701
will be deleted before item is created again. Each build starts in a clean view.
1702
 
1703
=item Populate the View
1704
 
1705
Loads files into the static view. The user label and the VOB name are used to
1706
created a clearcase configuration specification. This configuration
1707
specification is then activated and all files within the specified VOB will be
1708
loaded into the view if they match the user supplied label.
1709
 
1710
This processed normally results in a lot of error messages that can be ignored.
1711
 
1712
I<Note:> The label placed on the component to be built must extend to the
1713
root of the VOB, otherwise the directory path will not be extracted nor will
1714
the files within the component.
1715
 
1716
I<Note:> If the view is simply being extracted, then this is the end of the
1717
program. The extracted view is left in place.
1718
 
1719
=item Sanity Test
1720
 
1721
If the build is being used as a release into dpkg_archive then
1722
various tests are performed to ensure the repeatability of the view and the
1723
build. These tests include:
1724
 
1725
=over 8
1726
 
1727
=item   * The view must be constructed from one label
1728
 
1729
=item   * That label must be locked
1730
 
1731
=item   * The labelled view must contain exactly one build file
1732
 
1733
=item   * The view cannot have been re-used.
1734
 
1735
=back
1736
 
1737
=item Locate build files
1738
 
1739
Locate the build file within the view.
1740
 
1741
It is an error to have multiple build files within the view, unless the
1742
B<-build> option is used. By default, only one package will be built.
1743
 
1744
=item Package the results
1745
 
1746
Use JATS to build and make the package.
1747
 
1748
The resultant package may be copied to a numbers of locations. These include
1749
 
1750
=over 8
1751
 
1752
=item 1
1753
 
1754
The master dpkg_archive as an official release. This is the default operation.
1755
 
1756
=item 2
1757
 
1758
The users current directory. The package directory from the built package is
1759
copied locally. The "pkg" directory is copied. This is only performed with the
1760
B<-copy> option.
1761
 
1762
=back
1763
 
1764
=item Delete the view
1765
 
1766
Delete the view and all related files.
1767
 
1768
The view will not be deleted if an error was detected in the build process, or
1769
the "reuse" or "keep" options are present.
1770
 
1771
=back
1772
 
1773
=cut
1774