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'}};
313 dpurdie 368
    print "Checkedout File: $_\n" foreach @{$info{'checked_out_files'}};
369
    print "Checkedout Dir: $_\n" foreach @{$info{'checked_out_dirs'}};
309 dpurdie 370
 
371
    print        ("Labels applied:", scalar(@{$info{'label_list'}}) + scalar(@{$info{'dir_list'}}), "\n" );
372
    show_warning ("WARNING: Labels applied to checked out parent directories", 'checked_out_pdirs' );
373
    show_warning ("WARNING: Labels applied to checked out files", 'checked_out_files' );
374
    show_warning ("WARNING: Labels applied to checked out dirs", 'checked_out_dirs' );
375
    show_warning ("WARNING: Labels NOT applied to missing files", 'missing_files' );
376
    show_warning ("WARNING: Labels NOT applied to element-0 of files", 'element0_list' );
377
    print        ("WARNING: Path to the VOB root contains a symbolic link. Labeling incomplete") if ( $info{'is_symlink'} );
378
    show_warning ("WARNING: Multiple build.pl files labeled", 'build_files', 1 );
379
 
380
    Error ("Program Terminated") if ( $label_error );
381
 
382
    #
383
    #   Double check the label process
384
    #   We are seeing issues with ClearCase where a file, or dir, is not being
385
    #   labeled. The following is a quick check. See if there is any thing to
386
    #   label again
387
    #
313 dpurdie 388
    unless ( $opt_test )
309 dpurdie 389
    {
313 dpurdie 390
        %info = ();
391
        determine_dirs_to_label ( \%info );
392
        determine_files_to_label( \%info );
393
        if ( @{$info{'dir_list'}}  || @{$info{'label_list'}} )
394
        {
395
            DebugDumpData("DoubleCheck Data", \%info );
396
            Error ('ClearCase label problem detected',
397
                   'Please report to david.purdie@vix-erg.com',
398
                   'Directories and Files not labled as requested:',
399
                   @{$info{'dir_list'}},
400
                   @{$info{'label_list'}}
401
                   );
402
        }
309 dpurdie 403
    }
404
 
405
    $opr_done = 1;
406
}
407
 
