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