Subversion Repositories DevTools

Rev

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