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