Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

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