Subversion Repositories DevTools

Rev

Rev 361 | Details | Compare with Previous | 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
 
361 dpurdie 401
=for htmltoc    GENERAL::ClearCase::
402
 
229 dpurdie 403
=head1 NAME
404
 
405
CCbc2 - ClearCase BeyondCompare Difference
406
 
407
=head1 SYNOPSIS
408
 
231 dpurdie 409
  jats CCbc2 [options] [old_label new_label]
229 dpurdie 410
 
411
 Options:
412
    -help              - brief help message
413
    -help -help        - Detailed help message
414
    -man               - Full documentation
415
    -old=label         - Old label (or dir=path)
416
    -new=label         - New label (or dir=path)
417
    -drive=path        - Alternate vob location
418
 
419
=head1 OPTIONS
420
 
421
=over 8
422
 
423
=item B<-help>
424
 
425
Print a brief help message and exits.
426
 
427
=item B<-help -help>
428
 
429
Print a detailed help message with an explanation for each option.
430
 
431
=item B<-man>
432
 
433
Prints the manual page and exits.
434
 
435
=item B<-old=label>
436
 
437
This option specifies the old, or base, label for the difference report. This
438
label is mandatory for the difference report.
439
 
440
The old and new labels may be provided on the command line, or via named
441
options, but not both.
442
 
443
The label may be of the form dir=path to force the utility to use a local
444
view or path.
445
 
446
=item B<-new=label>
447
 
448
This option specifies the new, or current, label for the difference report. This
449
label is mandatory for the difference report.
450
 
451
The old and new labels may be provided on the command line, or via named
452
options, but not both.
453
 
454
The label may be of the form dir=path to force the utility to use a local
455
view or path.
456
 
457
=item B<-drive=path>
458
 
459
This option allows the user to provide an alternate location for the
460
administration vob used by the program. The default location is:
461
 
462
=over 8
463
 
361 dpurdie 464
=item *
229 dpurdie 465
 
361 dpurdie 466
Windows o:
229 dpurdie 467
 
361 dpurdie 468
=item *
469
 
470
Unix /view
471
 
229 dpurdie 472
=back
473
 
474
=back
475
 
476
=head1 DESCRIPTION
477
 
478
This program simplifies the process of perform a code review between two ClearCase
479
labels by:
480
 
481
=over 8
482
 
361 dpurdie 483
=item *
229 dpurdie 484
 
361 dpurdie 485
Creating a visual difference between two labels
229 dpurdie 486
 
361 dpurdie 487
=item *
229 dpurdie 488
 
361 dpurdie 489
Creating a visual difference between a label and a directory
490
 
491
=item *
492
 
493
Creating a visual difference between two directories.
494
 
229 dpurdie 495
=back
496
 
497
The program will:
498
 
499
=over 8
500
 
361 dpurdie 501
=item *
229 dpurdie 502
 
361 dpurdie 503
Create two dynamic views based on the provided label
229 dpurdie 504
 
361 dpurdie 505
=item *
229 dpurdie 506
 
361 dpurdie 507
Invoke BeyondCompare to allow visual inspection of the two software versions.
508
 
509
=item *
510
 
511
Delete the views when the comparison is complete.
512
 
229 dpurdie 513
=back
514
 
515
If one of the labels is of the form:
516
 
517
=over 8
518
 
361 dpurdie 519
=item *
229 dpurdie 520
 
361 dpurdie 521
current
229 dpurdie 522
 
361 dpurdie 523
=item *
229 dpurdie 524
 
361 dpurdie 525
current=path
526
 
527
=item *
528
 
529
dir=path
530
 
229 dpurdie 531
=back
532
 
533
Then the label will be treated as a directory and will be used for one side
534
of the comparison.
535
 
536
The program uses a global administration view for the purposes of determining
537
file versions.
538
 
539
Two dynamic views will be created. These should be deleted by this program,
540
but may remain if the command line program is terminated.
541
 
542
The user must have relevant VOBs mounted on there machine for this utility to
543
operate correctly.
544
 
545
=cut
546