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