Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2433 dpurdie 1
########################################################################
2
# Copyright (C) 1998-2012 Vix Technology, All rights reserved
3
#
4
# Module name   : cc2svn_labeldirs.pl
5
# Module type   : Makefile system
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   : Used to process package-versions that are incorrectly
10
#                 labled - the package has not been labedl up to the root
11
#                 of the VOB
12
#
13
#                 The utility works by scanning the VOB for labeled files
14
#                 It then determines the full path and will detect paths
15
#                 that have not been labled.
16
#
17
#                 It will then label them
18
#
19
#                 The search process is not fast.
20
#
21
# Usage:        jats cc2svn_labeldirs 'CC::/VobName/Path::Label'
22
#
23
#......................................................................#
24
 
25
require 5.008_002;
26
use strict;
27
use warnings;
28
 
29
use Pod::Usage;
30
use Getopt::Long;
31
 
32
use JatsError;
33
use JatsSystem;
34
 
35
#
36
#  Globals that can be set immediately
37
#
38
my $VERSION = "1.1.0";
39
my $ats = "@@";
40
my $UNIX = $ENV{'GBE_UNIX'};
41
my $UNIX_VOB_PREFIX = '/vobs/';
42
my $VOB_SEP = $UNIX ? '/' : '\\';
43
 
44
#
45
#   Options
46
#
47
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
48
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
49
my $opt_help = 0;
50
my $opt_drive = $UNIX ? '/view' : 'o:';
51
my $opt_viewname = 'administration_view';
52
my $opt_vob;
53
my $opt_label;
54
my $opt_test = 0;
55
 
56
my $vob_name;
57
my $vob_desc;
58
my $view_path;
59
my @paths;
60
my %usedDirs;
61
my %notLabled;
62
my $label_error = 0;
63
 
64
my @error_list;
65
my @last_results;
66
my $last_result;
67
my $label_exists = 0;
68
my $label_is_locked = 0;
69
my $label_is_unlocked;
70
my $label_count = 0;
71
 
72
#-------------------------------------------------------------------------------
73
# Function        : main Entry Point
74
#
75
# Description     : 
76
#
77
# Inputs          : 
78
#
79
# Returns         : 
80
#
81
my $result = GetOptions (
82
                "help:+"        => \$opt_help,
83
                "manual:3"      => \$opt_help,
84
                "verbose:+"     => \$opt_verbose,
85
                "label"         => \$opt_label,
86
                'vob:s'         => \$opt_vob,
87
                'test!'         => \$opt_test,
88
                );
89
 
90
                #
91
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
92
                #
93
 
