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");
245 dpurdie 638
    my @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");
1213
    open (CFG, ">$config_file") or Error ("Cannot create config spec");
1214
    print CFG "element * CHECKEDOUT\n";
1215
    print CFG "element .../lost+found -none\n";
1216
    print CFG "element * .../$opt_branch/LATEST\n" if $opt_branch;
1217
    foreach (@opt_spec)
1218
    {
1219
        print CFG "element * $_";
1220
        print CFG " -mkbranch $opt_branch" if $opt_branch;
1221
        print CFG "\n";
1222
 
1223
    }
1224
 
1225
    #
1226
    #   Packages SHOULD be labled to the root.
1227
    #   Do not extend this list fix the package - fix the labels in the VOB.
1228
    #
1229
    if ( $opt_latest_root )
1230
    {
1231
        print CFG "element -directory $ROOT_VOB .../$opt_latest_root/LATEST\n";
1232
        print CFG "element -directory $ROOT_VOB .../mass_dev/LATEST\n";
1233
        print CFG "element -directory $ROOT_VOB /main/LATEST\n";
1234
    }
1235
 
1236
    #
1237
    #   Do not branch directories above the load path
1238
    #   Load only the version on /main
1239
    #       UNIX: Don't play with the /vobs (won't work)
1240
    #
1241
    if ( $opt_branch )
1242
    {
1243
        if ( $opt_path )
1244
        {
1245
            my $fulldir = $VOB_PREFIX;
1246
            my @parts = split ('/', $opt_path);
1247
            shift @parts;
1248
            foreach my $dir ( @parts )
1249
            {
1250
                $fulldir .= "/$dir";
1251
                print CFG "element -dir $fulldir /main/LATEST\n"
1252
            }
1253
        }
1254
        else
1255
        {
1256
            print CFG "element -dir $ROOT_VOB /main/LATEST\n";
1257
        }
1258
    }
1259
 
1260
    #
1261
    #   Branch rule:
1262
    #   Need /main/0 to allow files to be added to the view
1263
    #   Will get a lot of stuff, so take care not to label it all
1264
    #
1265
    print CFG "element * /main/0 -mkbranch $opt_branch\n" if $opt_branch;
1266
 
1267
    #
1268
    #   Load rule
1269
    #   Use ROOT_VOB, unless the user has specified a path
235 dpurdie 1270
    #   Quote the path so that spaces will be correcly handled
227 dpurdie 1271
    #
1272
    print CFG "load $ROOT_VOB\n" unless $opt_path;
235 dpurdie 1273
    print CFG "load \"$VOB_PREFIX$opt_path\"\n" if $opt_path;
227 dpurdie 1274
    close CFG;
1275
 
1276
    return $config_file;
1277
}
1278
 
1279
#-------------------------------------------------------------------------------
1280
#   Documentation
1281
#
1282
 
1283
=pod
1284
 
1285
=head1 NAME
1286
 
1287
jats_cbuilder - Build a package given a clearcase label
1288
 
1289
=head1 SYNOPSIS
1290
 
1291
  jats cbuilder [options] [-label=]label | -config=config_spec
1292
 
1293
 Options:
1294
    -help              - brief help message
1295
    -help -help        - Detailed help message
1296
    -man               - Full documentation
1297
    -label=xxx         - Clearcase label
1298
    -spec=xxx          - Same as -label=xxx
1299
    -path=xxx          - Source Path
1300
    -view=xxx          - Modify the name of the created view
1301
    -vob=vobname       - VOB name
245 dpurdie 1302
    -build=xxx         - Package Name to build
227 dpurdie 1303
    -root=xxx          - Root directory for generated view
1304
    -latestroot=xxx    - Use the LATEST rootlevel directory 'xxx'
1305
    -[mk]branch=xxx    - Will create a view with a branch rule
1306
    -config=xxx        - Create a view with the provided config spec
1307
    -tag=xxx           - Alternate tag used with in the ViewTag
1308
    -extract           - Extract the view and exit
1309
    -extractfiles      - Extract files, without a view
1310
    -cache             - Refresh local dpkg_archive cache
1311
    -delete            - Remove any existing view and exit
1312
    -debugOnly         - Make only the debug version
1313
    -prodOnly          - Make only the production version
1314
    -[no]dpkg          - Transfer package into dpkg_archive
1315
    -[no]copy          - Transfer pkg directory to the current user directory
1316
    -[no]reuse         - Reuse the view
1317
    -[no]test          - Test package build. Implies nocopy and nodpkg
