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