Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

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