Subversion Repositories DevTools

Rev

Rev 241 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 241 Rev 247
Line 14... Line 14...
14
use strict;
14
use strict;
15
use warnings;
15
use warnings;
16
use JatsError;
16
use JatsError;
17
use JatsSystem;
17
use JatsSystem;
18
use Pod::Usage;                             # required for help support
18
use Pod::Usage;                             # required for help support
19
use Cwd;
-
 
20
 
-
 
21
use Getopt::Long;
19
use Getopt::Long;
-
 
20
use FileUtils;
22
 
21
 
23
#-------------------------------------------------------------------------------
22
#-------------------------------------------------------------------------------
24
#
23
#
25
#  Function Prototypes
24
#  Function Prototypes
26
#
25
#
27
sub prevElement($);
26
sub populateFilesArray($$$\%);
-
 
27
sub files_from_view($$$$\%);
-
 
28
sub generateOutputFilename(\$);
28
sub get_newFiles();
29
sub getTags();
29
sub get_prev_viewname();
30
sub parseTag(\$\$\$);
30
sub get_workingDirectory();
31
sub getClearToolFindOutput($$);
-
 
32
sub element0($);
-
 
33
sub getIds($@);
-
 
34
sub massage_path($\$$\$);
31
 
35
 
32
#-------------------------------------------------------------------------------
36
#-------------------------------------------------------------------------------
33
#
37
#
34
#  Global variables
38
#  Global variables
35
#
39
#
36
my $VERSION = "1.0.1";                      # Update this
-
 
37
 
40
 
-
 
41
#
-
 
42
# Update this:
-
 
43
#
-
 
44
my $VERSION = "1.0.3";                      
38
 
45
 
39
#
46
#
40
#   Globals - Provided by the JATS environment
47
#  Globals that can be set immediately
41
#
48
#
-
 
49
my $ats = "@@";
42
my $UNIX            = $ENV{'GBE_UNIX'};
50
my $UNIX = $ENV{'GBE_UNIX'};
-
 
51
my $UNIX_VOB_PREFIX = '/vobs';
-
 
52
my $VOB_SEP = $UNIX ? '/' : '\\';
43
 
53
 
44
#
54
#
45
#   Options
55
#   Options
46
#
56
#
47
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
57
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
Line 50... Line 60...
50
my $opt_manual = 0;
60
my $opt_manual = 0;
51
my $opt_drive = $UNIX ? '/view' : 'o:';
61
my $opt_drive = $UNIX ? '/view' : 'o:';
52
my $opt_viewname = 'administration_view';
62
my $opt_viewname = 'administration_view';
53
my $opt_outfile;
63
my $opt_outfile;
54
my @opt_vobs;
64
my @opt_vobs;
55
my $opt_new_label;
65
my $opt_new;
56
my $opt_old_label;
66
my $opt_old;
-
 
67
my $opt_massage = 1;
57
 
68
 
58
#
69
#
59
#   Globals
70
#  Globals that are set within the script
60
#
71
#
61
my @error_list;                             # ClearCmd detected errors
72
my @error_list;                             # ClearCmd detected errors
62
my $UNIX_VOB_PREFIX = '/vobs';
-
 
63
my $VOB_SEP         = $UNIX ? '/' : '\\';
-
 
64
my $view_path;
73
my $view_path;
65
my @view_tags;
74
my @view_tags;
66
my %files;
75
my %files;
-
 
76
my %clearCaseInfos;
-
 
77
 
67
my %diffs;
78
my $oldLabel;
-
 
79
my $newLabel;
-
 
80
my $oldDirectory;
68
( my $startDirectory = getcwd() ) =~ s/[\n\r]+$//;
81
my $newDirectory;
69
 
82
 
70
#
83
#
71
#   ROOT_VOBS is a list of VOBS too look in first
84
#   ROOT_VOBS is a list of VOBS too look in first
72
#   If a label is not found in these vobs, then the program will
85
#   If a label is not found in these vobs, then the program will
73
#   look in all vobs. This list is a hint to speed up searching
86
#   look in all vobs. This list is a hint to speed up searching
74
#
87
#
75
my @ROOT_VOBS = qw( /LMOS /DPG_SWBase /DPG_SWCode /ProjectCD /MASS_Dev_Bus
88
my @ROOT_VOBS = qw( /LMOS /DPG_SWBase /DPG_SWCode /ProjectCD /MASS_Dev_Bus
76
                    /MASS_Dev_Infra /MOS /MASS_Dataman /MASS_Dev /MASS_Dev_Dataman
89
                    /MASS_Dev_Infra /MOS /MASS_Dataman /MASS_Dev /MASS_Dev_Dataman
77
                    /COTS /GMPTE2005 /GMPTE2005_obe /MPR /MOS );
90
                    /COTS /GMPTE2005 /GMPTE2005_obe /MPR /MOS );
78
 
91
 
79
 
-
 
80
 
-
 
81
#-------------------------------------------------------------------------------
92
#-------------------------------------------------------------------------------
82
# Function        : Mainline Entry Point
-
 
83
#
93
#
84
# Description     :
-
 
85
#
-
 
86
# Inputs          :
94
#  Mainline entry point
87
#
95
#
-
 
96
InitFileUtils();
88
 
97
 
89
#
98
#
90
#   Parse the user options
99
#   Parse the user options
91
#
100
#
92
my $result = GetOptions (
101
my $result = GetOptions (
93
                "help+"         => \$opt_help,              # flag, multiple use allowed
102
    "help+"         => \$opt_help,              # flag, multiple use allowed
94
                "manual"        => sub{ $opt_help = 3},     # flag, multiple use allowed
103
    "manual"        => sub{ $opt_help = 3},     # flag, multiple use allowed
95
                "verbose+"      => \$opt_verbose,           # flag, multiple use allowed
104
    "verbose+"      => \$opt_verbose,           # flag, multiple use allowed
96
                "output=s"      => \$opt_outfile,           # String
105
    "output=s"      => \$opt_outfile,           # String
97
                "new=s"         => \$opt_new_label,         # String
106
    "new=s"         => \$opt_new,               # String
98
                "old=s"         => \$opt_old_label,         # String
107
    "old=s"         => \$opt_old,               # String
99
                "drive=s"       => \$opt_drive,             # String
108
    "drive=s"       => \$opt_drive,             # String
100
                "vob=s"         => \@opt_vobs,              # String
109
    "vob=s"         => \@opt_vobs,              # String
-
 
110
    "massage!"      => \$opt_massage,           # [no]flag
101
                );
111
    );
102
 
112
 
103
                #
113
#
104
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
114
#   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
105
                #
115
#
106
 
116
 
107
#
117
#
108
#   Process help and manual options
118
#   Process help and manual options
109
#
119
#
110
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result );
120
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result );
Line 116... Line 126...
116
#
126
#
117
ErrorConfig( 'name'    => 'CCDIFF',
127
ErrorConfig( 'name'    => 'CCDIFF',
118
             'verbose' => $opt_verbose );
128
             'verbose' => $opt_verbose );
119
 
129
 
120
#
130
#
121
#   Be nice to the user
-
 
122
#   If we have two options and no labels, then assigne them
-
 
123
#
-
 
124
if ( ! $opt_new_label && ! $opt_old_label )
-
 
