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