Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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