Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
229 dpurdie 1
########################################################################
263 dpurdie 2
# Copyright (C) 2008 ERG Limited, All rights reserved
229 dpurdie 3
#
263 dpurdie 4
# Module name   : CCbc2.pl
5
# Module type   : JATS Utility
6
# Compiler(s)   : Perl
7
# Environment(s): JATS
229 dpurdie 8
#
9
# Description   : Create two dynamic views and invoke Beyond Compare
10
#                 to view the differences.
11
#
12
#                 or
13
#
14
#                 Create one dynamic view and use the directory
15
#
16
#......................................................................#
17
 
255 dpurdie 18
require 5.006_001;
229 dpurdie 19
use strict;
20
use warnings;
21
use JatsError;
22
use JatsSystem;
23
use FileUtils;
24
 
25
use Pod::Usage;                             # required for help support
26
use Getopt::Long;
27
use Cwd;
28
use Sys::Hostname;                          # For hostname
29
 
30
my $VERSION = "1.1.0";                      # Update this
31
 
32
#
33
#   Options
34
#
35
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
36
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
37
my $opt_help = 0;
38
my $opt_manual = 0;
39
my $opt_drive = 'o';
40
my $opt_tag = 'dynamic';
41
my $opt_new_label;
42
my $opt_old_label;
43
 
44
#
45
#   Globals - Provided by the JATS environment
46
#
47
my $USER            = $ENV{'USER'};
48
my $UNIX            = $ENV{'GBE_UNIX'};
49
my $TMP             = $UNIX ? "/tmp" : $ENV{'TMP'};
50
 
51
#
52
#   Globals
53
#
54
my $MACHINENAME;
55
my @error_list;                             # ClearCmd detected errors
56
my $BC2             = 'c:/Program Files/Beyond Compare 2/BC2.exe';
57
my @view_tags;
58
 
59
 
60
#-------------------------------------------------------------------------------
61
# Function        : Mainline Entry Point
62
#
63
# Description     :
64
#
65
# Inputs          :
66
#
67
 
68
#
69
#   Parse the user options
70
#
71
my $result = GetOptions (
72
                "help+"         => \$opt_help,              # flag, multiple use allowed
73
                "manual"        => \$opt_manual,            # flag, multiple use allowed
74
                "verbose+"      => \$opt_verbose,           # flag, multiple use allowed
75
                "new=s"         => \$opt_new_label,         # String
76
                "old=s"         => \$opt_old_label,         # String
77
                "drive=s"       => \$opt_drive,             # String
78
                );
79
 
80
                #
81
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
82
                #
83
 
84
#
85
#   Process help and manual options
86
#
87
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result );
88
pod2usage(-verbose => 1)  if ($opt_help == 2 );
89
pod2usage(-verbose => 2)  if ($opt_manual || ($opt_help > 2));
90
 
91
InitFileUtils();
92
 
93
#
94
#   Configure the error reporting process now that we have the user options
95
#
96
ErrorConfig( 'name'    => 'CC_BC2',
97
             'verbose' => $opt_verbose );
98
 
99
#
100
#   Only for windows
101
#
102
Error ("This program only works under Windows")
103
    if ( $UNIX );
104
 