94
#
95
#   Process help and manual options
96
#
97
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
98
pod2usage(-verbose => 1) if ( $opt_help == 2 );
99
pod2usage(-verbose => 2) if ( $opt_help > 2 );
100
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ( $#ARGV < 0 );
101
 
102
#
103
#   Configure the error reporting process now that we have the user options
104
#
105
ErrorConfig( 'name'    =>'LABELDIRS',
106
             'verbose' => $opt_verbose,
107
             'on_exit' => \&display_error_list
108
            );
109
 
110
#
111
#   Sanity test
112
#
113
Error ("No labels provided") if ( $#ARGV < 0);
114
Error ("Too many labels provided") if ( $#ARGV > 0);
115
$opt_label = $ARGV[0];
116
 
117
#
118
#   Convert label with embedded VCS information into a 'normal' form.
119
#   Form:
120
#       CC::label
121
#       CC::path::label
122
#       CC::::label
123
#
124
$opt_label =~ tr~\\/~/~s;
125
if ( $opt_label =~ m~^(.+?)::(.*?)(::(.+))?$~ )
126
{
127
    Error ("Label contains invalid Version Control Identifier($1): $_")
128
        if ( $1 ne 'CC' );
129
 
130
    my $ll = $2;
131
    my $path;
132
    if ( $3 )
133
    {
134
        $ll = $4;
135
        my @pelements = split( m'/+', $2);
136
        $path = $pelements[1] || '';
137
        if ( $path  )
138
        {
139
 
140
            Error ("Multiple conflicting Embedded Vobs",
141
                   "Vob: $opt_vob",
142
                   "VCS Spec: $opt_label" ) if ( $opt_vob && $path ne $opt_vob );
143
            $opt_vob = $path;
144
        }
145
    }
146
    $opt_label = $ll;
147
    Verbose ("Clean URL: $opt_vob, $opt_label");
148
}
149
else
150
{
151
    $opt_vob =~ s~^/~~;
152
    $opt_vob =~ s~/.*?$~~;
153
}
154
Error ("No VOB specified") unless ( $opt_vob );
155
 
156
#
157
#   Ensure that the 'cleartool' program can be located
158
#
159
Verbose ("Locate clearcase utility in users path");
160
Error ("Cannot locate the 'cleartool' utility in the users PATH")
161
    unless ( LocateProgInPath('cleartool', '--All') );
162
 
163
#
164
#   Ensure that the 'administration_view' is available
165
#   Then start the view, before checking its availability
166
#
167
if( ClearCmd('lsview', $opt_viewname) )
168
{
169
    Error ("Required view not found: $opt_viewname",
170
           "This is a dynamic view that should exist as it is used by the build system");
171
}
172
 
173
if( ClearCmd( 'startview', $opt_viewname) )
174
{
175
    Error ("Cannot start the required view: $opt_viewname");
176
}
177
 
178
$view_path = "$opt_drive/$opt_viewname";
179
$view_path .= $UNIX_VOB_PREFIX if ( $UNIX );
180
Error ("Cannot locate the required dynamic view: $view_path",
181
       "The view exits and has been started. It cannot be found")
182
    if ( ! -d $view_path  );
183
 
184
$vob_name = $UNIX_VOB_PREFIX . $opt_vob if ( $UNIX && $opt_vob !~ m~^${UNIX_VOB_PREFIX}~ );
185
$vob_name =~ s~/~$VOB_SEP~g;
186
 
187
$vob_desc = '@' . $vob_name;
188
$vob_desc =~ s~//~/~g;
189
 
190
Message ("VobName: $vob_name, $vob_desc");
191
 
192
#
193
#   Mount the target VOB, but only if its not already mounted
194
#
195
ClearCmd( 'lsvob', $vob_name);
196
unless ( $last_result =~ m~^\*\s+$vob_name~)
197
{
198
    Message ("Mounting VOB: $vob_name");
199
    if( ClearCmd( 'mount', $vob_name) )
200
    {
201
        Error ("Could not mount the VOB: $vob_name");
202
    }
203
}
204
 
205
#
206
#   Change to the directory that contains the admin view
207
#   This will ensure that the 2nd line of the dump comamnd contains
208
#   the vob extended pathname within that view. This will be used
209
#   to simplify the pairing of files
210
#
211
Verbose2 ("getIds: chdir: $view_path");
212
chdir ($view_path) || Error ("Did not chdir to $view_path" );
213
 
214
 
215
#
216
#   Ensure that the label exists inthe VOB
217
#
218
LocateLabel($opt_label);
219
 
220
#
221
#   Search the VOB for all Objects with the label
222
#   Then examine each object and determine the set of unique paths
223
#
224
@paths = findLabledOjects($opt_label);
225
processOneItem($_) foreach ( @paths );
226
 
227
#
228
#   Now have a list of paths
229
#
230
foreach my $path ( reverse sort { length($a) <=> length($b) } keys %usedDirs )
231
{
232
my $ppath = $path; $ppath =~ s~.*/vobs/~~;
233
    Verbose("Examine: $ppath");
234
    unless ( tailIsLabeled ($path) )
235
    {
236
        $notLabled{$path} = 1;
237
        Verbose("NotLabled: $ppath");
238
#print "0: $path\n";
239
    }
240
}
241
 
242
#
243
#   Walk the list of paths and label the required directories
244
#   Walk from bottom to top (longest first)
245
#
246
foreach my $path ( reverse sort { length($a) <=> length($b) } keys %notLabled )
247
{
248
    Verbose("Path: $path");
249
    my $ppath = $path;
250
    $ppath =~ s~.*/vobs/~~;
251
 
252
    my $testdir = $path;
253
    #
254
    #   One final test
255
    #
256
    unless ( tailIsLabeled ($path) )
257
    {
258
        print "$testdir - Must label\n";
259
        smartUnLock();
260
        ClearCmd ("mklabel", '-c', 'JATS cc2svn_labeldirs', $opt_label, $path ) unless $opt_test;
261
        if ( display_error_list() )
262
        {
263
            $label_error++;
264
        }
265
        else
266
        {
267
            $label_count++ unless ($opt_test);
268
        }
269
    }
270
    else
271
    {
272
        print "$ppath - Already labled\n";
273
    }
274
}
275
 
276
#
277
#   All done
278
#
279
smartLock();
280
Message ("Items Found: ". scalar @paths);
281
Message ("Labels applied: $label_count");
282
Message ("Label  errors : $label_error") if $label_error;
283
Error ("Not all required paths labled") if ( $label_error );
284
exit (0);
285
 
286
#-------------------------------------------------------------------------------
287
# Function        : tailIsLabeled
288
#
289
# Description     : Determine if the tail of the current path is labled
290
#
291
# Inputs          : $test   - Path to test
292
#
293
# Returns         : 1       - Is labled
294
#                   0       - Is not Labled
295
#
296
sub tailIsLabeled
297
{
298
    my ($test) = @_;
299
 
300
#    print "$path\n";
301
    my $found = 0;
302
    my $more = 100;
303
 
304
    #
305
    #   First remove the last element - it will be a label (number)
306
    #
307
    $test =~ s~/[^/]*?$~~;
308
    while ( $more-- )
309
    {
310
        if ( -e $test . '/' . $opt_label )
311
        {
312
            return 1;
313
        }
314
        $test =~ s~(.*)/(.*?)$~~;
315
        $more = 1 if ( $2 eq 'main' );
316
        $test = $1;
317
    }
318
    return 0;
319
}
320
 
321
#-------------------------------------------------------------------------------
322
# Function        : processOneItem
323
#
324
# Description     : Examine a CC extended path. Break it into bits and
325
#                   determine with parts of the path have not been labled
326
#
327
# Inputs          : $path               - Path to process
328
#
329
# Returns         : Fill in %usedDirs
330
#
331
sub processOneItem
332
{
333
    my ($path) = @_;
334
 
335
    #
336
    #   Break of the last bit OBJECT/main/....../nn
337
    #
338
    while ( $path =~ m~(/.*)/([^/]+/main/)(.*?)$~ )
339
    {
340
        $path = $1;
341
        my $tagPath = $path;
342
        $tagPath =~ s~/\d+$~~;
343
        $usedDirs{$path} = 1 if $tagPath =~ m~\@\@~;
344
    }
345
}
346
 
347
#-------------------------------------------------------------------------------
348
# Function        : findLabledOjects
349
#
350
# Description     : Find all objects on the VOB with the specified label
351
#
352
# Inputs          : $opt_label      - Label to find
353
#
354
# Returns         : Results into @paths
355
#
356
sub findLabledOjects
357
{
358
    my ($opt_label) = @_;
359
    my @results;
360
    Message ("Locate objects in VOB: $opt_vob" );
361
 
362
    my $cmd = QuoteCommand("cleartool", "find", "$opt_vob", '-all', "-version", "lbtype($opt_label)", "-print");
363
    Verbose2($cmd);
364
 
365
    open(SHOWCMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
366
    while (<SHOWCMD>)
367
    {
368
        #
369
        #   Filter output from the user
370
        #
371
        chomp;
372
        Verbose3($_);
373
        push @results, $_;
374
    }
375
    close(SHOWCMD);
376
    return @results;
377
}
378
 
379
#-------------------------------------------------------------------------------
380
# Function        : LocateLabel
381
#
382
# Description     : Check that the label exists
383
#                   Determine if the label is locked
384
#
385
# Inputs          : $opt_label  - Label to locate
386
#
387
# Returns         : Nothing
388
#
389
sub LocateLabel
390
{
391
    Verbose ("Check label");
392
    ClearCmd ("describe", "-fmt", "%[locked]p", "lbtype:$opt_label$vob_desc" );
393
    $label_exists = 1 unless( $opt_test
394
                          || grep ( /Label type not found/, @error_list )
395
                          || grep ( /Unable to determine VOB/, @error_list )
396
                            );
397
    if ( $label_exists && $last_result )
398
    {
399
        $label_is_locked = ($last_result =~ m~unlocked~)? 0:1;
400
    }
401
    Verbose ("Check label: Exist:$label_exists, Locked:$label_is_locked");
402
}
403
 
404
#-------------------------------------------------------------------------------
405
# Function        : smartLock
406
#
407
# Description     : Lock, unlock label
408
#
409
# Inputs          : mode            : 1 - lock if it was unclocked
410
#                                     0 - unlock unless already done
411
#
412
# Returns         : 
413
#
414
sub smartUnLock
415
{
416
    if ( $label_is_locked && ! $label_is_unlocked)
417
    {
418
        ClearCmd ("unlock", "lbtype:$opt_label$vob_desc" ) unless $opt_test;
419
        Error ("Program Terminated") if ( @error_list );
420
        $label_is_unlocked = 1;
421
    }
422
}
423
 
424
sub smartLock
425
{
426
    if ( $label_is_unlocked)
427
    {
428
        ClearCmd ("lock", "lbtype:$opt_label$vob_desc" ) unless $opt_test;
429
        Error ("Program Terminated") if ( @error_list );
430
        $label_is_unlocked = 0;
431
    }
432
}
433
 
434
#-------------------------------------------------------------------------------
435
# Function        : ClearCmd
436
#
437
# Description     : Similar to the system command
438
#                   Does allow standard output and standard error to be captured
439
#                   to a log file
440
#
441
#                   Used since I was having problems with calling other programs
442
#                   and control-C. It could hang the terminal session.
443
#
444
# Inputs          :
445
#
446
# Returns         :
447
#
448
sub ClearCmd
449
{
450
    my $cmd = QuoteCommand (@_);
451
    Verbose2 "cleartool $cmd";
452
 
453
        @error_list = ();
454
        @last_results = ();
455
        $last_result = undef;
456
        my $cmd_handle;
457
        open($cmd_handle, "sudo -u buildadm cleartool $cmd  2>&1 |")    || Error "can't run command: $!";
458
        while (<$cmd_handle>)
459
        {
460
            chomp;
461
            $last_result = $_;
462
            $last_result =~ tr~\\/~/~s;
463
            push @last_results, $last_result;
464
            Verbose ( "cleartool resp:" . $_);
465
            push @error_list, $_ if ( m~Error:~ );
466
        }
467
        close($cmd_handle);
468
 
469
    Verbose2 "Exit Status: $?";
470
    return $? / 256;
471
}
472
 
473
#-------------------------------------------------------------------------------
474
# Function        : display_error_list
475
#
476
# Description     : Display the error list
477
#                   This function is registered as an Error callback function
478
#                   it will be called on error exit
479
#
480
#                   Will clear error list when called, so that it can be used
481
#                   in non-exit situations.
482
#
483
# Inputs          :
484
#
485
# Returns         : true            - Errors in list
486
#                   false           - No error in list
487
#
488
sub display_error_list
489
{
490
    return 0 unless ( @error_list );
491
    print "$_\n" foreach ( @error_list );
492
    @error_list = ();
493
 
494
    smartLock();
495
    return 1;
496
}
497
 
498