408
#-------------------------------------------------------------------------------
409
#   Process command
410
#       Clone
411
if ( $opt_clone )
412
{
413
    Verbose ("Clone Label");
414
    my @cmd_opt;
415
    push @cmd_opt, "-all" if ($opt_all);
416
 
417
    my @cmd2_opt;
418
    push @cmd2_opt, "-replace" if ( $opt_replace );
419
 
420
    my $count = 0;
421
    my $checked_out_count = 0;
422
 
423
    my $cmd = QuoteCommand ("cleartool", "find", ".", @cmd_opt, "-version", "lbtype($opt_clone)", "-print");
424
    Verbose2($cmd);
425
 
426
    open(CLONECMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
427
    while (<CLONECMD>)
428
    {
429
        chomp;
430
        print($_ . "\n");
431
        $count++;
432
        $checked_out_count++ if ( m/CHECKEDOUT$/ );
433
 
434
        ClearCmd ("mklabel", @cmd2_opt, $label, $_ ) unless ( $opt_test );
435
        last if ( @error_list )
436
    }
437
    close(CLONECMD);
438
 
439
    Error ("Program Terminated") if ( @error_list );
440
    print "Labels applied: $count\n";
441
    print "WARNING: Labels applied to checked out files: $checked_out_count\n" if ( $checked_out_count );
442
    $opr_done = 1;
443
}
444
 
445
 
446
#-------------------------------------------------------------------------------
447
#   Process command
448
#       Show labeled files and directories
449
#       Remove labels
450
 
451
if ( $opt_show || $opt_remove )
452
{
453
    Verbose ("Show Label");
454
    my @cmd_opt;
455
    push @cmd_opt, "-all" if ($opt_all);
456
 
457
    my $cmd = QuoteCommand("cleartool", "find", ".", @cmd_opt, "-version", "lbtype($label)", "-print");
458
    Verbose2($cmd);
459
 
460
    open(SHOWCMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
461
    while (<SHOWCMD>)
462
    {
463
        #
464
        #   Filter output from the user
465
        #
466
        chomp;
467
        print($_ . "\n");
468
 
469
        if ( $opt_remove )
470
        {
471
            ClearCmd ( "rmlabel", $label, $_ ) unless $opt_test;
472
        }
473
 
474
    }
475
    close(SHOWCMD);
476
    $opr_done = 1;
477
}
478
 
479
#-------------------------------------------------------------------------------
480
#   Process command
481
#       Delete a label
482
if ( $opt_delete )
483
{
484
    Verbose ("Delete label");
485
    ClearCmd ("rmtype", "-force", "-rmall", "lbtype:$label$vob_desc" ) unless $opt_test;
486
    Error ("Program Terminated") if ( @error_list );
487
    $opr_done = 1;
488
}
489
 
490
#-------------------------------------------------------------------------------
491
#   Process command
492
#       Lock a label - if not already locked
493
if ( $opt_lock )
494
{
495
    Verbose ("Lock label");
496
    ClearCmd ("describe", "-fmt", "%[locked]p", "lbtype:$label$vob_desc" );
497
    if ( $last_result =~ m~unlocked~ )
498
    {
499
        ClearCmd ("lock", "lbtype:$label$vob_desc" ) unless $opt_test;
500
        Error ("Program Terminated") if ( @error_list );
501
    }
502
    $opr_done = 1;
503
}
504
 
505
#-------------------------------------------------------------------------------
506
#   Process command
507
#       Display Label information
508
if ( $opt_info )
509
{
510
    Verbose ("describe label");
511
    system (QuoteCommand("cleartool", "describe", "-long", "lbtype:$label$vob_desc" )) unless $opt_test;
512
    Error ("Program Terminated") if ( @error_list );
513
    $opr_done = 1;
514
}
515
 
516
 
517
Error ("No valid operations specified. Try -h") unless ( $opr_done );
518
if ( $opt_test )
519
{
520
    print ("End program [Test Mode]\n");
521
}
522
else
523
{
524
    print ("End program\n");
525
}
526
 
527
exit 0;
528
 
529
#-------------------------------------------------------------------------------
530
# Function        : determine_dirs_to_label
531
#
532
# Description     : Determine diretories up to the VOB root that need to be
533
#                   labeled.
534
#
535
# Inputs          : $data           - Ref to hash to collect info
536
#
537
# Returns         : Nothing
538
#                   Values populated into $data hash
539
#
540
sub determine_dirs_to_label
541
{
542
    my ($data) = @_;
543
    Verbose ("Locate directories to label");
544
 
545
    #
546
    #   Init data - so that we can see what to expect
547
    #
548
    $data->{'dir_list'} = [];
549
    $data->{'checked_out_pdirs'} = [];
550
    $data->{'is_symlink'} = 0;
551
    $data->{'VobRoot'} = '';
552
 
553
    #
227 dpurdie 554
    #   Figure out what to do
555
    #       Label dirs upwards if requested, or we are not doing files or dirs
556
    #       Label the current directory unless asked to do files/dirs or up-only
557
    #
558
    my $do_files = scalar @opt_files;
309 dpurdie 559
    my $do_dirs  = scalar @opt_dirs;
227 dpurdie 560
    my $do_up = $opt_up || ( ! $do_files && ! $do_dirs );
561
    push @opt_dirs, '.' unless ($opt_up || $do_files || $do_dirs);
562
 
563
    #
564
    #   Build up a list of parent directories up to the root of the VOB
565
    #   that do not have the desired label
566
    #
567
    if ( $do_up )
568
    {
569
        Verbose ("Examine parent directories");
570
 
571
        my $path = getcwd();
572
        while ( 1 )
573
        {
574
            my $cmd = QuoteCommand ("cleartool", "describe", $path);
575
            my $has_label;
576
            my $is_versioned;
577
            my $start_labels;
578
            my $link;
579
            my $is_checkedout;
580
 
581
            Verbose($cmd);
309 dpurdie 582
            my $cmd_handle;
583
            open($cmd_handle, "$cmd 2>&1 |") || Error( "Can't run command: $!");
584
            while (<$cmd_handle>)
227 dpurdie 585
            {
586
                #
587
                #   Filter output from the user
588
                #
589
                chomp;
590
                Verbose2($_);
309 dpurdie 591
                push @error_list, $_    if ( m~Error:~ );
592
                $link = $1              if ( m~^symbolic link.* -> (.*)~ );
593
                $is_versioned = 1       if ( m~^directory version ~ );
594
                $start_labels = 1       if ( m~^\s+Labels:$~ );
595
                $is_checkedout = 1      if ( m~[\\/]CHECKEDOUT"~ );
227 dpurdie 596
                next unless ( $start_labels );
309 dpurdie 597
                $has_label = 1          if ( m~^\s+$label$~ );
227 dpurdie 598
            }
309 dpurdie 599
            close($cmd_handle);
600
            $data->{'VobRoot'} = $path;
227 dpurdie 601
 
602
            #
603
            #   Symbolic link located
604
            #   Resolve the link and continue
605
            #   The link cannot be labeled. If we can label the resolved link then
606
            #   all is good, otherwise we have a a problem
607
            #
608
            if ( $link )
609
            {
309 dpurdie 610
                $data->{'is_symlink'} = 1;
227 dpurdie 611
                $path =~ s~[/][^/]*$~~;
612
                $path = $path . '/' . $link;
613
                $path =~ s~/[^/]+/\.\./~/~;
614
                Verbose("Symbolic link: $link, Path: $path" );
615
                next;
616
            }
617
 
618
            #
619
            #   Parent directory checked out. Options:
620
            #       0: Don't Label checkedout elements
621
            #       1: Do Label only checkout elements
309 dpurdie 622
            #       2: Label both (default)
227 dpurdie 623
            #
624
            if ( $is_checkedout )
625
            {
309 dpurdie 626
                $has_label = 2 if ( $opt_checkout == 0 );
627
                push @{$data->{'checked_out_pdirs'}}, $_;
227 dpurdie 628
            }
629
            else
630
            {
309 dpurdie 631
                $has_label = 2 if ( $opt_checkout == 1 );
227 dpurdie 632
            }
633
 
634
            last unless ( $is_versioned );
309 dpurdie 635
            unshift @{$data->{'dir_list'}}, $path unless ( $has_label );
227 dpurdie 636
 
637
            #
638
            #   Versioned directory seen
639
            #   If the previous one loop was a symlink, then we have labeled
640
            #   the link correctly
641
            #
309 dpurdie 642
            $data->{'is_symlink'} = 0;
227 dpurdie 643
 
644
            #
645
            #   Calculate the path of the parent directory
646
            #   Stop when we get to the top ( ie z: is not good )
647
            #
309 dpurdie 648
            last unless ( $path =~ s~[/][^/]*$~~);
227 dpurdie 649
            last unless ( $path =~ m~/~ );
650
        }
651
    }
309 dpurdie 652
}
227 dpurdie 653
 
309 dpurdie 654
#-------------------------------------------------------------------------------
655
# Function        : determine_files_to_label
656
#
657
# Description     : Determine a list of files that need to be
658
#                   labeled.
659
#
660
# Inputs          : $data           - Ref to hash to collect info
661
#
662
# Returns         : Nothing
663
#                   Values populated into $data hash
664
#
665
sub determine_files_to_label
666
{
667
    my ($data) = @_;
668
    Verbose ("Locate files to label");
227 dpurdie 669
 
309 dpurdie 670
    #
671
    #   Init data - so that we can see what to expect
672
    #
673
    $data->{'label_list'} = [];
674
    $data->{'checked_out_files'} = [];
675
    $data->{'checked_out_dirs'} = [];
676
    $data->{'missing_files'} = [];
677
    $data->{'element0_list'} = [];
678
    $data->{'exclude_list'} = [];
679
    $data->{'build_files'} = [];
680
 
681
    #
682
    #   Figure out what to do
683
    #       Label dirs upwards if requested, or we are not doing files or dirs
684
    #       Label the current directory unless asked to do files/dirs or up-only
685
    #
686
    my $do_files = scalar @opt_files;
687
    my $do_dirs  = scalar @opt_dirs;
688
    my $do_up = $opt_up || ( ! $do_files && ! $do_dirs );
689
    push @opt_dirs, '.' unless ($opt_up || $do_files || $do_dirs);
690
 
691
    my @check_these;
692
 
693
    #
694
    #   Examine all specified files and directories
695
    #       Detect nasty files
696
    #       Don't label elements that have already been labled
697
    #
698
    #   Use the cleartool find command as it will allow us to determine
699
    #   if the element has already been labled.
700
    #
701
    #   Note: cleartool find works on files and directories
702
    #
703
    foreach my $dir (@opt_files, @opt_dirs )
227 dpurdie 704
    {
705
        #
706
        #   Remove possible trailing / from user specified directory as
707
        #   clearcase doesn't handle these too well.
708
        #
709
        $dir =~ tr~\\/~/~s;
710
        $dir =~ s~/+$~~;
711
        $dir = '/' unless ( $dir );
712
 
713
        Verbose ("Examine subdirectory: $dir");
237 dpurdie 714
        my $find_arg = $opt_recurse ? '' : '-nrecurse';
227 dpurdie 715
        my $cmd = QuoteCommand ("cleartool", "find", "$dir", "-cview", $find_arg, "-version", "{!lbtype($label)}", "-print");
716
        Verbose2($cmd);
717
 
309 dpurdie 718
        my $cmd_handle;
719
        open($cmd_handle, "$cmd 2>&1 |") || Error( "can't run command: $!");
720
        while (<$cmd_handle>)
227 dpurdie 721
        {
722
            #
723
            #   Filter output from the user
724
            #
725
            chomp;
726
            Verbose2($_);
727
            if ( m~Error:~ )
728
            {
729
                #
730
                #   In AutoBuild Mode allow the error "Not a vob object"
731
                #   This may be cause by generated directory that has been checked in
732
                #   If the directory gets re-generated then the Find gets confused.
733
                #
734
                if ( $autobuild && m~Not a vob object:~ )
735
                {
309 dpurdie 736
                    Warning( "AutoBuildTool supressed: $_" );
227 dpurdie 737
                    next;
738
                }
739
                push @error_list, $_;
740
                next;
741
            }
742
            push @check_these, $_;
743
        }
309 dpurdie 744
        close($cmd_handle);
227 dpurdie 745
        Error ("Program Terminated") if ( @error_list );
746
    }
747
 
748
    #
749
    #   Have a list of files to examine to see if we really want to label them
750
    #
751
    find:
752
    foreach ( @check_these )
753
    {
754
        ( my $file = $_ ) =~ s~@@.*~~;
755
 
756
        #
757
        #   If we are not recursing - then skip directories
758
        #
759
        next find
760
            if ( ! $opt_recurse  && -d $file );
761
 
762
        tr~\\/~/~s;
309 dpurdie 763
        s~^\./~~;
227 dpurdie 764
 
765
        #
766
        #   Exclude files and directories that are the /main/0 element
767
        #   These may be in a view due to branching rules
768
        #   The contents will be empty. Labeling them will create uglyness
769
        #   it simplifies life if we don't label them
770
        #
771
        if ( m~/main/0$~ )
772
        {
309 dpurdie 773
            push @{$data->{'element0_list'}}, $_;
227 dpurdie 774
            next find;
775
        }
776
 
777
        #
778
        #   Has it been excluded
779
        #
780
        foreach my $name ( @opt_exclude )
781
        {
313 dpurdie 782
            if ( m~(^|/)$name[/@]~ )
227 dpurdie 783
            {
309 dpurdie 784
                push @{$data->{'exclude_list'}}, $_;
227 dpurdie 785
                next find;
786
            }
787
        }
788
 
789
        #
790
        #   Ensure that the file is really present
791
        #   In a static sandbox CC retains memory of files that have been
792
        #   deleted. This may be intentional it may be an error
793
        #
794
        if ( ! -e $file && ! $opt_all )
795
        {
309 dpurdie 796
            push @{$data->{'missing_files'}}, $file;
227 dpurdie 797
            next find;
798
        }
799
 
800
        #
801
        #   Count build.pl files
309 dpurdie 802
        #   Not really useful for Ant Builds 
227 dpurdie 803
        #
313 dpurdie 804
        if ( m~(^|/)build.pl@~i )
227 dpurdie 805
        {
309 dpurdie 806
            push @{$data->{'build_files'}}, $_
227 dpurdie 807
        }
808
 
809
        #
810
        #   Handle Checked out files
811
        #
812
        if ( m/CHECKEDOUT$/ )
813
        {
814
            next find if ( $opt_checkout == 0 );
309 dpurdie 815
            if ( -d $file  )
816
            {
817
                push @{$data->{'checked_out_dirs'}}, $_;
818
            }
819
            else
820
            {
821
                push @{$data->{'checked_out_files'}}, $_;
822
            }
227 dpurdie 823
        }
824
        else
825
        {
826
            next find if ( $opt_checkout == 1 );
827
        }
828
 
309 dpurdie 829
        push @{$data->{'label_list'}}, $_ ;
227 dpurdie 830
    }
831
}
832
 
833
#-------------------------------------------------------------------------------
834
# Function        : display_error_list
835
#
836
# Description     : Display the error list
837
#                   This function is registered as an Error callback function
838
#                   it will be called on error exit
839
#
309 dpurdie 840
#                   Will clear error list when called, so that it can be used
841
#                   in non-exit situations.
842
#
227 dpurdie 843
# Inputs          :
844
#
309 dpurdie 845
# Returns         : true            - Errors in list
846
#                   false           - No error in list
227 dpurdie 847
#
848
sub display_error_list
849
{
309 dpurdie 850
    return 0 unless ( @error_list );
851
    print "$_\n" foreach ( @error_list );
852
    @error_list = ();
853
    return 1;
227 dpurdie 854
}
855
 
856
#-------------------------------------------------------------------------------
857
# Function        : ClearCmd
858
#
859
# Description     : Similar to the system command
860
#                   Does allow standard output and standard error to be captured
861
#                   to a log file
862
#
863
#                   Used since I was having problems with calling other programs
864
#                   and control-C. It could hang the terminal session.
865
#
866
# Inputs          :
867
#
868
# Returns         :
869
#
870
sub ClearCmd
871
{
872
    my $cmd = QuoteCommand (@_);
873
    Verbose2 "cleartool $cmd";
874
 
875
        @error_list = ();
309 dpurdie 876
        my $cmd_handle;
877
        open($cmd_handle, "cleartool $cmd  2>&1 |")    || Error "can't run command: $!";
878
        while (<$cmd_handle>)
227 dpurdie 879
        {
880
            chomp;
881
            $last_result = $_;
882
            Verbose ( "cleartool resp:" . $_);
883
            push @error_list, $_ if ( m~Error:~ );
884
        }
309 dpurdie 885
        close($cmd_handle);
227 dpurdie 886
 
887
    Verbose2 "Exit Status: $?";
888
    return $? / 256;
889
}
890
 
891
#-------------------------------------------------------------------------------
892
#   Documentation
893
#
894
 
895
=pod
896
 
897
=head1 NAME
898
 
899
jats_label - Clearcase label operations
900
 
901
=head1 SYNOPSIS
902
 
903
jats label [options] C<label>
904
 
905
 Options:
906
    -help              - brief help message
907
    -help -help        - Detailed help message
908
    -man               - Full documentation
909
    -auto              - Auto create and label
910
    -clone=xxx         - Apply new label to objects with label xxx
911
    -create            - Create a label
912
    -label             - Labels a directory tree
913
    -lock              - Lock the label
914
    -remove            - Remove label from elements
915
    -delete            - Delete label label from elements and vob
916
    -rename=xxx        - Rename a label
917
    -show              - Show elements with the label
918
    -unlock            - Unlock the label
919
    -[no]mine          - Set label owner to user.
920
    -info              - Provide label information
921
    -smartlock         - Unlock and Relock label, if it was locked
922
 
923
 Modifiers
924
    -all               - Process all the VOB. Use with -show and -remove.
925
    -replace           - Replace existing labels. Use with -label
926
    -exclude=n1,n2     - Exclude files and directories from the -label process.
927
    -files=f1,f2,...   - Label only the named files.
928
    -dirs=d1,d2,...    - Label only the named dirs.
929
    -[no]recurse       - Exclude all subdirectories from the -label process.
930
    -[no]checkout      - Don't/Do label checked out files. Default - label both
931
    -up                - Only label directories upwards. Do not label files/dirs
932
    -test              - Just show the labels that would be added.
933
    -comment=text      - Comment to add to label when created.
934
    -user=name         - Used with -mine to specify user
935
    -vob=name          - Specify VOB name when manipulating label.
936
                         Not allowed with -label, -clone, -remove and -show
937
 
938
=head1 OPTIONS
939
 
940
=over 8
941
 
942
=item B<-help>
943
 
944
Print a brief help message and exits.
945
 
946
=item B<-help -help>
947
 
948
Print a detailed help message with an explanation for each option.
949
 
950
=item B<-man>
951
 
952
Prints the manual page and exits.
953
 
954
=item B<-all>
955
 
956
This option modifies the operation of the -show, -remove and -label operations.
957
 
958
With this option the processing extends to the entire VOB. This is a slower, but
959
more complete operation.
960
 
961
With this option the -label will label files that are not currently present in a
962
static view.
963
 
964
=item B<-auto>
965
 
966
This option will create the label if the label does not exist and then label the
967
current directory.
968
 
969
This option is a combination of a -create and a -label, except that it will
970
not fail if the label already exists.
971
 
972
=item B<-clone=xxx>
973
 
974
This option will apply a new label to all objects that have the label xxx.
975
The effect is that the specified label is clone of label xxx.
976
 
977
This operation may be used to initiate a new build label by first cloning an
978
existing build before tailoring the file set.
979
 
980
=item B<-create>
981
 
982
This option will create the specified label. The operations will fail if the
983
label is already present in the current VOB.
984
 
985
The label will be created in the current VOB with a comment if one is provided.
986
 
987
=item B<-delete>
988
 
989
This option will delete the specified label from all objects with the label
990
and remove the label from the VOB. You need to be the owner of this label in
991
order for the operation to occur without error.
992
 
993
=item B<-exclude name>
994
 
995
Exclude specific files and directories from the labeling process.
996
 
997
The names may be comma separated, or the option may be specified multiple times.
998
 
999
Wildcards are supported in the form of regular expressions. All .h
1000
files may be excluded with the command "-exclude=.*\.h".
1001
 
1002
examples:
1003
    -exclude=test will exclude all directory trees called test
1004
 
1005
    -exclude=test,play will exclude all directory trees called 'test' and 'play'
1006
 
1007
    -exclude=test/seattle will exclude all directory trees called test/seattle
1008
 
1009
=item B<-files=name>
1010
 
1011
Label only the specified files. The names may be comma separated, or the option
1012
may be specified multiple times.
1013
 
1014
The use of this option overrides the default operation of the label utility
1015
and the entire file tree will not be scanned. Only the specified files will be
1016
labeled.
1017
 
1018
Wildcards are not supported.
1019
 
1020
Directories will not be recursed, but may be labeled.
1021
 
1022
=item B<-dirs=name>
1023
 
1024
Label only the specified directories. The names may be comma separated, or the
1025
option may be specified multiple times.
1026
 
1027
The use of this option overrides the default operation of the label utility
1028
and the entire file tree will not be scanned. Only the specified directories
1029
will be labeled.
1030
 
1031
Wildcards are not supported.
1032
 
1033
=item B<-label>
1034
 
1035
This option will label all the files in, and below, the current directory and
1036
all the parent directories.
1037
 
1038
The -replace option may be used to force labels to be moved.
1039
 
1040
The -norecurse option may be used to prevent recursion into all subdirectories,
1041
and the labeling of any directories.
1042
 
1043
=item B<-lock>
1044
 
1045
This option will lock the specified label. This operation will be done after any
1046
other operations have been performed.  If the label is already locked then
1047
this operation will not attempt to lock the label.
1048
 
1049
=item B<-remove>
1050
 
1051
This option will remove the specified label from all objects with the label.
1052
 
1053
If the -all option is present then all elements in the entire VOB will be
1054
examined, otherwise just this in and below the current directory will be
1055
examined.
1056
 
1057
The -all operation may take some time.
1058
 
1059
=item B<-rename=xxx>
1060
 
1061
This option will rename a label. The new name of the label is provided as the
1062
argument after the option. If any further operation are to be performed the
1063
new label name will be used.
1064
 
1065
By default, the owner of the label will be set to the current user. This
1066
mechanism is used in the build process. This -nomine option changes this
1067
behaviour.
1068
 
1069
=item B<-replace>
1070
 
1071
This option may be used with the -label command to force labels to be moved to
1072
the file or directory in the current view.
1073
 
1074
=item B<-[no]recurse>
1075
 
1076
This option modifies the behaviour of the B<-label> operation. The default
1077
behaviour is to label all files and directories in and below the current
1078
directory.
1079
 
1080
The B<-norecurse> option prevents recursion into subdirectories and the labeling
1081
of subdirectories. Only files in the current directory will be labeled. -
1082
together with parent directories as required.
1083
 
1084
=item B<-show>
1085
 
1086
This operation will show all clearcase elements with the specified label.
1087
 
1088
If the -all option is present then all elements in the entire VOB will be shown,
1089
otherwise just this in and below the current directory will be displayed.
1090
 
1091
The -all operation may take some time.
1092
 
1093
=item B<-test>
1094
 
1095
This operation will prevent the program from performing any destructive
1096
operation. It may be used to show what operation would be done.
1097
 
1098
=item B<-unlock>
1099
 
1100
This option will unlock the specified label. This operation will be done before
1101
any other operations have been performed.  If the label is not locked then
1102
this operation will not attempt to unlock the label.
1103
 
1104
=item B<-[no]mine>
1105
 
1106
This option will set the owner of the label to the current user. This
1107
operation is performed automatically when a -rename operation occurs. The
1108
"no" option allows this behaviour to be modified.
1109
 
1110
=item B<-up>
1111
 
1112
This option will prevent the utility for labeling files and directories below
1113
the current directory. Only directories above the current directory will be
1114
labeled.
1115
 
1116
This option may be specifically used with -dirs and -files to label the named
1117
directories and files as well as the directoires up, from the current directory.
1118
 
1119
=item B<-info>
1120
 
1121
This option will provide label information. It uses the clearcase describe
1122
command.
1123
 
1124
=item B<-smartlock>
1125
 
1126
This option will unlock the label for the duration of the operations and then
1127
lock the label again - if it was locked to start with. Smart locking allows
1128
label operations while retaining the lock state of the label.
1129
 
1130
=item B<-[no]checkout>
1131
 
1132
This option affects the processing of checked out files. There are three modes of
1133
operation.:
1134
 
1135
    1) -nocheckout      Checked out files are not labeled
1136
    2) -checkout        Only checked out files are labeled
1137
    3) Neither          All files are labeled.
