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