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_label.pl
6
# Module type   : Makefile system
7
# Compiler(s)   : n/a
8
# Environment(s):
9
#
10
# Description   : A script to perform a number of labeling operations
11
#                 The script will:
12
#                   create a label
13
#                   lock a label
14
#                   unlock a label
15
#                   label all files below the current directory and
16
#                         all directories above the current directory
17
#
18
# Version   Who      Date        Description
19
# 1.0.0     DDP      04-Feb-05   Created
20
#......................................................................#
21
 
255 dpurdie 22
require 5.006_001;
227 dpurdie 23
use strict;
24
use warnings;
25
use JatsError;
26
use JatsSystem;
27
 
28
use Pod::Usage;                             # required for help support
29
use Getopt::Long;
30
use Cwd;
31
 
32
my $VERSION = "1.2.2";                      # Update this
33
 
34
#
35
#   Options
36
#
37
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
38
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
39
my $opt_help = 0;
40
my $opt_label;
41
my $opt_replace;
42
my $opt_create;
43
my $opt_lock;
44
my $opt_unlock;
45
my $opt_show;
46
my $opt_all;
47
my $opt_remove;
48
my $opt_delete;
49
my @opt_exclude;
50
my $opt_test;
51
my $opt_rename;
52
my $opt_auto;
53
my $opt_clone;
54
my $opt_recurse = 1;
55
my $opt_mine;
56
my $opt_info;
57
my $opt_up = 0;
58
my $opt_smartlock;
59
my $opt_checkout = 2;
60
my @opt_files;
61
my @opt_dirs;
62
my $opt_comment;
63
my $opt_vob;
64
my $opt_user;
65
 
66
my $label;
67
my $user_cwd;
68
my @error_list;
69
my $last_result;
70
my $opr_done;
71
my $label_exists = 0;
72
my $build_count = 0;
73
my $vob_desc ='';
74
 
75
#
76
#   Globals
77
#
78
my $USER = $ENV{'USER'};
79
my $UNIX = $ENV{'GBE_UNIX'};
80
my $autobuild = $ENV{'GBE_ABT'};
81
my $UNIX_VOB_PREFIX = '/vobs';
82
my $VOB_SEP = $UNIX ? '/' : '\\';
83
 
84
#-------------------------------------------------------------------------------
85
# Function        : Mainline Entry Point
86
#
87
# Description     :
88
#
89
# Inputs          :
90
#
91
my $result = GetOptions (
309 dpurdie 92
                "help:+"        => \$opt_help,
93
                "manual:3"      => \$opt_help,
94
                "verbose:+"     => \$opt_verbose,
227 dpurdie 95
                "label"         => \$opt_label,             # Flag
96
                "replace"       => \$opt_replace,           # Flag
97
                "create"        => \$opt_create,            # Flag
98
                "lock"          => \$opt_lock,              # Flag
99
                "unlock"        => \$opt_unlock,            # Flag
100
                "smartlock"     => \$opt_smartlock,         # Flag
101
                "show"          => \$opt_show,              # Flag
102
                "remove"        => \$opt_remove,            # Flag
103
                "delete"        => \$opt_delete,            # Flag
104
                "all"           => \$opt_all,               # Flag
105
                "test"          => \$opt_test,              # Flag
106
                "exclude=s"     => \@opt_exclude,           # Multiple strings
107
                "rename=s"      => \$opt_rename,            # String
108
                "clone=s"       => \$opt_clone,             # String
109
                "auto"          => \$opt_auto,              # Flag
110
                "recurse!",     => \$opt_recurse,           # [No]Flag
111
                "mine!",        => \$opt_mine,              # Flag
112
                "info",         => \$opt_info,              # Flag
113
                "up",           => \$opt_up,                # Flag
114
                "checkout!",    => \$opt_checkout,          # [No]Flag
115
                "files=s"       => \@opt_files,             # Multiple strings
116
                "dirs=s"        => \@opt_dirs,              # Multiple strings
117
                "comment=s"     => \$opt_comment,           # String
118
                "vob=s"         => \$opt_vob,               # String
119
                "user=s"        => \$opt_user,              # String
120
 
121
                );
122
 
123
                #
124
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
125
                #
126
 