1318
    -[no]keep          - Keep the view after the build
1319
    -[no]lock          - Lock labels
1320
    -[no]beta          - Release a beta package
1321
    -[no]merge         - Merge packages into dpkg_archive
1322
    -[no]runtests      - Run units tests. Default is runtests
1323
    -[no]prefix        - Supress user prefix in view name. Default prefix is USER
1324
 
1325
=head1 OPTIONS
1326
 
1327
=over 8
1328
 
1329
=item B<-help>
1330
 
1331
Print a brief help message and exits.
1332
 
1333
=item B<-help -help>
1334
 
1335
Print a detailed help message with an explanation for each option.
1336
 
1337
=item B<-man>
1338
 
1339
Prints the manual page and exits.
1340
 
1341
=item B<-label> or B<-spec>
1342
 
1343
The ClearCase label to use as the base for the view.
1344
 
1345
Eg: daf_utils_math_3.2.1
1346
 
1347
=item B<-view name>
1348
 
1349
Specified an alternate view name and tag to be used. This option does not provide the
1350
full name of the view.
1351
 
1352
    The view tag will be : "${USER}_${MACHINENAME}_${TAG}_${NAME}"
1353
    The view path will be: "${USER}_${NAME}"
1354
 
1355
The default "NAME" is the first label specified.
1356
The default "TAG" is build. See B<-tag=tagname>.
1357
 
1358
If the user provides a view "name" that is prefixed with their user name
1359
('${USER}_'), then the username will be stripped of for internal processing.
1360
This allows a user to provide a view path when deleting a view.
1361
 
1362
=item B<-path=xxx>
1363
 
1364
Specifies the source path to the root of the extracted file tree. This option has several uses:
1365
 
1366
=over 8
1367
 
1368
=item   *
1369
 
1370
Provide a sanity test of the "Source Path" item within Release Manager
1371
 
1372
=item   *
1373
 
1374
Specify the VOB that contains the source. The VOB name will be extracted and
1375
used as the B<-vob> parameter.
1376
 
1377
=item   *
1378
 
1379
Limit the work to do in extracting the file tree.
1380
 
1381
=back
1382
 
1383
=item B<-vob=xxx>
1384
 
1385
Specifies the Clearcase VOB in which the clearcase label will be located.
1386
This is used as the basis for locating and loading the files within the view.
1387
 
1388
By default this utility will examine all the VOBs for the label.
1389
 
1390
=item B<-build=xxx>
1391
 
245 dpurdie 1392
This option allows the user to specify the packages to be built and the
1393
order in which the packages are to be built.
227 dpurdie 1394
This is useful if the extracted view contains multiple build files
1395
 
245 dpurdie 1396
This option may be used multiple times.
227 dpurdie 1397
 
245 dpurdie 1398
There are two forms in which the build target can be specified. It can be
1399
specified as a full package name and vesrion, or as a package name and the
1400
project suffix.
1401
 
227 dpurdie 1402
By default the program will assume that there is only one build file in the
245 dpurdie 1403
view and will not build if multiple files are present, unless the package to be
1404
built can be resolved.
227 dpurdie 1405
 
245 dpurdie 1406
The location mechanism operates for both JATS and ANT build files.
227 dpurdie 1407
 
245 dpurdie 1408
Example: -build=jats-api.1.0.0000.cr
227 dpurdie 1409
 
245 dpurdie 1410
This will locate the build file that builds version 1.0.0000.cr of the jats-api
1411
package. The version numbers must match exactly.
227 dpurdie 1412
 
245 dpurdie 1413
Example: -build=jats-api.cr -build=jats-lib.cr
227 dpurdie 1414
 
245 dpurdie 1415
This will located the build files that build the jats_api (cr) package and the
1416
jats-lib (cr) package. The version of the packages will not be considered.
227 dpurdie 1417
 
1418
=item B<-root=xxx>
1419
 
1420
This option allows the location of the generated view to be specified on the
1421
command line. The environment variable GBE_VIEWBASE provides the same feature,
1422
but it will affect all the view created.
1423
 
1424
The default location is:
1425
 
1426
=over 8
1427
 
1428
=item WINDOWS
1429
 
1430
c:\clearcase
1431
 
1432
=item Unix
1433
 
1434
$(HOME)/jats_cbuilder
1435
 
1436
If the comamnd is invoked within a development sandbox, then the default
1437
location will be the root directory of the development sandbox.
1438
 
1439
=back
1440
 
1441
=item B<-latestroot=xxx>
1442
 
