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