105
#
106
#   Validate user options
107
#
108
#   Be nice to the user
109
#   If we have two options and no labels, then assign them
110
#
111
if ( ! $opt_new_label && ! $opt_old_label )
112
{
113
    Error ("Must provide two labels on command line unless they are provided via -old and -new options")
114
         if ( $#ARGV < 1 );
115
 
116
    $opt_old_label = shift @ARGV;
117
    $opt_new_label = shift @ARGV;
118
}
119
 
120
Error ("Need two labels on the command line, or via options")
121
    unless ( $opt_old_label && $opt_new_label );
122
 
123
Error ("Too many command line arguments" )
124
    unless ( $#ARGV < 0 );
125
 
126
#
127
#   Determine the machine type
128
#
129
Verbose ("Machine Type: UNIX=$UNIX");
130
 
131
#
132
#   Extract parameters that will be used to create a view that is
133
#   unique. Will use hostname and user name
134
#
135
$MACHINENAME = hostname;
136
Error ("Machine Name not determined")
137
    unless ( $MACHINENAME );
138
chomp( $MACHINENAME );
139
 
140
Error ("USER name not determined" )
141
    unless ( $USER );
142
 
143
#
144
#   Need a TMP working directory
145
#   Used to create config files
146
#
147
Error ("TMP not found or not a directory")
148
    unless ( $TMP && -d $TMP );
149
$TMP = "$TMP/$$";
150
 
151
#
231 dpurdie 152
#   Determine the path to BC2.EXE
153
#   It maynot be installed inthe default place
229 dpurdie 154
#
231 dpurdie 155
if ( ! -x $BC2 )
156
{
157
    $BC2 = GetBc2ExePath();
158
}
229 dpurdie 159
 
160
#
161
#   Ensure that the 'cleartool' program can be located
162
#
163
Verbose ("Locate clearcase utility in users path");
164
Error ("Cannot locate the 'cleartool' utility in the users PATH")
165
    unless ( LocateProgInPath('cleartool', '--All') );
166
 
167
 
168
#
169
#   Create dynamic views for the two views
170
#   Verify that the view are present
171
#
172
Message ("Constructing dynamic views");
173
my $path1 = create_dynamic_view( $opt_old_label );
174
my $path2 = create_dynamic_view( $opt_new_label );
175
 
176
Error ("Cannot locate view directory: $path1" ) unless (-d $path1);
177
Error ("Cannot locate view directory: $path2" ) unless (-d $path2);
178
 
179
#
180
#   If one of the paths is a dynamic view and the other is a local path
181
#   then attempt to locate the common directories
182
#
183
if ( $#view_tags == 0 )
184
{
185
    massage_paths();
186
}
187
 
188
 
189
Message ("Using Beyond Compare to compare two views",
190
         "Wait for BC2 to exit so that we can delete the views" );
191
System ( $BC2, $path1, $path2 );
192
exit 0;
193
 
194
#-------------------------------------------------------------------------------
195
# Function        : create_dynamic_view
196
#
197
# Description     : Create a dynamic view, based on a label
198
#
199
# Inputs          : $label          - Base label
200
#
201
# Returns         : Path to the view
202
#
203
sub create_dynamic_view
204
{
205
    my ($label) = @_;
206
 
207
    #
208
    #   Intercept and treat the special label 'current'
209
    #
210
    return create_path_view( $label )
211
        if ( $label eq 'current'  || $label =~ m~^dir=.+~ || $label =~ m~^current=.+~ );
212
 
213
    my $config = "${TMP}.config_ccview.txt";
214
 
215
    #
216
    #   Create a config spec
217
    #
218
    Verbose ("Create tmp file: $config");
261 dpurdie 219
    FileCreate ( $config,
220
                 "element * CHECKEDOUT",
221
                 "element .../lost+found -none",
222
                 "element * $label",
223
                );
229 dpurdie 224
 
225
    my $tag = "${USER}_${MACHINENAME}_${opt_tag}_${label}";
226
    push @view_tags, $tag;
227
 
228
    ClearCmd ( "rmview -tag $tag" );
229
    ClearCmd ( "mkview -tag $tag -stgloc -auto" );
230
    ClearCmd ( "setcs  -tag $tag $config" );
231
 
232
    unlink $config;
233
 
234
    return "$opt_drive:/$tag";
235
}
236
 
237
#-------------------------------------------------------------------------------
238
# Function        : create_path_view
239
#
240
# Description     : Not using a view, using a path
241
#                   Return the path as requested
242
#
243
# Inputs          : $label                  - with embedded path
244
#
245
# Returns         : Path to the (dummy) view
246
#
247
sub create_path_view
248
{
249
    my ($label) = @_;
250
    my $path  = '.';
251
 
252
    $path = $1
253
        if ( $label =~ m~.+=(.+)~ );
254
 
255
    Error ("Directory not found: $path" )
256
        unless ( -d $path );
257
 
258
    $path = FullPath( $path );
259
    return $path;
260
}
261
 
262
#-------------------------------------------------------------------------------
263
# Function        : massage_paths
264
#
265
# Description     : Used when one of the paths is a view and the the other
266
#                   is a local directory.
267
#
268
#                   Attempt to locate the common root
269
#
270
# Inputs          : None
271
#
272
# Returns         : Modifies $path1 and $path2
273
#
274
sub massage_paths
275
{
276
    my $view_path = "$opt_drive:/" . $view_tags[0];
277
    my $user_path = $path1;
278
    $user_path = $path2 if ( $view_path eq $path1 );
279
 
280
    #
281
    #   Split the user path into its component directory entries
282
    #   Start at the top and look for one of these in the view
283
    #
284
    my @user_path = split ('/', $user_path );
285
    my $tpath = '';
286
    foreach my $dir ( @user_path )
287
    {
288
        if ( -d "$view_path/$dir" )
289
        {
290
            #
291
            #   Common directory found
292
            #   Set the user path to the previous directory
293
            #
294
            $user_path = $tpath;
295
            if ( $view_path eq $path1   )
296
            {
297
                $path2 = $user_path;
298
            }
299
            else
300
            {
301
                $path1 = $user_path;
302
            }
303
 
304
            #
305
            #   now add the common part
306
            #
307
            $path1 .= "/$dir";
308
            $path2 .= "/$dir";
309
            Message ("Setting common root path ($dir)", $path1, $path2);
310
            last;
311
        }
312
        $tpath .= '/' if ( $tpath );
313
        $tpath .= $dir;
314
    }
315
}
316
 
231 dpurdie 317
#-------------------------------------------------------------------------------
318
# Function        : GetBc2ExePath
319
#
320
# Description     : Determine the path to the BeyondCompare executable
321
#                   by looking in the Windows Registry
322
#
323
# Inputs          : None
324
#
325
# Returns         : Path to an executable
326
#
229 dpurdie 327
 
231 dpurdie 328
sub GetBc2ExePath
329
{
330
    eval "require Win32::TieRegistry"
331
        or Error ("Win32::TieRegistry not available");
332
 
333
    my $userKey= Win32::TieRegistry->new("CUser")
334
        or  Error( "Can't access HKEY_CURRENT_USER key: $^E" );
335
 
336
    my $bc2Key= $userKey->Open( "Software/Scooter Software/Beyond Compare", {Delimiter=>"/"} )
337
        or  Error "Can't access BC2 Keys: $^E";
338
 
339
    my $bc2Data = $bc2Key->GetValue( 'ExePath' )
340
        or Error( "Cannot locate BeyondCompare in Windows Registry");
341
 
342
    Error ("BeyondCompare program not found", "Prog: $bc2Data") unless ( -x $bc2Data );
343
    return $bc2Data;
344
}
345
 
229 dpurdie 346
#-------------------------------------------------------------------------------
347
# Function        : END
348
#
349
# Description     : This function will be called as the program exits
350
#                   It will also be called under error conditions
351
#                   Close down stuff we created
352
#
353
# Inputs          : 
354
#
355
# Returns         : 
356
#
357
 
358
sub END
359
{
360
    Message ("Cleaning up views - Please wait") if @view_tags;
361
    foreach my $tag ( @view_tags )
362
    {
363
#        Message ("NOT Cleaning up views");
364
        ClearCmd ( "rmview -tag $tag" );
365
    }
366
}
367
 
368
#-------------------------------------------------------------------------------
369
# Function        : ClearCmd
370
#
371
# Description     : Execute a cleartool command
372
#                   Capture error messages only
373
#
374
# Inputs          : Command to execute
375
#
376
# Returns         : Exit code
377
#                   Also the global @error_list
378
#
379
sub ClearCmd
380
{
381
    my( $cmd ) = @_;
382
    Verbose2 "cleartool $cmd";
383
 
384
        @error_list = ();
385
        open(CMD, "cleartool $cmd  2>&1 |")    || Error "can't run command: $!";
386
        while (<CMD>)
387
        {
388
            chomp;
389
            Verbose ($_);
390
            push @error_list, $_ if ( m~Error:~ );
391
        }
392
        close(CMD);
393
 
394
    Verbose2 "Exit Status: $?";
395
    return $? / 256;
396
}
397
 
398
#-------------------------------------------------------------------------------
399
#   Documentation
400
#
401
 
402
=pod
403
 
404
=head1 NAME
405
 
406
CCbc2 - ClearCase BeyondCompare Difference
407
 
408
=head1 SYNOPSIS
409
 
231 dpurdie 410
  jats CCbc2 [options] [old_label new_label]
229 dpurdie 411
 
412
 Options:
413
    -help              - brief help message
414
    -help -help        - Detailed help message
415
    -man               - Full documentation
416
    -old=label         - Old label (or dir=path)
417
    -new=label         - New label (or dir=path)
418
    -drive=path        - Alternate vob location
419
 
420
=head1 OPTIONS
421
 
422
=over 8
423
 
424
=item B<-help>
425
 
426
Print a brief help message and exits.
427
 
428
=item B<-help -help>
429
 
430
Print a detailed help message with an explanation for each option.
431
 
432
=item B<-man>
433
 
434
Prints the manual page and exits.
435
 
436
=item B<-old=label>
437
 
438
This option specifies the old, or base, label for the difference report. This
439
label is mandatory for the difference report.
440
 
441
The old and new labels may be provided on the command line, or via named
442
options, but not both.
443
 
444
The label may be of the form dir=path to force the utility to use a local
445
view or path.
446
 
447
=item B<-new=label>
448
 
449
This option specifies the new, or current, label for the difference report. This
450
label is mandatory for the difference report.
451
 
452
The old and new labels may be provided on the command line, or via named
453
options, but not both.
454
 
455
The label may be of the form dir=path to force the utility to use a local
456
view or path.
457
 
458
=item B<-drive=path>
459
 
460
This option allows the user to provide an alternate location for the
461
administration vob used by the program. The default location is:
462
 
463
=over 8
464
 
465
=item * Windows o:
466
 
467
=item * Unix /view
468
 
469
=back
470
 
471
=back
472
 
473
=head1 DESCRIPTION
474
 
475
This program simplifies the process of perform a code review between two ClearCase
476
labels by:
477
 
478
=over 8
479
 
480
=item # Creating a visual difference between two labels
481
 
482
=item # Creating a visual difference between a label and a directory
483
 
484
=item # Creating a visual difference between two directories.
485
 
486
=back
487
 
488
The program will:
489
 
490
=over 8
491
 
492
=item * Create two dynamic views based on the provided label
493
 
494
=item * Invoke BeyondCompare to allow visual inspection of the two software versions.
495
 
496
=item * Delete the views when the comparison is complete.
497
 
498
=back
499
 
500
If one of the labels is of the form:
501
 
502
=over 8
503
 
504
=item * current
505
 
506
=item * current=path
507
 
508
=item * dir=path
509
 
510
=back
511
 
512
Then the label will be treated as a directory and will be used for one side
513
of the comparison.
514
 
515
The program uses a global administration view for the purposes of determining
516
file versions.
517
 
518
Two dynamic views will be created. These should be deleted by this program,
519
but may remain if the command line program is terminated.
520
 
521
The user must have relevant VOBs mounted on there machine for this utility to
522
operate correctly.
523
 
524
=cut
525