127
#
128
#   Process help and manual options
129
#
130
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
309 dpurdie 131
pod2usage(-verbose => 1) if ( $opt_help == 2 );
132
pod2usage(-verbose => 2) if ( $opt_help > 2 );
227 dpurdie 133
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ( $#ARGV < 0 );
134
 
135
#
136
#   Configure the error reporting process now that we have the user options
137
#
138
ErrorConfig( 'name'    =>'LABEL',
139
             'verbose' => $opt_verbose,
140
             'on_exit' => \&display_error_list
141
            );
142
 
143
#
144
#   Validate user options
145
#   Use either -spec or one command line argument
146
#
147
Error ("No labels provided") if ( $#ARGV < 0);
148
Error ("Too many labels provided") if ( $#ARGV > 0);
149
Error ("Conflicting options") if ( $opt_clone && $opt_label );
150
$label = $ARGV[0];
151
 
152
#
153
#   Allow the exclude list to contain comma seperated names
154
#
155
@opt_exclude = split( /,/,join(',',@opt_exclude));
156
@opt_files   = split( /,/,join(',',@opt_files));
157
@opt_dirs    = split( /,/,join(',',@opt_dirs));
158
 
159
#
160
#   Determine the user
161
#
162
Error ("USER name not determined" )
163
    unless ( $USER );
164
$opt_user = $USER unless ( $opt_user );
165
 
166
#
167
#   Ensure that the 'cleartool' program can be located
168
#
169
Verbose ("Locate clearcase utility in users path");
170
Error ("Cannot locate the 'cleartool' utility in the users PATH")
171
    unless ( LocateProgInPath('cleartool', '--All') );
172
 
173
#-------------------------------------------------------------------------------
174
#   Construct a vob descriptor, if required
175
#
176
if ( $opt_vob )
177
{
178
    Error ("-vob option cannot be used with this command")
179
        if ( $opt_clone || $opt_label || $opt_show || $opt_remove  );
180
 
181
    $vob_desc = $UNIX_VOB_PREFIX if ( $UNIX );
182
    $vob_desc = '@/' . $vob_desc . '/' . $opt_vob;
183
    $vob_desc =~ s~//~/~g;
184
    $vob_desc =~ s~/~$VOB_SEP~g;
185
}
186
 
187
#-------------------------------------------------------------------------------
188
#   Check to see if the clone source label exists
189
#       Create a label
190
#
191
if ( $opt_clone )
192
{
193
    Verbose ("Check clone label");
194
    ClearCmd ("describe", "-short", "lbtype:$opt_clone" );
195
    Error ("Clone source label does not exist") if ( @error_list );
196
}
197
 
198
#-------------------------------------------------------------------------------
199
#   Check to see if the label exists
200
#
201
Verbose ("Check label");
202
ClearCmd ("describe", "-short", "lbtype:$label$vob_desc" ) unless $opt_test;
203
$label_exists = 1 unless( $opt_test || grep ( /Label type not found/, @error_list ));
204
Verbose ("Check label: $label_exists");
205
 
206
 
207
#-------------------------------------------------------------------------------
208
#   Process command
209
#       Create a label
210
#
211
if ( $opt_create || ( $opt_auto && ! $label_exists    ) )
212
{
213
    Verbose ("Create label");
214
    Error ("Label already exists") if ( $label_exists );
215
 
216
    my $opts = '-nc';
217
    $opts = '-c "' . $opt_comment . '"' if ( $opt_comment );
218
 
219
    ClearCmd ("mklbtype", $opts, "$label$vob_desc" ) unless $opt_test;
220
    Error ("Program Terminated") if ( @error_list );
221
    $opr_done = 1;
222
}
223
 
224
#-------------------------------------------------------------------------------
225
#   Ensure that the specified label exists
226
#
227
    Verbose ("Check label");
228
    ClearCmd ("describe", "-short", "lbtype:$label$vob_desc" ) unless $opt_test;
229
    Error ("Program Terminated") if ( @error_list );
230
 
231
#-------------------------------------------------------------------------------
232
#   Process command
233
#       Unlock a label - if it was locked
234
#
235
if ( $opt_unlock || $opt_smartlock )
236
{
237
    Verbose ("Unlock label");
238
 
239
    ClearCmd ("describe", "-fmt", "%[locked]p", "lbtype:$label$vob_desc" );
240
    unless ( $last_result && $last_result =~ m~unlocked~ )
241
    {
242
        ClearCmd ("unlock", "lbtype:$label$vob_desc" ) unless $opt_test;
243
        Error ("Program Terminated") if ( @error_list );
244
        $opt_lock = 1 if ( $opt_smartlock );
245
    }
246
    $opr_done = 1;
247
}
248
 
249
#-------------------------------------------------------------------------------
250
#   Process command
251
#       Rename a label
252
if ( $opt_rename )
253
{
254
    Verbose ("Rename label");
255
    ClearCmd ("rename", "lbtype:$label$vob_desc", "lbtype:$opt_rename$vob_desc" ) unless $opt_test;
256
    Error ("Program Terminated") if ( @error_list );
257
    $label = $opt_rename;
258
 
259
    #
260
    #   Also rename the owner of the label
261
    #   This facility is used by the build process to rename WIP labels
262
    #   The idea is to prevent the original owner from modifying the label
263
    #
264
    $opt_mine = 1
265
        if ( $opt_mine && ($opt_mine != 0) );
266
 
267
    $opr_done = 1;
268
}
269
 
270
#-------------------------------------------------------------------------------
271
#   Change label ownership
272
#
273
if ( $opt_mine )
274
{
275
    Verbose ("Change label owner: $opt_user");
276
    ClearCmd ("protect", "-chown", $opt_user, "lbtype:$label$vob_desc" ) unless $opt_test;
277
    Error ("Program Terminated") if ( @error_list );
278
 
279
    $opr_done = 1;
280
}
281
 
282
#-------------------------------------------------------------------------------
283
#   Process command
284
#       Label files and directories
285
 
286
if ( $opt_label || ( $opt_auto && ! $opt_clone ) )
287
{
309 dpurdie 288
    my $label_error;
227 dpurdie 289
    my @cmd_opt;
309 dpurdie 290
    my %info;
227 dpurdie 291
    push @cmd_opt, "-replace" if ( $opt_replace );
292
 
293
    #
309 dpurdie 294
    #   Locate and label directories first
295
    #   Label dirs before we locate files as it simplifies the process
296
    #   of avoiding the current directory
297
    #
298
    determine_dirs_to_label(\%info);
299
    DebugDumpData("Directory Data", \%info ) if (IsVerbose (2));
300
    #
301
    #   Label the directories
302
    #
303
    if ( @{$info{'dir_list'}}  )
304
    {
305
        print "Root : $info{'VobRoot'}\n";
306
        foreach  ( @{$info{'dir_list'}} )
307
        {
308
            my $name = $_;
309
            $name =~ s~^$info{'VobRoot'}/~~;
310
            print "Label: $name\n";
311
        }
312
 
313
        ClearCmd ("mklabel", @cmd_opt, $label, @{$info{'dir_list'}} ) unless $opt_test;
314
        $label_error = 1
315
            if ( display_error_list() );
316
    }
317
 
318
    #
319
    #   Locate and label files
320
    #
321
    determine_files_to_label( \%info );
322
    DebugDumpData("File Data", \%info ) if (IsVerbose (2));
323
 
324
    #
325
    #   Label required files
326
    #   Only do a few at a time so as to limit the command line length
327
    #
328
    if ( @{$info{'label_list'}} )
329
    {
330
        print "Label: $_\n" foreach @{$info{'label_list'}};
331
 
332
        #
333
        #   Process the labels in groups
334
        #   The command line does have a finite length
335
        #
336
        my $base = 0;
337
        my $num = $#{$info{'label_list'}};
338
 
339
        while ( $base <= $num )
340
        {
341
            my $end = $base + 10;
342
            $end = $num if ( $end > $num );
343
 
344
            print ".";
345
            ClearCmd ("mklabel", @cmd_opt, $label, @{$info{'label_list'}}[$base .. $end] ) unless ( $opt_test );
346
            $label_error = 1
347
                if ( display_error_list() );
348
            $base = $end + 1;
349
        }
350
        print "\n";
351
    }
352
 
353
    #
354
    #   Generate warnings based on collected data
355
    #
356
    sub show_warning
357
    {
358
        my ($text, $element, $allowed) = @_;
359
        $allowed = 0 unless ( $allowed );
360
        my $count = scalar(@{$info{$element}});
361
        print $text, ': ', $count, "\n"
362
            if ( $count > $allowed );
363
    }
364
 
365
    print "Exclude: $_\n" foreach @{$info{'exclude_list'}};
366
    print "Exclude(/main/0): $_\n" foreach @{$info{'element0_list'}};
367
    print "Missing File: $_\n" foreach @{$info{'missing_files'}};
368
 
369
    print        ("Labels applied:", scalar(@{$info{'label_list'}}) + scalar(@{$info{'dir_list'}}), "\n" );
370
    show_warning ("WARNING: Labels applied to checked out parent directories", 'checked_out_pdirs' );
371
    show_warning ("WARNING: Labels applied to checked out files", 'checked_out_files' );
372
    show_warning ("WARNING: Labels applied to checked out dirs", 'checked_out_dirs' );
373
    show_warning ("WARNING: Labels NOT applied to missing files", 'missing_files' );
374
    show_warning ("WARNING: Labels NOT applied to element-0 of files", 'element0_list' );
375
    print        ("WARNING: Path to the VOB root contains a symbolic link. Labeling incomplete") if ( $info{'is_symlink'} );
376
    show_warning ("WARNING: Multiple build.pl files labeled", 'build_files', 1 );
377
 
378
    Error ("Program Terminated") if ( $label_error );
379
 
380
    #
381
    #   Double check the label process
382
    #   We are seeing issues with ClearCase where a file, or dir, is not being
383
    #   labeled. The following is a quick check. See if there is any thing to
384
    #   label again
385
    #
386
    %info = ();
387
    determine_dirs_to_label ( \%info );
388
    determine_files_to_label( \%info );
389
    if ( @{$info{'dir_list'}}  || @{$info{'label_list'}} )
390
    {
391
        DebugDumpData("DoubleCheck Data", \%info );
392
        Error ('ClearCase label problem detected',
393
               'Please report to david.purdie@vix-erg.com',
394
               'Directories and Files not labled as requested:',
395
               @{$info{'dir_list'}},
396
               @{$info{'label_list'}}
397
               );
398
    }
399
 
400
 
401
    $opr_done = 1;
402
}
403
 
404
#-------------------------------------------------------------------------------
405
#   Process command
406
#       Clone
407
if ( $opt_clone )
408
{
409
    Verbose ("Clone Label");
410
    my @cmd_opt;
411
    push @cmd_opt, "-all" if ($opt_all);
412
 
413
    my @cmd2_opt;
414
    push @cmd2_opt, "-replace" if ( $opt_replace );
415
 
416
    my $count = 0;
417
    my $checked_out_count = 0;
418
 
419
    my $cmd = QuoteCommand ("cleartool", "find", ".", @cmd_opt, "-version", "lbtype($opt_clone)", "-print");
420
    Verbose2($cmd);
421
 
422
    open(CLONECMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
423
    while (<CLONECMD>)
424
    {
425
        chomp;
426
        print($_ . "\n");
427
        $count++;
428
        $checked_out_count++ if ( m/CHECKEDOUT$/ );
429
 
430
        ClearCmd ("mklabel", @cmd2_opt, $label, $_ ) unless ( $opt_test );
431
        last if ( @error_list )
432
    }
433
    close(CLONECMD);
434
 
435
    Error ("Program Terminated") if ( @error_list );
436
    print "Labels applied: $count\n";
437
    print "WARNING: Labels applied to checked out files: $checked_out_count\n" if ( $checked_out_count );
438
    $opr_done = 1;
439
}
440
 
441
 
442
#-------------------------------------------------------------------------------
443
#   Process command
444
#       Show labeled files and directories
445
#       Remove labels
446
 
447
if ( $opt_show || $opt_remove )
448
{
449
    Verbose ("Show Label");
450
    my @cmd_opt;
451
    push @cmd_opt, "-all" if ($opt_all);
452
 
453
    my $cmd = QuoteCommand("cleartool", "find", ".", @cmd_opt, "-version", "lbtype($label)", "-print");
454
    Verbose2($cmd);
455
 
456
    open(SHOWCMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
457
    while (<SHOWCMD>)
458
    {
459
        #
460
        #   Filter output from the user
461
        #
462
        chomp;
463
        print($_ . "\n");
464
 
465
        if ( $opt_remove )
466
        {
467
            ClearCmd ( "rmlabel", $label, $_ ) unless $opt_test;
468
        }
469
 
470
    }
471
    close(SHOWCMD);
472
    $opr_done = 1;
473
}
474
 
475
#-------------------------------------------------------------------------------
476
#   Process command
477
#       Delete a label
478
if ( $opt_delete )
479
{
480
    Verbose ("Delete label");
481
    ClearCmd ("rmtype", "-force", "-rmall", "lbtype:$label$vob_desc" ) unless $opt_test;
482
    Error ("Program Terminated") if ( @error_list );
483
    $opr_done = 1;
484
}
485
 
486
#-------------------------------------------------------------------------------
487
#   Process command
488
#       Lock a label - if not already locked
489
if ( $opt_lock )
490
{
491
    Verbose ("Lock label");
492
    ClearCmd ("describe", "-fmt", "%[locked]p", "lbtype:$label$vob_desc" );
493
    if ( $last_result =~ m~unlocked~ )
494
    {
495
        ClearCmd ("lock", "lbtype:$label$vob_desc" ) unless $opt_test;
496
        Error ("Program Terminated") if ( @error_list );
497
    }
498
    $opr_done = 1;
499
}
500
 
501
#-------------------------------------------------------------------------------
502
#   Process command
503
#       Display Label information
504
if ( $opt_info )
505
{
506
    Verbose ("describe label");
507
    system (QuoteCommand("cleartool", "describe", "-long", "lbtype:$label$vob_desc" )) unless $opt_test;
508
    Error ("Program Terminated") if ( @error_list );
509
    $opr_done = 1;
510
}
511
 
512
 
513
Error ("No valid operations specified. Try -h") unless ( $opr_done );
514
if ( $opt_test )
515
{
516
    print ("End program [Test Mode]\n");
517
}
518
else
519
{
520
    print ("End program\n");
521
}
522
 
523
exit 0;
524
 
525
#-------------------------------------------------------------------------------
526
# Function        : determine_dirs_to_label
527
#
528
# Description     : Determine diretories up to the VOB root that need to be
529
#                   labeled.
530
#
531
# Inputs          : $data           - Ref to hash to collect info
532
#
533
# Returns         : Nothing
534
#                   Values populated into $data hash
535
#
536
sub determine_dirs_to_label
537
{
538
    my ($data) = @_;
539
    Verbose ("Locate directories to label");
540
 
541
    #
542
    #   Init data - so that we can see what to expect
543
    #
544
    $data->{'dir_list'} = [];
545
    $data->{'checked_out_pdirs'} = [];
546
    $data->{'is_symlink'} = 0;
547
    $data->{'VobRoot'} = '';
548
 
549
    #
227 dpurdie 550
    #   Figure out what to do
551
    #       Label dirs upwards if requested, or we are not doing files or dirs
552
    #       Label the current directory unless asked to do files/dirs or up-only
553
    #
554
    my $do_files = scalar @opt_files;
309 dpurdie 555
    my $do_dirs  = scalar @opt_dirs;
227 dpurdie 556
    my $do_up = $opt_up || ( ! $do_files && ! $do_dirs );
557
    push @opt_dirs, '.' unless ($opt_up || $do_files || $do_dirs);
558
 
559
    #
560
    #   Build up a list of parent directories up to the root of the VOB
561
    #   that do not have the desired label
562
    #
563
    if ( $do_up )
564
    {
565
        Verbose ("Examine parent directories");
566
 
567
        my $path = getcwd();
568
        while ( 1 )
569
        {
570
            my $cmd = QuoteCommand ("cleartool", "describe", $path);
571
            my $has_label;
572
            my $is_versioned;
573
            my $start_labels;
574
            my $link;
575
            my $is_checkedout;
576
 
577
            Verbose($cmd);
309 dpurdie 578
            my $cmd_handle;
579
            open($cmd_handle, "$cmd 2>&1 |") || Error( "Can't run command: $!");
580
            while (<$cmd_handle>)
227 dpurdie 581
            {
582
                #
583
                #   Filter output from the user
584
                #
585
                chomp;
586
                Verbose2($_);
309 dpurdie 587
                push @error_list, $_    if ( m~Error:~ );
588
                $link = $1              if ( m~^symbolic link.* -> (.*)~ );
589
                $is_versioned = 1       if ( m~^directory version ~ );
590
                $start_labels = 1       if ( m~^\s+Labels:$~ );
591
                $is_checkedout = 1      if ( m~[\\/]CHECKEDOUT"~ );
227 dpurdie 592
                next unless ( $start_labels );
309 dpurdie 593
                $has_label = 1          if ( m~^\s+$label$~ );
227 dpurdie 594
            }
309 dpurdie 595
            close($cmd_handle);
596
            $data->{'VobRoot'} = $path;
227 dpurdie 597
 
598
            #
599
            #   Symbolic link located
600
            #   Resolve the link and continue
601
            #   The link cannot be labeled. If we can label the resolved link then
602
            #   all is good, otherwise we have a a problem
603
            #
604
            if ( $link )
605
            {
309 dpurdie 606
                $data->{'is_symlink'} = 1;
227 dpurdie 607
                $path =~ s~[/][^/]*$~~;
608
                $path = $path . '/' . $link;
609
                $path =~ s~/[^/]+/\.\./~/~;
610
                Verbose("Symbolic link: $link, Path: $path" );
611
                next;
612
            }
613
 
614
            #
615
            #   Parent directory checked out. Options:
616
            #       0: Don't Label checkedout elements
617
            #       1: Do Label only checkout elements
309 dpurdie 618
            #       2: Label both (default)
227 dpurdie 619
            #
620
            if ( $is_checkedout )
621
            {
309 dpurdie 622
                $has_label = 2 if ( $opt_checkout == 0 );
623
                push @{$data->{'checked_out_pdirs'}}, $_;
227 dpurdie 624
            }
625
            else
626
            {
309 dpurdie 627
                $has_label = 2 if ( $opt_checkout == 1 );
227 dpurdie 628
            }
629
 
630
            last unless ( $is_versioned );
309 dpurdie 631
            unshift @{$data->{'dir_list'}}, $path unless ( $has_label );
227 dpurdie 632
 
633
            #
634
            #   Versioned directory seen
635
            #   If the previous one loop was a symlink, then we have labeled
636
            #   the link correctly
637
            #
309 dpurdie 638
            $data->{'is_symlink'} = 0;
227 dpurdie 639
 
640
            #
641
            #   Calculate the path of the parent directory
642
            #   Stop when we get to the top ( ie z: is not good )
643
            #
309 dpurdie 644
            last unless ( $path =~ s~[/][^/]*$~~);
227 dpurdie 645
            last unless ( $path =~ m~/~ );
646
        }
647
    }
309 dpurdie 648
}
227 dpurdie 649
 
309 dpurdie 650
#-------------------------------------------------------------------------------
651
# Function        : determine_files_to_label
652
#
653
# Description     : Determine a list of files that need to be
654
#                   labeled.
655
#
656
# Inputs          : $data           - Ref to hash to collect info
657
#
658
# Returns         : Nothing
659
#                   Values populated into $data hash
660
#
661
sub determine_files_to_label
662
{
663
    my ($data) = @_;
664
    Verbose ("Locate files to label");
227 dpurdie 665
 
309 dpurdie 666
    #
667
    #   Init data - so that we can see what to expect
668
    #
669
    $data->{'label_list'} = [];
670
    $data->{'checked_out_files'} = [];
671
    $data->{'checked_out_dirs'} = [];
672
    $data->{'missing_files'} = [];
673
    $data->{'element0_list'} = [];
674
    $data->{'exclude_list'} = [];
675
    $data->{'build_files'} = [];
676
 
677
    #
678
    #   Figure out what to do
679
    #       Label dirs upwards if requested, or we are not doing files or dirs
680
    #       Label the current directory unless asked to do files/dirs or up-only
681
    #
682
    my $do_files = scalar @opt_files;
683
    my $do_dirs  = scalar @opt_dirs;
684
    my $do_up = $opt_up || ( ! $do_files && ! $do_dirs );
685
    push @opt_dirs, '.' unless ($opt_up || $do_files || $do_dirs);
686
 
687
    my @check_these;
688
 
689
    #
690
    #   Examine all specified files and directories
691
    #       Detect nasty files
692
    #       Don't label elements that have already been labled
693
    #
694
    #   Use the cleartool find command as it will allow us to determine
695
    #   if the element has already been labled.
696
    #
697
    #   Note: cleartool find works on files and directories
698
    #
699
    foreach my $dir (@opt_files, @opt_dirs )
227 dpurdie 700
    {
701
        #
702
        #   Remove possible trailing / from user specified directory as
703
        #   clearcase doesn't handle these too well.
704
        #
705
        $dir =~ tr~\\/~/~s;
706
        $dir =~ s~/+$~~;
707
        $dir = '/' unless ( $dir );
708
 
709
        Verbose ("Examine subdirectory: $dir");
237 dpurdie 710
        my $find_arg = $opt_recurse ? '' : '-nrecurse';
227 dpurdie 711
        my $cmd = QuoteCommand ("cleartool", "find", "$dir", "-cview", $find_arg, "-version", "{!lbtype($label)}", "-print");
712
        Verbose2($cmd);
713
 
309 dpurdie 714
        my $cmd_handle;
715
        open($cmd_handle, "$cmd 2>&1 |") || Error( "can't run command: $!");
716
        while (<$cmd_handle>)
227 dpurdie 717
        {
718
            #
719
            #   Filter output from the user
720
            #
721
            chomp;
722
            Verbose2($_);
723
            if ( m~Error:~ )
724
            {
725
                #
726
                #   In AutoBuild Mode allow the error "Not a vob object"
727
                #   This may be cause by generated directory that has been checked in
728
                #   If the directory gets re-generated then the Find gets confused.
729
                #
730
                if ( $autobuild && m~Not a vob object:~ )
731
                {
309 dpurdie 732
                    Warning( "AutoBuildTool supressed: $_" );
227 dpurdie 733
                    next;
734
                }
735
                push @error_list, $_;
736
                next;
737
            }
738
            push @check_these, $_;
739
        }
309 dpurdie 740
        close($cmd_handle);
227 dpurdie 741
        Error ("Program Terminated") if ( @error_list );
742
    }
743
 
744
    #
745
    #   Have a list of files to examine to see if we really want to label them
746
    #
747
    find:
748
    foreach ( @check_these )
749
    {
750
        ( my $file = $_ ) =~ s~@@.*~~;
751
 
752
        #
753
        #   If we are not recursing - then skip directories
754
        #
755
        next find
756
            if ( ! $opt_recurse  && -d $file );
757
 
758
        tr~\\/~/~s;
309 dpurdie 759
        s~^\./~~;
227 dpurdie 760
 
761
        #
762
        #   Exclude files and directories that are the /main/0 element
763
        #   These may be in a view due to branching rules
764
        #   The contents will be empty. Labeling them will create uglyness
765
        #   it simplifies life if we don't label them
766
        #
767
        if ( m~/main/0$~ )
768
        {
309 dpurdie 769
            push @{$data->{'element0_list'}}, $_;
227 dpurdie 770
            next find;
771
        }
772
 
773
        #
774
        #   Has it been excluded
775
        #
776
        foreach my $name ( @opt_exclude )
777
        {
778
            if ( m~/$name[/@]~ )
779
            {
309 dpurdie 780
                push @{$data->{'exclude_list'}}, $_;
227 dpurdie 781
                next find;
782
            }
783
        }
784
 
785
        #
786
        #   Ensure that the file is really present
787
        #   In a static sandbox CC retains memory of files that have been
788
        #   deleted. This may be intentional it may be an error
789
        #
790
        if ( ! -e $file && ! $opt_all )
791
        {
309 dpurdie 792
            push @{$data->{'missing_files'}}, $file;
227 dpurdie 793
            next find;
794
        }
795
 
796
        #
797
        #   Count build.pl files
309 dpurdie 798
        #   Not really useful for Ant Builds 
227 dpurdie 799
        #
800
        if ( m~/build.pl@~i )
801
        {
309 dpurdie 802
            push @{$data->{'build_files'}}, $_
227 dpurdie 803
        }
804
 
805
        #
806
        #   Handle Checked out files
807
        #
808
        if ( m/CHECKEDOUT$/ )
809
        {
810
            next find if ( $opt_checkout == 0 );
309 dpurdie 811
            if ( -d $file  )
812
            {
813
                push @{$data->{'checked_out_dirs'}}, $_;
814
            }
815
            else
816
            {
817
                push @{$data->{'checked_out_files'}}, $_;
818
            }
227 dpurdie 819
        }
820
        else
821
        {
822
            next find if ( $opt_checkout == 1 );
823
        }
824
 
309 dpurdie 825
        push @{$data->{'label_list'}}, $_ ;
227 dpurdie 826
    }
827
}
828
 
829
#-------------------------------------------------------------------------------
830
# Function        : display_error_list
831
#
832
# Description     : Display the error list
833
#                   This function is registered as an Error callback function
834
#                   it will be called on error exit
835
#
309 dpurdie 836
#                   Will clear error list when called, so that it can be used
837
#                   in non-exit situations.
838
#
227 dpurdie 839
# Inputs          :
840
#
309 dpurdie 841
# Returns         : true            - Errors in list
842
#                   false           - No error in list
227 dpurdie 843
#
844
sub display_error_list
845
{
309 dpurdie 846
    return 0 unless ( @error_list );
847
    print "$_\n" foreach ( @error_list );
848
    @error_list = ();
849
    return 1;
227 dpurdie 850
}
851
 
852
#-------------------------------------------------------------------------------
853
# Function        : ClearCmd
854
#
855
# Description     : Similar to the system command
856
#                   Does allow standard output and standard error to be captured
857
#                   to a log file
858
#
859
#                   Used since I was having problems with calling other programs
860
#                   and control-C. It could hang the terminal session.
861
#
862
# Inputs          :
863
#
864
# Returns         :
865
#
866
sub ClearCmd
867
{
868
    my $cmd = QuoteCommand (@_);
869
    Verbose2 "cleartool $cmd";
870
 
871
        @error_list = ();
309 dpurdie 872
        my $cmd_handle;
873
        open($cmd_handle, "cleartool $cmd  2>&1 |")    || Error "can't run command: $!";
874
        while (<$cmd_handle>)
227 dpurdie 875
        {
876
            chomp;
877
            $last_result = $_;
878
            Verbose ( "cleartool resp:" . $_);
879
            push @error_list, $_ if ( m~Error:~ );
880
        }
309 dpurdie 881
        close($cmd_handle);
227 dpurdie 882
 
883
    Verbose2 "Exit Status: $?";
884
    return $? / 256;
885
}
886
 
887
#-------------------------------------------------------------------------------
888
#   Documentation
889
#
890
 
891
=pod
892
 
893
=head1 NAME
894
 
895
jats_label - Clearcase label operations
896
 
897
=head1 SYNOPSIS
898
 
899
jats label [options] C<label>
900
 
901
 Options:
902
    -help              - brief help message
903
    -help -help        - Detailed help message
904
    -man               - Full documentation
905
    -auto              - Auto create and label
906
    -clone=xxx         - Apply new label to objects with label xxx
907
    -create            - Create a label
908
    -label             - Labels a directory tree
909
    -lock              - Lock the label
910
    -remove            - Remove label from elements
911
    -delete            - Delete label label from elements and vob
912
    -rename=xxx        - Rename a label
913
    -show              - Show elements with the label
914
    -unlock            - Unlock the label
915
    -[no]mine          - Set label owner to user.
916
    -info              - Provide label information
917
    -smartlock         - Unlock and Relock label, if it was locked
918
 
919
 Modifiers
920
    -all               - Process all the VOB. Use with -show and -remove.
921
    -replace           - Replace existing labels. Use with -label
922
    -exclude=n1,n2     - Exclude files and directories from the -label process.
923
    -files=f1,f2,...   - Label only the named files.
924
    -dirs=d1,d2,...    - Label only the named dirs.
925
    -[no]recurse       - Exclude all subdirectories from the -label process.
926
    -[no]checkout      - Don't/Do label checked out files. Default - label both
927
    -up                - Only label directories upwards. Do not label files/dirs
928
    -test              - Just show the labels that would be added.
929
    -comment=text      - Comment to add to label when created.
930
    -user=name         - Used with -mine to specify user
931
    -vob=name          - Specify VOB name when manipulating label.
932
                         Not allowed with -label, -clone, -remove and -show
933
 
934
=head1 OPTIONS
935
 
936
=over 8
937
 
938
=item B<-help>
939
 
940
Print a brief help message and exits.
941
 
942
=item B<-help -help>
943
 
944
Print a detailed help message with an explanation for each option.
945
 
946
=item B<-man>
947
 
948
Prints the manual page and exits.
949
 
950
=item B<-all>
951
 
952
This option modifies the operation of the -show, -remove and -label operations.
953
 
954
With this option the processing extends to the entire VOB. This is a slower, but
955
more complete operation.
956
 
957
With this option the -label will label files that are not currently present in a
958
static view.
959
 
960
=item B<-auto>
961
 
962
This option will create the label if the label does not exist and then label the
963
current directory.
964
 
965
This option is a combination of a -create and a -label, except that it will
966
not fail if the label already exists.
967
 
968
=item B<-clone=xxx>
969
 
970
This option will apply a new label to all objects that have the label xxx.
971
The effect is that the specified label is clone of label xxx.
972
 
973
This operation may be used to initiate a new build label by first cloning an
974
existing build before tailoring the file set.
975
 
976
=item B<-create>
977
 
978
This option will create the specified label. The operations will fail if the
979
label is already present in the current VOB.
980
 
981
The label will be created in the current VOB with a comment if one is provided.
982
 
983
=item B<-delete>
984
 
985
This option will delete the specified label from all objects with the label
986
and remove the label from the VOB. You need to be the owner of this label in
987
order for the operation to occur without error.
988
 
989
=item B<-exclude name>
990
 
991
Exclude specific files and directories from the labeling process.
992
 
993
The names may be comma separated, or the option may be specified multiple times.
994
 
995
Wildcards are supported in the form of regular expressions. All .h
996
files may be excluded with the command "-exclude=.*\.h".
997
 
998
examples:
999
    -exclude=test will exclude all directory trees called test
1000
 
1001
    -exclude=test,play will exclude all directory trees called 'test' and 'play'
1002
 
1003
    -exclude=test/seattle will exclude all directory trees called test/seattle
1004
 
1005
=item B<-files=name>
1006
 
1007
Label only the specified files. The names may be comma separated, or the option
1008
may be specified multiple times.
1009
 
1010
The use of this option overrides the default operation of the label utility
1011
and the entire file tree will not be scanned. Only the specified files will be
1012
labeled.
1013
 
1014
Wildcards are not supported.
1015
 
1016
Directories will not be recursed, but may be labeled.
1017
 
1018
=item B<-dirs=name>
1019
 
1020
Label only the specified directories. The names may be comma separated, or the
1021
option may be specified multiple times.
1022
 
1023
The use of this option overrides the default operation of the label utility
1024
and the entire file tree will not be scanned. Only the specified directories
1025
will be labeled.
1026
 
1027
Wildcards are not supported.
1028
 
1029
=item B<-label>
1030
 
1031
This option will label all the files in, and below, the current directory and
1032
all the parent directories.
1033
 
1034
The -replace option may be used to force labels to be moved.
1035
 
1036
The -norecurse option may be used to prevent recursion into all subdirectories,
1037
and the labeling of any directories.
1038
 
1039
=item B<-lock>
1040
 
1041
This option will lock the specified label. This operation will be done after any
1042
other operations have been performed.  If the label is already locked then
1043
this operation will not attempt to lock the label.
1044
 
1045
=item B<-remove>
1046
 
1047
This option will remove the specified label from all objects with the label.
1048
 
1049
If the -all option is present then all elements in the entire VOB will be
1050
examined, otherwise just this in and below the current directory will be
1051
examined.
1052
 
1053
The -all operation may take some time.
1054
 
1055
=item B<-rename=xxx>
1056
 
1057
This option will rename a label. The new name of the label is provided as the
1058
argument after the option. If any further operation are to be performed the
1059
new label name will be used.
1060
 
1061
By default, the owner of the label will be set to the current user. This
1062
mechanism is used in the build process. This -nomine option changes this
1063
behaviour.
1064
 
1065
=item B<-replace>
1066
 
1067
This option may be used with the -label command to force labels to be moved to
1068
the file or directory in the current view.
1069
 
1070
=item B<-[no]recurse>
1071
 
1072
This option modifies the behaviour of the B<-label> operation. The default
1073
behaviour is to label all files and directories in and below the current
1074
directory.
1075
 
1076
The B<-norecurse> option prevents recursion into subdirectories and the labeling
1077
of subdirectories. Only files in the current directory will be labeled. -
1078
together with parent directories as required.
1079
 
1080
=item B<-show>
1081
 
1082
This operation will show all clearcase elements with the specified label.
1083
 
1084
If the -all option is present then all elements in the entire VOB will be shown,
1085
otherwise just this in and below the current directory will be displayed.
1086
 
1087
The -all operation may take some time.
1088
 
1089
=item B<-test>
1090
 
1091
This operation will prevent the program from performing any destructive
1092
operation. It may be used to show what operation would be done.
1093
 
1094
=item B<-unlock>
1095
 
1096
This option will unlock the specified label. This operation will be done before
1097
any other operations have been performed.  If the label is not locked then
1098
this operation will not attempt to unlock the label.
1099
 
1100
=item B<-[no]mine>
1101
 
1102
This option will set the owner of the label to the current user. This
1103
operation is performed automatically when a -rename operation occurs. The
1104
"no" option allows this behaviour to be modified.
1105
 
1106
=item B<-up>
1107
 
1108
This option will prevent the utility for labeling files and directories below
1109
the current directory. Only directories above the current directory will be
1110
labeled.
1111
 
1112
This option may be specifically used with -dirs and -files to label the named
1113
directories and files as well as the directoires up, from the current directory.
1114
 
1115
=item B<-info>
1116
 
1117
This option will provide label information. It uses the clearcase describe
1118
command.
1119
 
1120
=item B<-smartlock>
1121
 
1122
This option will unlock the label for the duration of the operations and then
1123
lock the label again - if it was locked to start with. Smart locking allows
1124
label operations while retaining the lock state of the label.
1125
 
1126
=item B<-[no]checkout>
1127
 
1128
This option affects the processing of checked out files. There are three modes of
1129
operation.:
1130
 
1131
    1) -nocheckout      Checked out files are not labeled
1132
    2) -checkout        Only checked out files are labeled
1133
    3) Neither          All files are labeled.
1134
 
1135
=item B<-comment=text>
1136
 
1137
This option allows a comment to be added to a label when it is created. The
1138
option has no effect if the label is not created.
1139
 
1140
=item B<-vob=name>
1141
 
1142
This option is used by commands that do not acutally place labels on files to
1143
manipulate when the user's current directry is not within a view. This allows lables to be created,
1144
locked and unlocked without having a view present.
1145
 
1146
=back
1147
 
1148
=head1 DESCRIPTION
1149
 
1150
This program provides a number of useful ClearCase labeling operations. These
1151
are:
1152
 
1153
=over 8
1154
 
1155
=item   create - create a label
1156
 
1157
=item   unlock - unlock the specified label
1158
 
1159
=item   rename - rename a label
1160
 
1161
=item   mine - change ownership of a label
1162
 
1163
=item   label - label a directory tree
1164
 
1165
=item   remove - remove the label from all labeled objects
1166
 
1167
=item   show - show all objects tagged with the label
1168
 
1169
=item   lock - lock a label
1170
 
1171
=item   delete - delete all instances of a label and the label
1172
 
1173
=item   info - describe the labels properties
1174
 
1175
=back
1176
 
1177
The various operations may be mixed in the one command. The order of the
1178
operations is: create, unlock, rename, mine, label, show, remove, delete, lock
1179
and info.
1180
 
1181
Thus it is possible to create a label, label a directory tree and then lock the
1182
label.
1183
 
1184
=head1 EXAMPLE
1185
 
1186
jats label -create -label -lock daf_br_23.0.0.syd
1187
 
1188
=cut
1189