125
{
-
 
126
    Error ("Must provide two labels on command line unless they are provided via -old and -new options")
131
#   Work out '$oldLabel', '$newLabel', '$oldDirectory', '$newDirectory' tags
127
         if ( $#ARGV < 1 );
-
 
128
 
-
 
129
    $opt_old_label = shift @ARGV;
-
 
130
    $opt_new_label = shift @ARGV;
-
 
131
}
-
 
132
 
-
 
133
#
-
 
134
#   Error check the user arguments
-
 
135
#
132
#
136
Error ("Need to provide the 'new' label")
-
 
137
    unless ( $opt_new_label );
133
getTags();
138
 
134
 
139
Error ("Too many command line arguments" )
135
Error ("Too many command line arguments" )
140
    unless ( $#ARGV < 0 );
136
    unless ( $#ARGV < 0 );
141
 
137
 
142
#
-
 
143
# $workingDirectory is only used if compareWithDirectory == 1, which is
-
 
144
# only true when user has specified that -new points to a directory
-
 
145
#
-
 
146
my ( $workingDirectory, $compareWithDirectory ) = get_workingDirectory ();
-
 
147
 
-
 
148
#
-
 
149
#   Generate a default ouput put file name
-
 
150
#
-
 
151
unless ( $opt_outfile )
-
 
152
{
-
 
153
    if ( $opt_old_label )
-
 
154
    {
-
 
155
        $opt_outfile = "${opt_old_label}-${opt_new_label}-diff.txt";
-
 
156
    }
-
 
157
    else
-
 
158
    {
-
 
159
        $opt_outfile = "${opt_new_label}-diff.txt";
-
 
160
    }
-
 
161
}
-
 
162
Verbose ("Output file: $opt_outfile");
138
generateOutputFilename($opt_outfile);
163
 
139
 
164
#
140
#
165
#   Determine the machine type
141
#   Determine the machine type
166
#
142
#
167
Verbose ("Machine Type: UNIX=$UNIX");
143
Verbose ("Machine Type: UNIX=$UNIX");
Line 172... Line 148...
172
Verbose ("Locate clearcase utility in users path");
148
Verbose ("Locate clearcase utility in users path");
173
Error ("Cannot locate the 'cleartool' utility in the users PATH")
149
Error ("Cannot locate the 'cleartool' utility in the users PATH")
174
    unless ( LocateProgInPath('cleartool', '--All') );
150
    unless ( LocateProgInPath('cleartool', '--All') );
175
 
151
 
176
#
152
#
177
#   Ensure that the 'administration_view' is availalable
153
#   Ensure that the 'administration_view' is available
178
#   Then start the view, before checking its availability
154
#   Then start the view, before checking its availability
179
#
155
#
180
if( ClearCmd('lsview', $opt_viewname) )
156
if( ClearCmd('lsview', $opt_viewname) )
181
{
157
{
182
    Error ("Required view not found: $opt_viewname",
158
    Error ("Required view not found: $opt_viewname",
183
           "This is a dynamic view that should exist as it is used by the build system"
159
           "This is a dynamic view that should exist as it is used by the build system");
184
          );
-
 
185
}
160
}
186
 
161
 
187
#
-
 
188
# Under windows if user is comparing with a directory you need knowledge of under
-
 
189
# what view the command was invoked with
-
 
190
#
-
 
191
#my $prev_viewname = "";
-
 
192
#$prev_viewname = get_prev_viewname() if( $compareWithDirectory && ! $UNIX );
-
 
193
 
-
 
194
if( ClearCmd( 'startview', $opt_viewname) )
162
if( ClearCmd( 'startview', $opt_viewname) )
195
{
163
{
196
    Error ("Cannot start the required view: $opt_viewname");
164
    Error ("Cannot start the required view: $opt_viewname");
197
}
165
}
198
 
166
 
199
$view_path = "$opt_drive/$opt_viewname";
167
$view_path = "$opt_drive/$opt_viewname";
200
$view_path .= $UNIX_VOB_PREFIX if ( $UNIX );
168
$view_path .= $UNIX_VOB_PREFIX if ( $UNIX );
201
if ( ! -d $view_path  )
-
 
202
{
-
 
203
    Error ("Cannot locate the required dynamic view: $view_path",
169
Error ("Cannot locate the required dynamic view: $view_path",
204
            "The view exits and has been started. It cannot be found"
170
       "The view exits and has been started. It cannot be found")
205
          );
171
    if ( ! -d $view_path  );
206
}
-
 
207
 
172
 
208
#
173
#
209
#
-
 
210
#   Extend the list of ROOT_VOBS with all the known vobs
174
#   Determine the list of VOBs to scan for a label
211
#   The initial ROOT_VOBS are treated as a "hint" to assist searching
175
#   This may be user specified or all the known vobs
212
#
176
#
213
if ( @opt_vobs )
177
if ( @opt_vobs )
214
{
178
{
-
 
179
    #
-
 
180
    #   User has provided a list of vobs to search
-
 
181
    #   Use this list
-
 
182
    #
215
    @ROOT_VOBS = ();
183
    @ROOT_VOBS = ();
216
    foreach my $vob ( @opt_vobs )
184
    foreach my $vob ( @opt_vobs )
217
    {
185
    {
218
        $vob = '/' . $vob;
186
        $vob = '/' . $vob;
219
        $vob =~ s~^$UNIX_VOB_PREFIX~~ if ($UNIX);
187
        $vob =~ s~^$UNIX_VOB_PREFIX~~ if ($UNIX);
Line 221... Line 189...
221
        push @ROOT_VOBS, $vob;
189
        push @ROOT_VOBS, $vob;
222
    }
190
    }
223
}
191
}
224
else
192
else
225
{
193
{
-
 
194
    #
-
 
195
    #   Extend the list of ROOT_VOBS with all the known vobs
-
 
196
    #   The initial ROOT_VOBS are treated as a "hint" to assist searching
-
 
197
    #
226
    my $cmd = "cleartool lsvob -short";
198
    my $cmd = "cleartool lsvob -short";
227
    open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
199
    open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
228
    while (<CMD>)
200
    while (<CMD>)
229
    {
201
    {
230
        #
202
        #
Line 240... Line 212...
240
}
212
}
241
 
213
 
242
#
214
#
243
#   Ensure the two labels are present - determine the VOB root
215
#   Ensure the two labels are present - determine the VOB root
244
#
216
#
245
my $l1_vob = LocateLabel( $opt_old_label) if $opt_old_label;
217
my $oldLabelVob = $oldLabel ? LocateLabel( $oldLabel ) : "";
246
my $l2_vob = LocateLabel( $opt_new_label);
218
my $newLabelVob = $newLabel ? LocateLabel( $newLabel ) : "";
247
 
219
 
248
#
220
#
-
 
221
#   Massage the directory path
-
 
222
#   If the user has provided a directory, then we will compare the
249
#   Locate all files for the two labels
223
#   entire contents of the directory against the label
250
#
224
#
251
files_from_view( $l1_vob, $opt_old_label, 1 ) if $opt_old_label;
225
massage_path( $oldLabelVob, $oldDirectory, $newLabelVob, $newDirectory  )
252
files_from_view( $l2_vob, $opt_new_label, 2 );
226
    if ( $opt_massage );
253
 
-
 
254
#DebugDumpData ("Files", \%files );
-
 
255
 
227
 
256
#
228
#
257
#   Create a hash of files that are different
229
#   Locate all files for the two areas
258
#   The hash key will be the file name
-
 
259
#   The tag will be the branch that the file is on
-
 
260
#
230
#
261
foreach my $file ( sort keys %files )
-
 
262
{
231
{
263
    #
-
 
264
    #   These files are the same
232
    my %initialFilePaths;
265
    #
233
 
266
    next if ( $files{$file}{1} && $files{$file}{2} );
234
    files_from_view( $oldLabelVob, $oldLabel, 1, $oldDirectory, %initialFilePaths );
267
    
-
 
268
    my $tag = 1;
-
 
269
    $tag = 2 if $files{$file}{2};
235
    files_from_view( $newLabelVob, $newLabel, 2, $newDirectory, %initialFilePaths );
270
    
-
 
271
    #
-
 
272
    #   Break path into file and version
236
    #DebugDumpData ("initialFilePaths", \%initialFilePaths );
273
    #
237
 
274
    $file =~ m~(.*)(@@[^@]*$)~;
238
    populateFilesArray( $oldLabel, 1, $oldDirectory, %initialFilePaths);
275
    my ($f,$b) = ($1,$2);
239
    populateFilesArray( $newLabel, 2, $newDirectory, %initialFilePaths);
276
    $diffs{$f}{$tag} = $file;  
240
    #DebugDumpData ("Files", \%files );
277
}
241
}
278
 
242
 
-
 
243
 
279
#
244
#
-
 
245
#   Have a structure that contains files for both the old and new labels
280
#   Process files that are common, but have changed
246
#   Scan the list locating files that are different
281
#
247
#
282
my @no_text;
248
my @no_text;
283
my $added = 0;
249
my $added = 0;
284
my $deleted = 0;
250
my $deleted = 0;
285
my $diffs = 0;
251
my $ndiffs = 0;
286
my $ifile = 0;
252
my $ifile = 0;
287
 
253
 
-
 
254
Verbose ("Opening file in current directory", $opt_outfile, Getcwd() );
288
open (FO, ">", "$startDirectory/$opt_outfile") || Error ("Cannot open file: $startDirectory/$opt_outfile");
255
open (FO, ">$opt_outfile") || Error ("Cannot open file: $opt_outfile", "Reason: $!");
289
 
256
 
290
foreach my $file ( sort keys %diffs )
257
foreach my $id ( sort keys %files )
291
{
258
{
292
    $ifile ++;
259
    $ifile ++;
293
 
260
 
294
    print "Running ClearDiff on file $ifile/" . scalar(keys %diffs) . "            \r";
261
    Verbose("Computing differences for file $ifile/" . scalar(keys %files));
295
 
262
 
296
    my ($hs, $id, $type);
263
    my ($hs, $aid);
297
    #
-
 
298
    #   Files are are common
-
 
299
    #
264
 
300
    if ( $diffs{$file}{1} && $diffs{$file}{2} )
265
    if ( $files{$id}{1} && $files{$id}{2} ) #  File exists in both areas:
301
    {
266
    {
-
 
267
        #
-
 
268
        #   Test for files existing in both tags and being identical
-
 
269
        #
-
 
270
        next if( $files{$id}{1} eq $files{$id}{2} );
-
 
271
 
-
 
272
        #
302
	$type = "different";
273
        #   Files are in both areas, but are different
-
 
274
        #   Perform diff. There may be cases where they are really the same text
-
 
275
        #   or the only change is in white space.
-
 
276
        #
303
	($hs, $id) = ClearDiff("-serial_format", "-blank_ignore", $diffs{$file}{1}, $diffs{$file}{2});
277
        ($hs, $aid) = ClearDiff("-serial_format", "-blank_ignore", $files{$id}{1}, $files{$id}{2});
304
	$diffs++ if ( $hs );
278
        $ndiffs++ if ( $hs );
305
    }
279
    }
306
    elsif ($diffs{$file}{1} )
280
    elsif( $files{$id}{1} ) # File doesn't exist in 'new' area:
307
    {
281
    {
308
	#
-
 
309
	#   File has been deleted
-
 
310
	#
-
 
311
	$type = "deleted";
-
 
312
	Verbose ("$file has been deleted");
-
 
313
	($hs, $id) = ClearDiff("-serial_format", $diffs{$file}{1}, element0($diffs{$file}{1}) );
282
        ($hs, $aid) = ClearDiff("-serial_format", $files{$id}{1}, element0($files{$id}{1}) );
314
	$deleted++ if ( $hs );
283
        $deleted++ if ( $hs );
315
    }
284
    }
316
    else
285
    elsif( $files{$id}{2} ) # File doesn't exist in 'old' area:
317
    {
286
    {
318
	#
-
 
319
	#   File has been added
-
 
320
	#
-
 
321
	$type = "added";
-
 
322
	if( $compareWithDirectory )
-
 
323
	{
-
 
324
	    my $cmd = QuoteCommand( 'cleartool', 'dump', $diffs{$file}{2} );
-
 
325
 
-
 
326
	    open( CMD, "$cmd 2>&1 |") or Error("can't run command: $!");
-
 
327
	    <CMD>; # line 1 - blank
-
 
328
	    <CMD>; # line 2 - clearcase filename and a code for it
-
 
329
	    (my $basefilename = <CMD>) =~ s~[\n\r]+$~~; # line 3 is what we want
-
 
330
	    while( <CMD> ){} # Get rid of broken pipe messages
-
 
331
	    close( CMD );
-
 
332
 
-
 
333
	    $basefilename =~ s{@@.*}{}; # strip off the branch/version number
-
 
334
#	    $basefilename = "${opt_drive}/${prev_viewname}${basefilename}" if( ! $UNIX );
-
 
335
 
-
 
336
	    ($hs, $id) = ClearDiff("-serial_format", $diffs{$file}{2}, $basefilename );
-
 
337
	    $diffs++ if ( $hs );
-
 
338
	}
-
 
339
	else
-
 
340
	{
-
 
341
	    ($hs, $id) = ClearDiff("-serial_format", element0($diffs{$file}{2}) , $diffs{$file}{2} );
287
        ($hs, $aid) = ClearDiff("-serial_format", element0($files{$id}{2}), $files{$id}{2} );
342
	    $added++ if ( $hs );
288
        $added++ if ( $hs );
343
	}
-
 
344
    }
289
    }
345
 
-
 
346
    $type = "identical"
-
 
347
	if ( $id  );
-
 
348
    $file = StripView($file);
-
 
349
    Verbose ("$type: $file" );
-
 
350
    
-
 
351
    push @no_text, $file unless ( $hs || $id );
-
 
352
}
-
 
353
 
-
 
354
#
-
 
355
# If comparing with a directory, do additional files that have been
-
 
356
# added since the label
-
 
357
#
-
 
358
if( $compareWithDirectory )
-
 
359
{
-
 
360
    my @newFiles = get_newFiles();
-
 
361
 
-
 
362
    my ($hs, $id);
290
    else # bug!
363
    my $type = "added";
-
 
364
 
-
 
365
    Message ("Going to run cleardiff for new files") if( @newFiles );
-
 
366
 
-
 
367
    foreach my $newFile (@newFiles)
-
 
368
    {
291
    {
369
	my $prev_element = prevElement($newFile);
-
 
370
 
-
 
371
	($hs, $id) = ClearDiff("-serial_format", $prev_element, $newFile );
292
        Error("Internal BUG in main line!  Please report!",
372
	$added++ if ( $hs );
-
 
373
	
-
 
374
	$type = "identical" if ( $id  );
-
 
375
	$newFile = StripView($newFile);
-
 
376
	Verbose ("$type: $newFile" );
-
 
377
	
-
 
378
	push @no_text, $newFile unless ( $hs || $id );
293
              "id='$id' ifile=$ifile neither has a 1 nor a 2 tag");
379
    }
294
    }
-
 
295
 
-
 
296
    push @no_text, $files{$id}{1} if ( $files{$id}{1} && ! $hs && ! $aid );
-
 
297
    push @no_text, $files{$id}{2} if ( $files{$id}{2} && ! $hs && ! $aid );
380
}
298
}
381
 
299
 
-
 
300
close FO;
-
 
301
 
382
#
302
#
383
#   Warn about problem files
303
#   Warn about problem files
384
#
304
#
385
if ( @no_text )
305
if ( @no_text )
386
{
306
{
Line 390... Line 310...
390
 
310
 
391
#
311
#
392
#   Summary information
312
#   Summary information
393
#
313
#
394
Information ("Summary Information",
314
Information ("Summary Information",
395
             "Old Label:         : " . ( $opt_old_label ? $opt_old_label : '-None-') ,
315
             "Old:               : " . $oldLabel ? $oldLabel : $oldDirectory,
396
             "New Label:         : $opt_new_label",
316
             "New:               : " . $newLabel ? $newLabel : $newDirectory,
397
             "Files different    : $diffs",
317
             "Files different    : $ndiffs",
398
             "Files added        : $added",
318
             "Files added        : $added",
399
             "Files deleted      : $deleted",
319
             "Files deleted      : $deleted",
400
             "Files not in report: " . scalar(@no_text),
320
             "Files not in report: " . scalar(@no_text),
401
             "Output file        : $startDirectory/$opt_outfile",
321
             "Output file        : $opt_outfile"
402
             );
322
             );
403
 
323
 
404
 
-
 
405
#DebugDumpData ("Files", \%diffs);
-
 
406
 
-
 
407
close FO;
-
 
408
exit (0);
324
exit (0);
409
 
325
 
-
 
326
 
410
#-------------------------------------------------------------------------------
327
#-------------------------------------------------------------------------------
411
# Function        : get_workingDirectory
328
# Function        : generateOutputFilename
412
#
329
#
413
# Description     : Works out the working directory that should be used if the
330
# Description     : Works out what the output diff filename should be
414
#                   user has specified that the 'new' label is really a directory 
-
 
415
#
331
#
-
 
332
# Inputs          : $oldLabel, $newLabel
416
#
333
#
417
# Inputs          : 
334
# Input/Output    : reference to $opt_outfile
418
#
335
#
419
# Returns         : $workingDirectory    - The directory to compare with
336
# Returns         : 
420
#                   $compareWithDirectory - 1 (true) if the user has specified that
-
 
421
#                                          a directory is to be compared
-
 
422
#
337
#
423
sub get_workingDirectory()
338
sub generateOutputFilename(\$)
424
{
339
{
425
    return ("", 0) if( $opt_new_label !~ m/^dir=/ && $opt_new_label !~ m/^current/ );
-
 
426
 
-
 
427
    my $workingDirectory = "";
340
    my $refOpt_outfile = shift;
428
 
341
 
429
    $workingDirectory = $startDirectory 
342
    unless( $$refOpt_outfile )
430
	if ( $opt_new_label eq 'current' || $opt_new_label eq "dir=current" );
-
 
431
    
-
 
432
    if ( $opt_new_label =~ m~^dir=(.+)~ || $opt_new_label =~ m~^current=(.+)~ )
-
 
433
    {
343
    {
-
 
344
        $$refOpt_outfile = "${oldLabel}-${newLabel}-diff.txt" if(  $oldLabel &&  $newLabel );
-
 
345
        $$refOpt_outfile = "${oldLabel}-diff.txt"             if(  $oldLabel && !$newLabel );
-
 
346
        $$refOpt_outfile = "${newLabel}-diff.txt"             if( !$oldLabel &&  $newLabel );
434
	my $wdir = $1;
347
        $$refOpt_outfile = "directoryDifferences-diff.txt"    if( !$oldLabel && !$newLabel );
435
 
348
 
436
	if( ! $UNIX && $wdir =~ m~^.:~ ) # on windows, directory has been specified as a full drive path
-
 
437
	{
-
 
438
	    $workingDirectory = $wdir;
349
        #
439
	}
-
 
440
	elsif( $wdir =~ m~^/~ || ($wdir =~ m~^\\~ && ! $UNIX) ) # Full path on the current drive
350
        #   If the label has ugly characaters in it then we won't be able to create
441
	{
-
 
442
	    $workingDirectory = $wdir;
351
        #   a nice file name. Sanitise the filename
443
	}
352
        #
444
	else # Relative path
353
        $$refOpt_outfile =~ s{[\\/:]+}{_}g;
445
	{
-
 
446
	    $workingDirectory = "$startDirectory/$wdir"; 
354
        $$refOpt_outfile =~ s{_+}{_}g;
447
	}
-
 
448
    }
355
    }
449
 
356
 
-
 
357
    #
-
 
358
    # Do an early check that output file can be written to
-
 
359
    #
-
 
360
    open( Z, ">$$refOpt_outfile") or Error("Could not open '$$refOpt_outfile' for writing");
-
 
361
    close( Z );
-
 
362
    unlink $$refOpt_outfile;
-
 
363
}
-
 
364
 
-
 
365
 
-
 
366
#-------------------------------------------------------------------------------
-
 
367
# Function        : getTags
-
 
368
#
-
 
369
# Description     : Works out whether using labels or directories, and fills in
450
    Verbose ("working directory: '$workingDirectory'");
370
#                   $oldLabel or $oldDirectory
-
 
371
#                   $newLabel or $newDirectory
-
 
372
#                   Function works with $opt_new, $opt_old, @ARGV
-
 
373
#
-
 
374
# Inputs          : 
-
 
375
#
-
 
376
# Returns         : 
-
 
377
#
-
 
378
sub getTags()
-
 
379
{
-
 
380
    # If we have two options and no labels, then assign them
-
 
381
    if ( ! $opt_new && ! $opt_old )
-
 
382
    {
-
 
383
        Error ("Must provide two labels on command line unless they are provided " .
-
 
384
               "via -old and -new options") if ( $#ARGV < 1 );
451
 
385
 
452
    Error("Could not find the directory '$workingDirectory'")
386
        $opt_old = shift @ARGV;
453
	unless( -d $workingDirectory );
387
        $opt_new = shift @ARGV;
-
 
388
    }
454
 
389
 
-
 
390
    Error ("Need to provide the 'new' label/directory") unless ( $opt_new );
455
    chdir $workingDirectory or Error ("Could not chdir into '$workingDirectory'");
391
    Error ("Need to provide the 'old' label/directory") unless ( $opt_old );
456
 
392
 
457
    # We go through the same algorithm in many parts as the
-
 
458
    # no-minus-old algorithm, so to minimise code changes we just 
-
 
459
    # treat it the same with the addition of the '$compareWithDirectory' flag
393
    parseTag($opt_old, $oldLabel, $oldDirectory);
460
    # to execute additional code.
-
 
461
    $opt_new_label = $opt_old_label;
394
    parseTag($opt_new, $newLabel, $newDirectory);
462
    $opt_old_label = "";
-
 
463
 
395
 
464
    return( $workingDirectory, 1);
396
    Error("Cannot compare two directories") if( $oldDirectory && $newDirectory );
465
}
397
}
466
 
398
 
467
 
399
 
468
#-------------------------------------------------------------------------------
400
#-------------------------------------------------------------------------------
469
# Function        : prevElement
401
# Function        : parseTags
470
#
402
#
471
# Description     : Works out the element that should be compared with the 
403
# Description     : Worker function for getTags() - parses a "-new"/"-old" option
472
#                   file in the working directory.
-
 
473
#
404
#
-
 
405
# Inputs          : $retOpt - reference to the command line argument
-
 
406
#                   $refLabel - reference to the label variable that may be initialised
-
 
407
#                   $refDirectory - reference to the directory variable that may be initialised
474
#
408
#
475
# Inputs          : $newFile        - File found by cleartool ls'ing the
-
 
476
#                                     working directory
409
# Returns         : 
477
#
410
#
478
# Returns         : $prevElement - the element to cleardiff on
-
 
479
#
-
 
480
sub prevElement($)
411
sub parseTag(\$\$\$)
481
{
412
{
482
    my ( $newFile ) = @_;
413
    my ($refOpt,$refLabel,$refDirectory) = @_;
483
 
414
 
-
 
415
    if( $$refOpt =~ m/^dir=(.*)/ )
-
 
416
    {
-
 
417
        $$refLabel = "";
484
    my $cmd = qq(cleartool find $newFile -directory -version "{lbtype($opt_new_label)}" -print);
418
        $$refDirectory = ($1 eq "current") ? "." : $1;
-
 
419
        $$refDirectory =~ tr{\\/}{/}s;
-
 
420
        $$refDirectory =~ s~/$~~;
-
 
421
    }
-
 
422
    elsif( $$refOpt =~ m/^current/ )
-
 
423
    {
-
 
424
        $$refLabel = "";
-
 
425
        $$refDirectory = ".";
-
 
426
    }
-
 
427
    else
-
 
428
    {
-
 
429
        $$refLabel = $$refOpt;
-
 
430
        $$refDirectory = "";
485
 
431
 
-
 
432
        #
486
    Verbose ("Cmd: '$cmd'");
433
        #   Sanity check
-
 
434
        #   Labels shouldn't have directory seperator characters in them
-
 
435
        #   The user may have mis-used the command
-
 
436
        #
-
 
437
        if ( $$refOpt =~ m~[/\\]~  )
-
 
438
        {
-
 
439
            Warning("Label has slashes in it. Looks like a directory",
-
 
440
            "Did you mean 'dir=$$refOpt'?",
-
 
441
            "Continuing anyway...");
-
 
442
        }
-
 
443
    }
-
 
444
}
487
 
445
 
-
 
446
#-------------------------------------------------------------------------------
-
 
447
# Function        : populateFilesArray
-
 
448
#
-
 
449
# Description     : Populates the global '%files' hash array.  It does this
-
 
450
#                   by taking as input a hash array that is the output of cleartool
-
 
451
#                   find/ls, and, for files that did not come up identical for both
-
 
452
#                   old and new labels, calling cleartool dump to get the info
-
 
453
#                   to put into the '%files' hash.
-
 
454
#
-
 
455
# Inputs          : $label          - Label (not set if $directory defined)
-
 
456
#                   $tag            - File tag (1 for 'old' or 2 for 'new')
-
 
457
#                   $directory      - Directory name (not set if $label defined)
-
 
458
#                   $refInitialFilePaths - reference to the hash array that stores the
-
 
459
#                                          output of previous calls to cleartool find/ls.
-
 
460
#
-
 
461
# Returns         : Nothing
488
    my $ret = "${newFile}@@/main/0";
462
#                   Populates the %files array
-
 
463
#
-
 
464
sub populateFilesArray($$$\%)
-
 
465
{
-
 
466
    my ($label, $tag, $directory, $refInitialFilePaths) = @_;
489
 
467
 
-
 
468
    #######################
490
    open( CMD, "$cmd 2>&1 |") or Error("can't run command: $!");
469
    # Step 1: Get an array of filenames
491
    while( <CMD> )
470
    my @initialFilePaths;
-
 
471
 
-
 
472
    foreach my $initialFilePath (sort keys %$refInitialFilePaths)
492
    {
473
    {
-
 
474
        # If a file exists in both labels and has the same initial file path
-
 
475
        # we just assume that the ids are identical and that 
-
 
476
        # cleartool dump does not need to be called
-
 
477
        # This saves execution time.
-
 
478
        # Instead - we just use the file path as the id
493
        s~[\n\r]+$~~;
479
        #
494
	next if( m/Error:/ || m/Warning:/ );
480
        if( $$refInitialFilePaths{$initialFilePath}{1} && 
-
 
481
            $$refInitialFilePaths{$initialFilePath}{2} )
495
	($ret = $_) =~ s{//}{/}g;
482
        {
-
 
483
            $files{$initialFilePath}{$tag} = $initialFilePath;
496
	$ret =~ s{vobs/vobs/}{vobs/}g;
484
            next;
497
	last;
485
        }
-
 
486
 
-
 
487
        push @initialFilePaths, $initialFilePath 
-
 
488
            if( $$refInitialFilePaths{$initialFilePath}{$tag} );
498
    }
489
    }
499
    while( <CMD> ){} # Get rid of broken pipe messages
-
 
500
    close( CMD );
-
 
501
 
490
 
-
 
491
    #######################
-
 
492
    # Step 2: Call cleartool dump on each of these initial filenames and get the ids
-
 
493
    # Then populate the %files array
-
 
494
    #
-
 
495
    #   In practice this will only be used when one side of the comarison
-
 
496
    #   is a directory. Should be able to use this knowledge
-
 
497
    #
-
 
498
    my @ids = getIds( $tag, @initialFilePaths );
-
 
499
#DebugDumpData ("IDS", \@ids);
-
 
500
 
-
 
501
    #
-
 
502
    #   Populate the 'files' hash
-
 
503
    #   Keys are: element number and tag
-
 
504
    #   This groups files that are the same element together
-
 
505
    #   They may be different versions of the element
-
 
506
    #
-
 
507
    #   The value is the vob extended pathname within the admin vob
-
 
508
    #   This can be used to extract the file in any view
-
 
509
    #
502
    return $ret;
510
    foreach my $datap ( @ids )
-
 
511
    {
-
 
512
        my $pname = $datap->{pname};
-
 
513
        my $element = $datap->{element};
-
 
514
        $files{$element}{$tag} = $pname;
-
 
515
    }
503
}
516
}
504
 
517
 
-
 
518
 
505
#-------------------------------------------------------------------------------
519
#-------------------------------------------------------------------------------
506
# Function        : get_newFiles
520
# Function        : files_from_view
507
#
521
#
508
# Description     : Calls 'cleartool ls -recurse' to get a list of clearcase
522
# Description     : Fills in the hash array 'initialFilePaths' with filename paths
509
#                   objects in the working directory that have been 
523
#                   If a label, uses cleartool find
510
#                   checked in to clearcase only after the label was made
524
#                   If a directory, then cleartool ls is used
511
#
525
#
512
# Inputs          : 
526
# Inputs          : $vpath          - Path to the view
-
 
527
#                   $label          - Label (not set if $directory defined)
-
 
528
#                   $tag            - File tag (1 for 'old' or 2 for 'new')
-
 
529
#                   $directory      - Directory name (not set if $label defined)
-
 
530
#                   $refInitialFilePaths - reference to hash array of filename paths
513
#
531
#
514
# Returns         : @newFiles - an array of files
532
# Returns         : Nothing
515
#
533
#
516
sub get_newFiles()
534
sub files_from_view($$$$\%)
517
{
535
{
518
    Message ("Determine clearcase file versions for: $workingDirectory");
536
    my ($vpath, $label, $tag, $directory, $refInitialFilePaths) = @_;
519
 
537
 
520
    # Step 1: get list of files that are in the directory and in clearcase
-
 
521
    my @candFiles = ();
538
    if( $label )
522
    {
539
    {
-
 
540
        #
523
	my $cmd = QuoteCommand( 'cleartool', 'ls', '-recurse', $workingDirectory);
541
        #   Ensure that the VOB is mounted
524
	open( CMD, "$cmd 2>& 1 |") or Error("can't run command: $!");
542
        #   The mount command MUST have the correct vob format
525
 
-
 
526
	while( <CMD> )
543
        #
527
	{
-
 
528
	    # Each line will be of the form (e.g.):
544
        my $vob_name = $vpath;
-
 
545
        $vob_name =~ s~^/+~~;
529
	    # ./LIB/JatsMakeConfig.pm@@/main/4         Rule: core_devl_2.73.2000.cr
546
        ClearCmd ('mount', $VOB_SEP . $vob_name);
530
 
547
 
531
	    s~[\n\r]+$~~;
-
 
532
	    next if( ! m/Rule:/ ); # We only want clearcase files - these will show with what rule
-
 
533
	                           # they are in our view via some text like m/Rule: .*/.
548
        my @initialFilePaths = getClearToolFindOutput( $vpath, $label );
534
 
549
 
535
	    (my $firstWord = $_) =~ s/^(\S+).*/$1/;
550
        foreach my $initialFilePath (@initialFilePaths)
-
 
551
        {
-
 
552
            $$refInitialFilePaths{$initialFilePath}{$tag} = 1;
-
 
553
        }
-
 
554
    }    
-
 
555
    else
-
 
556
    {
536
	    my ( $candFile, $candFileVersion) = split(/@@/, $firstWord);
557
        my $nfilesStartedWith = scalar(keys %$refInitialFilePaths);
-
 
558
        my @checkedout;
537
 
559
 
-
 
560
        #
538
	    push @candFiles, $candFile;
561
        #   Locate files in the specified directory
539
	}
-
 
540
	close( CMD );
562
        #   Use an absolute directory to simplify location of files
-
 
563
        #   Will cause output of the 'ls' to have absolute paths, which is good
541
    }
564
        #
-
 
565
        $directory = FullPath( $directory );
-
 
566
        my $cmd = QuoteCommand( 'cleartool', 'ls', '-recurse', $directory);
542
 
567
 
543
    my @newFiles = ();
568
        Message("Cleartool: searching for clearcase elements in '$directory'");
544
 
569
 
545
    # Step 2: See whether each candidate file is in the 'old' label
570
        open( CMD, "$cmd 2>& 1 |") or Error("can't run command: $!");
546
    # If not, then it is a new file that has been added since the label was created
-
 
547
    my $icandFile = 0;
571
        while( <CMD> )
548
    foreach my $candFile (@candFiles)
-
 
549
    {
572
        {
550
	$icandFile ++;
573
            # Each line will be of the form (e.g.):
-
 
574
            # ./LIB/JatsMakeConfig.pm@@/main/4         Rule: core_devl_2.73.2000.cr
551
 
575
 
552
	print "Running cleartool find on file $icandFile/" . scalar(@candFiles) . "           \r";
576
            s~[\n\r]+$~~;
553
 
577
 
-
 
578
            #
-
 
579
            #   Only want the files known to ClearCase
-
 
580
            #   These will have a 'Rule:'
-
 
581
            #
-
 
582
            #   If the user has checkedout files, then all of this will
-
 
583
            #   not work
-
 
584
            #
-
 
585
            if ( m{(.+?)\s+Rule:(.+)} )
-
 
586
            {
-
 
587
                my $files = $1;
554
	my $isPartOfLabel = 0;
588
                my $rule = $2;
-
 
589
 
-
 
590
                $files =~ tr{\\/}{/}s;  # Replace \ and / with /
-
 
591
                (my $actualFilePath = $files) =~ s~${ats}.*~~;
-
 
592
 
-
 
593
                if ( $rule =~ m/CHECKEDOUT/ )
-
 
594
                {
-
 
595
                    push @checkedout, $actualFilePath;
-
 
596
                }
555
 
597
 
556
	# This command will return no output if file is not part of label, else
598
                #
557
	# some output if it is part of the label.  This provides an simple way of
599
                #   Don't want to know about directories
558
	# determining if the file is a new file that has been added since the label was created
600
                #
559
	my $cmd = qq(cleartool find $candFile -directory -version "{lbtype($opt_new_label)}" -print);
601
                next if( -d $actualFilePath );
560
 
602
 
561
	Verbose ("Cmd: '$cmd'");
603
                #
562
	open( CMD, "$cmd 2>& 1 |") or Error("can't run command: $!");
604
                #   Save files name, with embedded version
563
	$isPartOfLabel = 1 if( <CMD> );
605
                #
564
	while( <CMD> ){} # Get rid of broken pipe messages
606
                $$refInitialFilePaths{$files}{$tag} = 1;
-
 
607
            }
-
 
608
        }
565
	close( CMD );
609
        close( CMD );
-
 
610
    
-
 
611
        Message ("There are " . (scalar(keys %$refInitialFilePaths) - $nfilesStartedWith) . 
-
 
612
             " files in directory $directory");
566
 
613
 
-
 
614
        #
-
 
615
        #   Files that are checked otu are bad news. They cannot be reproduced
567
	push @newFiles, $candFile if( ! $isPartOfLabel );
616
        #   on demand. Generate an error
-
 
617
        #
-
 
618
        if ( @checkedout )
-
 
619
        {
-
 
620
            Error ("Processed directory contains checked out files",
-
 
621
                   "Not supported by this tool. Files are:", @checkedout );
-
 
622
        }
568
    }
623
    }
569
 
-
 
570
    return @newFiles;
-
 
571
}
624
}
572
 
625
 
-
 
626
 
573
#-------------------------------------------------------------------------------
627
#-------------------------------------------------------------------------------
574
# Function        : get_prev_viewname
628
# Function        : getClearToolFindOutput
575
#
629
#
576
# Description     : Works out the view in use when CCdiff.pl is invoked.
630
# Description     : Runs cleartool find on a label
-
 
631
#                   Runs in the adbinistration view so that the paths that
-
 
632
#                   are provided are vob extended.
577
#
633
#
578
# Inputs          : 
634
# Inputs          : $vpath, $label
579
#
635
#
580
# Returns         : $prev_viewname
636
# Returns         : An array of the output lines of cleartool find
581
#
637
#
582
sub get_prev_viewname()
638
sub getClearToolFindOutput($$)
583
{
639
{
584
    my $cmd = "cleartool pwv";
640
    my ($vpath,$label) = @_;
-
 
641
    
-
 
642
    my $cmd = qq(cleartool find "$opt_drive/$opt_viewname/$vpath" -all -follow -type f -element "lbtype_sub($label)" -version "lbtype_sub($label)" -print);
585
 
643
 
586
    open( CMD, "$cmd 2>&1 |") or Error("can't run command: $!");
-
 
587
    (my $firstline = <CMD>) =~ s~[\n\r]+$~~;
-
 
588
    while( <CMD> ){} # Get rid of broken pipe messages
644
    Message ("Cleartool: searching for files with label '$label'");
589
    close( CMD );
-
 
590
 
645
 
-
 
646
    my @outputLines;
-
 
647
    
-
 
648
    # A typical line of output:
-
 
649
    #/view/administration_view/vobs/MASS_Dev_Infra/core_devl@@/main/mass_dev/1/BIN.win32/main/mass_dev/1/printenv.exe@@/main/mass_dev/1
-
 
650
    
591
    if( $firstline !~ /^Working directory view: / || $firstline =~ / NONE / )
651
    open(CMD, "$cmd 2>&1 |") || Error "Can't run command: $!";
-
 
652
    while (<CMD>)
592
    {
653
    {
-
 
654
        s~\s+$~~;           # Remove white space including newline/returns
-
 
655
        tr{\\/}{/}s;        # Replace \ and / with /
593
	Error ("Cannot determine current view name",
656
        next if( -d $_ );   # -d tests if file is a directory
594
	       "Path may not be a clearcase view");  
657
        Verbose2 ("ctf: $_");
-
 
658
        push @outputLines, $_;
595
    }
659
    }
-
 
660
    close(CMD);
596
 
661
 
597
    (my $prev_viewname = $firstline) =~ s/^Working directory view: (\S+).*/$1/;
662
    Message("There are " . scalar(@outputLines) . " files in $opt_drive/$opt_viewname/$vpath");
598
 
663
    
599
    Verbose ("Previous viewname: '$prev_viewname'");
-
 
600
    return $prev_viewname;
664
    return @outputLines;
601
}
665
}
602
 
666
 
603
 
667
 
604
#-------------------------------------------------------------------------------
668
#-------------------------------------------------------------------------------
605
# Function        : files_from_view
669
# Function        : getIds
606
#
670
#
607
# Description     : Determine the list of files/versions in a given view
671
# Description     : Calls cleartool dump to retrieve the unique identifer
-
 
672
#                   for each of a list of files.
608
#
673
#
609
# Inputs          : $vpath          - Path to the view
674
# Inputs          : $tag
610
#                   $label          - Label
-
 
611
#                   $tag            - File tag
675
#                   @initialFilePaths - a list of filenames with @@'s in them.
612
#
676
#
613
# Returns         : Nothing
677
# Returns         : An array of unique identifier strings.  This array has the same
-
 
678
#                   size as the input @initialFilePaths - each element is the unique
614
#                   Populates the %files array
679
#                   identifier for the corresponding element of that array.
615
#
680
#
616
 
-
 
617
sub files_from_view
681
sub getIds($@)
618
{
682
{
619
    my ($vpath, $label, $tag) = @_;
683
    my ($tag,@initialFilePaths) = @_;
620
    my $cutlen = length ($vpath );
684
    my @ids;
621
    Message ("Determine file versions for label: $label");
685
    my $nfilesPerCallToDump = 20;
622
 
686
 
623
    #
687
    #
624
    #   Ensure that the VOB is mounted
688
    #   Change to the directory that contains the admin view
625
    #   The mount command MUST have the correct vob format
689
    #   This will ensure that the 2nd line of the dump comamnd contains
-
 
690
    #   the vob extended pathname within that view. This will be used
-
 
691
    #   to simplify the pairing of files
626
    #
692
    #
-
 
693
    chdir ($view_path) || Error ("Did not chdir to $view_path" );
-
 
694
    
627
    my $vob = $vpath;
695
    while( @initialFilePaths )
-
 
696
    {
628
    $vob =~ s~^/+~~;
697
        #
-
 
698
        #   Limit the number of files to be processed in one call to the
-
 
699
        #   clearcase dump. Iff too many, then the command line will be long.
-
 
700
        #   If short ( ie 1 ), then the call overhead is very high
629
    $vob = $VOB_SEP . $vob;
701
        #
630
    ClearCmd ('mount',$vob);
702
        my @filesToDump = splice( @initialFilePaths, 0, $nfilesPerCallToDump);
631
 
703
 
-
 
704
        #
-
 
705
        #   The dump command provides two useful bits of information
-
 
706
        #       1) Line1: The vob extended pathname of the files as
-
 
707
        #                 seen in the current view, together with some junk
632
    my $cmd = qq(cleartool find "$opt_drive/$opt_viewname/$vpath" -all -follow -type f -element "lbtype_sub($label)" -version "lbtype_sub($label)" -print);
708
        #                 The line contains two @@ which is used by codestriker
-
 
709
        #                 Line2 would be better, but doesn't work with
-
 
710
        #                 Codestriker
-
 
711
        #
633
    Verbose ("ClearTool: $cmd");
712
        #       2) element number
-
 
713
        #           This will be the same for all versions of an element
-
 
714
        #           This allows files from two views to be correlated
-
 
715
        #
-
 
716
        #
634
 
717
 
-
 
718
        my $cmd2 = QuoteCommand( "cleartool", "dump", @filesToDump);
-
 
719
        my @newids;
-
 
720
        my %data;
-
 
721
        my $line = 0;
-
 
722
 
-
 
723
        Verbose2("Cleartool: getting unique identifiers for " . scalar(@filesToDump) . " files");
-
 
724
 
635
    open(CMD, "$cmd 2>&1 |") || Error "Can't run command: $!";
725
        open(CCI, "$cmd2 2>&1 |") || Error "Can't run command: $!";
636
    while (<CMD>)
726
        while( <CCI> )
637
    {
727
        {
-
 
728
            s~[\n\r]+$~~;
-
 
729
 
-
 
730
            #
-
 
731
            #   Blank entry signals new package
-
 
732
            #
-
 
733
            unless ( $_ )
-
 
734
            {
-
 
735
                $line = 0;
638
        Verbose( "Label$tag: $_");
736
                %data = ();
-
 
737
                next;
-
 
738
            }
639
        my $file = $_;
739
            $line++;
-
 
740
 
-
 
741
            #
-
 
742
            #   Line-1:
-
 
743
            #   Path to package as seen from current view
-
 
744
            #
640
        $file =~ s~[\n\r]+$~~;
745
            if ( $line eq 1 )
-
 
746
            {
641
        $file =~ tr{\\/}{/}s;
747
                s{\\}{/}g;
-
 
748
                s{\s+\(.+\)$}{};
642
        $files{$file}{$tag} = 1;
749
                $data{pname} = $_;
-
 
750
                Verbose2 ("ctd: pname: $_");
-
 
751
                next;
-
 
752
            }
-
 
753
 
-
 
754
            #
-
 
755
            #   Extract the element number
-
 
756
            #   This will be common for each file, independent of the version of the
-
 
757
            #   file. This allows files from different views to be correlated
-
 
758
            #   Line is of the form:
-
 
759
            #   elem=596638  branch=596639  ver num=3  line count=526
-
 
760
            #
-
 
761
            if ( m{^(elem=\d+)} )
-
 
762
            {
-
 
763
                $data{element} = $1;
-
 
764
                Verbose2 ("ctd: elem: $1");
-
 
765
                push @newids, {%data};
-
 
766
            }
-
 
767
        }
-
 
768
        close(CCI);
-
 
769
 
-
 
770
        Error("Internal error in getIds(): Only retrieved " . scalar(@newids) . 
-
 
771
              " IDs from a cleartool dump command for " . scalar(@filesToDump) . " files")
-
 
772
            if( scalar(@newids) != scalar(@filesToDump) );
-
 
773
 
-
 
774
        push @ids, @newids;
643
    }
775
    }
644
    close(CMD);
-
 
645
    Verbose2 ("ClearTool Exit Status: $?");
-
 
646
 
776
 
647
    Message ("There are " . scalar(keys %files) . " files in label $label");
777
    chdir ($FileUtils::CwdFull) || Error ("Did not chdir to $FileUtils::CwdFull") ;
-
 
778
    return @ids;
648
}
779
}
649
 
780
 
-
 
781
 
650
#-------------------------------------------------------------------------------
782
#-------------------------------------------------------------------------------
651
# Function        : ClearDiff
783
# Function        : ClearDiff
652
#
784
#
653
# Description     : Issue a cleartool command
785
# Description     : Issue a cleartool command
654
#                   Filter out many of the stupid messages
786
#                   Filter out many of the stupid messages
655
#
787
#
656
# Inputs          : Options and Command line
788
# Inputs          : Options and Command line
657
#                   Options:
-
 
658
#
789
#
659
# Returns         : Error code
790
# Returns         : header_seen         - Bool. Header has been seen
-
 
791
#                   identical           - Bool. Files are really the same
660
#
792
#
661
sub ClearDiff
793
sub ClearDiff
662
{
794
{
663
    my $header_seen = 0;
795
    my $header_seen = 0;
664
    my $identical = 0;
796
    my $identical = 0;
665
    my $cmd = QuoteCommand("cleardiff", @_);
797
    my $cmd = QuoteCommand("cleardiff", @_);
666
 
798
 
667
    Verbose ("ClearDiff: $cmd");    
799
    Verbose("ClearDiff cmd: $cmd");
668
 
-
 
669
    open(CMD, "$cmd 2>&1 |") || Error "can't run command: $!";
800
    open(CMD, "$cmd 2>&1 |") || Error "can't run command: $!";
670
 
801
 
671
    while (<CMD>)
802
    while (<CMD>)
672
    {
803
    {
-
 
804
        Verbose2("ClearDiff: $_");
673
        $header_seen = 1
805
        $header_seen = 1
674
            if ( m~^[*]{32}~ );
806
            if ( m~^[*]{32}~ );
675
        unless ( $header_seen )
807
        unless ( $header_seen )
676
        {
808
        {
677
	    $identical = 1 if ( m~^Files are identical~ );
809
            $identical = 1 if ( m~^Files are identical~ );
678
            next;
810
            next;
679
        }
811
        }
680
 
812
 
681
        #
813
        #
682
        #   Filter output from the user
814
        #   Filter output from the user
Line 691... Line 823...
691
    #   An extra line doesn't affect CS parsing, but without it any file
823
    #   An extra line doesn't affect CS parsing, but without it any file
692
    #   without a trailing \n will kill the header parsing
824
    #   without a trailing \n will kill the header parsing
693
    #
825
    #
694
    print FO "\n" if($header_seen);
826
    print FO "\n" if($header_seen);
695
    
827
    
696
    Verbose ("ClearDiff Exit Status: $?");
-
 
697
 
-
 
698
    return $header_seen, $identical;
828
    return $header_seen, $identical;
699
}
829
}
700
 
830
 
-
 
831
 
701
#-------------------------------------------------------------------------------
832
#-------------------------------------------------------------------------------
702
# Function        : ClearCmd
833
# Function        : ClearCmd
703
#
834
#
704
# Description     : Execute a cleartool command
835
# Description     : Execute a cleartool command
705
#                   Capture error messages only
836
#                   Capture error messages only
Line 711... Line 842...
711
#
842
#
712
sub ClearCmd
843
sub ClearCmd
713
{
844
{
714
    my $cmd = QuoteCommand( @_ );
845
    my $cmd = QuoteCommand( @_ );
715
    
846
    
716
    Verbose ("cleartool $cmd");
-
 
717
 
-
 
718
    @error_list = ();    
847
    @error_list = ();    
719
    open(CMD, "cleartool $cmd  2>&1 |")    || Error "can't run command: $!";
848
    open(CMD, "cleartool $cmd  2>&1 |")    || Error "can't run command: $!";
720
    while (<CMD>)
849
    while (<CMD>)
721
    {
850
    {
722
	s~[\n\r]+$~~;
851
        s~[\n\r]+$~~;
723
	Verbose2 ($_);
852
        Verbose2 ($_);
724
	push @error_list, $_ if ( m~Error:~ );
853
        push @error_list, $_ if ( m~Error:~ );
725
    }
854
    }
726
    close(CMD);
855
    close(CMD);
727
 
856
 
728
    Verbose2 ("Exit Status: $?");
857
    Verbose2 ("ClearCmd: Exit Status: $?");
-
 
858
 
729
    return ($?) / 256;
859
    return ($?) / 256;
730
}
860
}
731
 
861
 
-
 
862
 
732
#-------------------------------------------------------------------------------
863
#-------------------------------------------------------------------------------
733
# Function        : LocateLabel
864
# Function        : LocateLabel
734
#
865
#
735
# Description     : Determine the VOBs that contains the specified label
866
# Description     : Determine the VOBs that contains the specified label
736
#
867
#
Line 741... Line 872...
741
sub LocateLabel
872
sub LocateLabel
742
{
873
{
743
    my ($label) = @_;
874
    my ($label) = @_;
744
 
875
 
745
    Message ("Locate label in VOB: $label" );
876
    Message ("Locate label in VOB: $label" );
746
    Verbose ("Ensure Label is found in a VOB");
-
 
-
 
877
 
747
    my $found = 0;
878
    my $found = 0;
748
    foreach my $vob ( @ROOT_VOBS )
879
    foreach my $vob ( @ROOT_VOBS )
749
    {
880
    {
750
        $vob = $UNIX_VOB_PREFIX . $vob if ( $UNIX && $vob !~ m~^${UNIX_VOB_PREFIX}~ );
881
        $vob = $UNIX_VOB_PREFIX . $vob if ( $UNIX && $vob !~ m~^${UNIX_VOB_PREFIX}~ );
751
        (my $vob_name = $vob) =~ s~/~$VOB_SEP~g;
882
        (my $vob_name = $vob) =~ s~/~$VOB_SEP~g;
752
 
883
 
753
        Verbose2 ("Examine label $label in vob: $vob" );
884
        Verbose ("Examine label $label in vob: $vob" );
754
 
885
 
755
        my $cmd = "cleartool lstype \"lbtype:$label\@$vob_name\"";
886
        my $cmd = "cleartool lstype \"lbtype:$label\@$vob_name\"";
-
 
887
 
756
        open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
888
        open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
757
        while (<CMD>)
889
        while (<CMD>)
758
        {
890
        {
759
            #
891
            #
760
            #   Filter output from the user
892
            #   Filter output from the user
761
            #
893
            #
762
	    s~[\n\r]+$~~;
894
            s~[\n\r]+$~~;
763
            Verbose2 ("lstype: $_");
895
            Verbose2 ("lstype: $_");
764
            next if ( m~Error~ );
896
            next if ( m~Error~ );
765
            next unless ( m~label type~ );
897
            next unless ( m~label type~ );
766
            $found = $vob;
898
            $found = $vob;
-
 
899
 
767
            last;
900
            last;
768
        }
901
        }
769
	while( <CMD> ){} # Get rid of broken pipe messages
902
        while( <CMD> ){} # Get rid of broken pipe messages
770
        close(CMD);
903
        close(CMD);
771
        last if ( $found );
904
        last if ( $found );
772
    }
905
    }
773
 
906
 
774
    Error ("Label $label not found in @ROOT_VOBS")
907
    Error ("Label $label not found in @ROOT_VOBS")
Line 790... Line 923...
790
#
923
#
791
# Inputs          : $element
924
# Inputs          : $element
792
#
925
#
793
# Returns         : as described
926
# Returns         : as described
794
#
927
#
795
sub element0
928
sub element0($)
796
{
929
{
797
    my ($element) = @_;
930
    my ($element) = @_;
798
    $element =~ s{/\d+$}{/0};
931
    $element =~ s~/\d+$~/0~;
799
    return $element;
932
    return $element;
800
}
933
}
801
 
934
 
-
 
935
 
802
#-------------------------------------------------------------------------------
936
#-------------------------------------------------------------------------------
803
# Function        : StripView
937
# Function        : massage_path
804
#
938
#
805
# Description     : Strips the view nae from a file
939
# Description     : Massage the user directory, if specified, such that
-
 
940
#                   it describes the root of the vob.
806
#
941
#
-
 
942
# Inputs          : $oldLabelVob
-
 
943
#                   $oldDirectory
-
 
944
#                 : $newLabelVob
807
# Inputs          : $name       - A pathname with view name prefix
945
#                   $newDirectory
808
#
946
#
809
# Returns         : The name without the view name
947
# Returns         : Modifies $newDirectory or $oldDirectory
810
#
948
#
811
my $StripView_len;
949
#
812
sub StripView
950
sub massage_path($\$$\$)
813
{
951
{
-
 
952
    my ($oldLabelVob, $oldDirectory, $newLabelVob, $newDirectory ) = @_;
-
 
953
 
-
 
954
    #
-
 
955
    #   If the user is comparing two labels, then there is nothing to do
-
 
956
    #
814
    my ($name) = @_;
957
    return unless ( $$newDirectory || $$oldDirectory );
815
 
958
 
816
    #
959
    #
817
    #   Determine the length to strip off - once
960
    #   Figure out which ones to use
818
    #
961
    #
-
 
962
    my $vob = $$newDirectory ? $oldLabelVob : $newLabelVob;
-
 
963
    my $directory = $$newDirectory ? $newDirectory : $oldDirectory;
-
 
964
 
-
 
965
    #
-
 
966
    #   Walk up the directory until we find the vob root
-
 
967
    #   The vob has a leading /
-
 
968
    #
-
 
969
    my $dir = $$directory;
819
    unless ( $StripView_len )
970
    while ( $$directory )
820
    {
971
    {
821
        $StripView_len = length($view_path);
972
        if ( $$directory =~ m{(.*)\Q$vob\E$} )
-
 
973
        {
-
 
974
            Verbose ("Massaged path to: $$directory");
-
 
975
            return;
-
 
976
        }
-
 
977
        last unless ($$directory =~ s{/[^/]+$}{});
822
    }
978
    }
-
 
979
    Error ("Could not find vob root in user directory",
-
 
980
           "Vob Root: $vob",
-
 
981
           "Path : $dir");
823
 
982
 
824
    return substr ($name, $StripView_len );
-
 
825
}
983
}
826
 
984
 
827
 
-
 
828
#-------------------------------------------------------------------------------
985
#-------------------------------------------------------------------------------
829
#   Documentation
986
#   Documentation
830
#
987
#
831
 
988
 
832
=pod
989
=pod
Line 835... Line 992...
835
 
992
 
836
CCdiff - ClearCase Difference Report
993
CCdiff - ClearCase Difference Report
837
 
994
 
838
=head1 SYNOPSIS
995
=head1 SYNOPSIS
839
 
996
 
840
  jats CCdiff [options] [[old_label] new-label]
997
jats CCdiff [options] [old-label new-label]
841
 
998
 
842
 Options:
999
Options:
-
 
1000
 
843
    -help              - brief help message
1001
  -help              - brief help message
844
    -help -help        - Detailed help message
1002
  -help -help        - Detailed help message
845
    -man               - Full documentation
1003
  -man               - Full documentation
846
    -old=label         - Old label (optional)
1004
  -old=label         - Old label (or dir=path)
847
    -new=label         - New label (or dir=path) (mandatory)
1005
  -new=label         - New label (or dir=path)
848
    -output=file       - Output filename
1006
  -output=file       - Output filename
849
    -vob=name          - Vob for labels
1007
  -vob=name          - Vob for labels
850
    -drive=path        - Alternate vob location
1008
  -drive=path        - Alternate vob location
-
 
1009
  -[no]massage       - Massage the user path [default]
851
 
1010
 
852
=head1 OPTIONS
1011
=head1 OPTIONS
853
 
1012
 
854
=over 8
1013
=over 8
855
 
1014
 
Line 866... Line 1025...
866
Prints the manual page and exits.
1025
Prints the manual page and exits.
867
 
1026
 
868
=item B<-old=label>
1027
=item B<-old=label>
869
 
1028
 
870
This option specifies the old, or base, label for the difference report. This
1029
This option specifies the old, or base, label for the difference report. This
871
option is not required when a new package is being processed.
1030
label is mandatory for the difference report.
-
 
1031
 
-
 
1032
The old and new labels may be provided on the command line, or via named
-
 
1033
options, but not both.
-
 
1034
 
-
 
1035
The label may be of the form dir=path to force the utility to use a local
-
 
1036
view or path, within a cleacsae view.
872
 
1037
 
873
=item B<-new=label>
1038
=item B<-new=label>
874
 
1039
 
875
This option specifies the new, or current, label for the difference report. This
1040
This option specifies the new, or current, label for the difference report. This
876
label is mandatory for the difference report.
1041
label is mandatory for the difference report.
877
 
1042
 
878
The label may be of the form dir=path to force the utility to use a
-
 
879
local view or path.  You may also use '-new=current', or -new=current=path,
-
 
880
as in jats CCbc2.
-
 
881
 
-
 
882
The old and new labels may be provided on the command line, or via named
1043
The old and new labels may be provided on the command line, or via named
883
options, but not both.
1044
options, but not both.
884
 
1045
 
-
 
1046
The label may be of the form dir=path to force the utility to use a local
-
 
1047
clearcase view. The utility understands:
-
 
1048
 
-
 
1049
=over 8
-
 
1050
 
-
 
1051
=item *-new=dir=some_path  and dir=some_path
-
 
1052
 
-
 
1053
=item *-new=dir=current and dir=current
-
 
1054
 
-
 
1055
=item *-new=current and current
-
 
1056
 
-
 
1057
=back
-
 
1058
 
-
 
1059
The utiliity cannot compare two directories. It can only compare a directory
-
 
1060
against a labeled version. It will adjust the user-provided path to backtrack
-
 
1061
to the root of the view. The comparision is not limited to the specified
-
 
1062
sub-tree; it will always be the complete view.
-
 
1063
 
-
 
1064
All files within the view directory must be checked in. The utility will not
-
 
1065
process the directory if any files or directories are checkedout. The utility
-
 
1066
will ignore files that are not version controlled.
-
 
1067
 
885
=item B<-vob=name>
1068
=item B<-vob=name>
886
 
1069
 
887
This option limits the label search to the specified VOB. This option may be
1070
This option limits the label search to the specified VOB. This option may be
888
needed if the labels are to be found in multiple VOBs.
1071
needed if the labels are to be found in multiple VOBs.
889
 
1072
 
Line 898... Line 1081...
898
=item B<-drive=path>
1081
=item B<-drive=path>
899
 
1082
 
900
This option allows the user to provide an alternate location for the
1083
This option allows the user to provide an alternate location for the
901
administration vob used by the program. The default location is:
1084
administration vob used by the program. The default location is:
902
 
1085
 
-
 
1086
=item B<-[no]massage>
-
 
1087
 
-
 
1088
If the user has provided a directory path, then it will be massaged such that
-
 
1089
the comparison will include the entire VOB.
-
 
1090
 
-
 
1091
The default operation is to massage the path. This can be suppressed if required.
-
 
1092
 
903
=over 8
1093
=over 8
904
 
1094
 
905
=item * Windows o:
1095
=item * Windows o:
906
 
1096
 
907
=item * Unix /view
1097
=item * Unix /view
908
 
1098
 
909
=back
1099
=back
910
 
1100
 
-
 
1101
=back
-
 
1102
 
911
=head1 DESCRIPTION
1103
=head1 DESCRIPTION
912
 
1104
 
913
This program is the primary tool for creating 'diff' reports to be uploaded to
1105
This program is the primary tool for creating 'diff' reports to be uploaded to
914
Code Striker.
1106
Code Striker.
915
 
1107