1443
This option enables a work around for a bad-labelling practice that has existed
1444
in the past. This LATEST version of the named (xxx) branch will be added to
1445
the config spec used to create the view.
1446
 
1447
This is a work around for a problem where the top-level directory in the VOB has
1448
not been labelled. This can result in unreproducible builds.
1449
 
1450
This option allows the utility to construct a view, but the user SHOULD label
1451
the root level directory to correct the problem.
1452
 
1453
The use of this switch will add the following lines to the config spec:
1454
 
1455
    element -directory /DPG_SWBase /main/xxxx/LATEST
1456
 
1457
=item B<-branch=xxx or -mkbranch=xxx>
1458
 
1459
This option will create a view such that files that are checked out will be
1460
checked out on the named branch. This is intended to facilitate the maintenance
1461
of existing packages - the creation of a patch.
1462
 
1463
The named branch must exist within the VOB containing the label. The script will
1464
check for its existence.
1465
 
1466
The use of this switch will add the following lines to the config spec:
1467
 
1468
    element * .../xxx/LATEST
1469
    element * {label} -mkbranch xxx
1470
    element * /main/0 -mkbranch xxx
1471
 
1472
=item B<-config=config_spec>
1473
 
1474
This option is an alternate mechanism to create a static view. The view will be
1475
based on the provided configuration spec. This view cannot be used to release a package.
1476
The option is intended to simplify development.
1477
 
1478
This option is incompatibale with:
1479
 
1480
    -release
1481
    -label
1482
    -branch
1483
    -path
1484
    -vob
1485
 
1486
 
1487
=item B<-tag=text>
1488
 
1489
This option alters the ClearCase view tag created for the view. It allows
1490
the creation of multiple views based on the same label. Intended to be used in
1491
the automated build system to create unique views tags.
1492
 
1493
The default tag is 'build'.
1494
 
1495
=item B<-extract>
1496
 
1497
With this option the view is created and the left in place. The user may then
1498
access the files within the view. The view should not be used for a
1499
production release.
1500
 
1501
=item B<-extractfiles>
1502
 
1503
With this option the utility will create a dynamic view and transfer files from
1504
the view to the user's tararget. The dynamic view is then removed.
1505
 
1506
This command is intended to simplify the process of creating an escrow.
1507
 
1508
=item B<-cache>
1509
 
1510
Forces external packages to be placed in the local dpkg_archive cache.
1511
 
1512
The normal operation is to copy the packages, only if they do not already exist
1513
in the local cache. This option may be used to ensure that the local copy is
1514
correct and up to date.
1515
 
1516
=item B<-delete>
1517
 
1518
Delete the view used by the program, if it exists. This option may be used to
1519
cleanup after an error.
1520
 
1521
Note: Ensure that no files are open in the view and that the users current
1522
working directory is not in the view as these will prevent the view from being
1523
deleted.
1524
 
1525
 
1526
=item B<-debugOnly>
1527
 
1528
Make only the debug version of the package. The default it to create both the
1529
debug and production version of the package. The type of build may be  further
1530
limited by options within the package.
1531
 
1532
=item B<-prodOnly>
1533
 
1534
Make only the production version of the package. The default it to create both the
1535
debug and production version of the package. The type of build may be  further
1536
limited by options within the package.
1537
 
1538
=item B<-[no]dpkg>
1539
 
1540
Copy the generated package into dpkg_archive. This is the default mode of
1541
operation.
1542
 
1543
=item B<-[no]copy>
1544
 
1545
Copy the built "pkg" directory to the users current directory. The entire
1546
"pkg" subdirectory includes the full package named directory for the package
1547
that has been built.
1548
 
1549
=item B<-[no]reuse>
1550
 
1551
This flag allows the view created by the program to be re-used.
1552
 
1553
=over 8
1554
 
1555
=item 1. The view is not deleted before being populated.
1556
 
1557
=item 2. The view will not be populated if it does exist.
1558
 
1559
=item 3. The view will not be deleted at the end the process.
1560
 
1561
=back
1562
 
1563
This option is useful for debugging a build process.
1564
 
1565
=item B<-[no]test>
1566
 
1567
Test the building of the package. This option implies "nocopy" and "nodpkg".
1568
 
1569
=item B<-[no]keep>
1570
 
1571
Keep the clearcase view after the build. The default option is "nokeep"
1572
 
1573
This option is different to the "reuse" in that the view will be deleted, if
1574
it exists, before the build, but will be retained at the completion of the
1575
process. The user may then manually extract the created package.
1576
 