1138
 
1139
=item B<-comment=text>
1140
 
1141
This option allows a comment to be added to a label when it is created. The
1142
option has no effect if the label is not created.
1143
 
1144
=item B<-vob=name>
1145
 
1146
This option is used by commands that do not acutally place labels on files to
1147
manipulate when the user's current directry is not within a view. This allows lables to be created,
1148
locked and unlocked without having a view present.
1149
 
1150
=back
1151
 
1152
=head1 DESCRIPTION
1153
 
1154
This program provides a number of useful ClearCase labeling operations. These
1155
are:
1156
 
1157
=over 8
1158
 
1159
=item   create - create a label
1160
 
1161
=item   unlock - unlock the specified label
1162
 
1163
=item   rename - rename a label
1164
 
1165
=item   mine - change ownership of a label
1166
 
1167
=item   label - label a directory tree
1168
 
1169
=item   remove - remove the label from all labeled objects
1170
 
1171
=item   show - show all objects tagged with the label
1172
 
1173
=item   lock - lock a label
1174
 
1175
=item   delete - delete all instances of a label and the label
1176
 
1177
=item   info - describe the labels properties
1178
 
1179
=back
1180
 
1181
The various operations may be mixed in the one command. The order of the
1182
operations is: create, unlock, rename, mine, label, show, remove, delete, lock
1183
and info.
1184
 
1185
Thus it is possible to create a label, label a directory tree and then lock the
1186
label.
1187
 
1188
=head1 EXAMPLE
1189
 
1190
jats label -create -label -lock daf_br_23.0.0.syd
1191
 
1192
=cut
1193