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