1577
The view may be deleted with the the "delete" option; taking care to ensure that
1578
no files are open in the view and that the users current working directory is
1579
not in the view.
1580
 
1581
=item B<-[no]lock>
1582
 
1583
Lock any unlocked labels before attempting the build. This operation may be used
1584
to ensure that a release build does not fail due to the labels not being locked.
1585
The label is locked before the view is constructed and populated.
1586
 
1587
This operation may fail if the user does not "own" the label.
1588
 
1589
=item B<-[no]beta>
1590
 
1591
This option overrides many of the package release tests to allow a beta package
1592
to be released.
1593
 
1594
=item B<-[no]merge>
1595
 
1596
This option will merge packages being built on multiple machines into
1597
dpkg_archive. By default, if a package already exists in the archive it will be
1598
deleted and replaced. With this option the package will be merged. The merge
1599
process does not over write files found in the archive.
1600
 
1601
=item B<-[no]runtests>
1602
 
1603
This option will allow the suppression of the running of the unit tests included
1604
with the component. By default the tests are run. This can be suppressed
1605
without affecting the release process.
1606
 
1607
=back
1608
 
1609
=head1 DESCRIPTION
1610
 
1611
This program is the primary tool for the creation, recreation and release of
1612
packages within the B<ERG> build environment, although the program can perform a
1613
number of very useful operations required during normal development and
1614
maintenance.
1615
 
1616
This program will build a system containing one or more inter-related build
1617
files using the JATS build tools.
1618
 
1619
In normal operation the program will:
1620
 
1621
=over 8
1622
 
1623
=item Remove View
1624
 
1625
Remove any existing view of the same name. The view will not be removed if it
1626
contains checked-out files.
1627
 
1628
The view removal may fail if there are any files B<open> within the view or if
1629
any shell has a subdirectory of the view set as a B<current working directory>.
1630
 
1631
=item Locate VOB
1632
 
1633
Locate the VOB that contains the specified label or labels. If multiple labels
1634
are specified they must all exist in the same VOB.
1635
 
1636
=item Lock Labels
1637
 
1638
Lock any unlocked labels, if required.
1639
 
1640
=item Create the view
1641
 
1642
Create a static view to containing the files describes by the Clearcase
1643
label being processed.
1644
 
1645
The program uses a fixed view name. If this view exists then item
1646
will be deleted before item is created again. Each build starts in a clean view.
1647
 
1648
=item Populate the View
1649
 
1650
Loads files into the static view. The user label and the VOB name are used to
1651
created a clearcase configuration specification. This configuration
1652
specification is then activated and all files within the specified VOB will be
1653
loaded into the view if they match the user supplied label.
1654
 
1655
This processed normally results in a lot of error messages that can be ignored.
1656
 
1657
I<Note:> The label placed on the component to be built must extend to the
1658
root of the VOB, otherwise the directory path will not be extracted nor will
1659
the files within the component.
1660
 
1661
I<Note:> If the view is simply being extracted, then this is the end of the
1662
program. The extracted view is left in place.
1663
 
1664
=item Sanity Test
1665
 
1666
If the build is being used as a release into dpkg_archive then
1667
various tests are performed to ensure the repeatability of the view and the
1668
build. These tests include:
1669
 
1670
=over 8
1671
 
1672
=item   * The view must be constructed from one label
1673
 
1674
=item   * That label must be locked
1675
 
1676
=item   * The labelled view must contain exactly one build file
1677
 
1678
=item   * The view cannot have been re-used.
1679
 
1680
=back
1681
 
1682
=item Locate build files
1683
 
1684
Locate the build file within the view.
1685
 
1686
It is an error to have multiple build files within the view, unless the
1687
B<-build> option is used. By default, only one package will be built.
1688
 
1689
=item Package the results
1690
 
1691
Use JATS to build and make the package.
1692
 
1693
The resultant package may be copied to a numbers of locations. These include
1694
 
1695
=over 8
1696
 
1697
=item 1
1698
 
1699
The master dpkg_archive as an official release. This is the default operation.
1700
 
1701
=item 2
1702
 
1703
The users current directory. The package directory from the built package is
1704
copied locally. The "pkg" directory is copied. This is only performed with the
1705
B<-copy> option.
1706
 
1707
=back
1708
 
1709
=item Delete the view
1710
 
1711
Delete the view and all related files.
1712
 
1713
The view will not be deleted if an error was detected in the build process, or
1714
the "reuse" or "keep" options are present.
1715
 
1716
=back
1717
 
1718
=cut
1719