Subversion Repositories DevTools

Rev

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