Subversion Repositories DevTools

Rev

Go to most recent revision | 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
 
19
require 5.6.1;
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
#
153
#   Ensure BeyondCompare is installed in the expected(default) location
154
#
155
Error ("Beyond Compare not found",
156
       "Looking in: $BC2" )
157
    unless ( -x $BC2 );
158
 
159
#
160
#   Ensure that the 'cleartool' program can be located
161
#
162
Verbose ("Locate clearcase utility in users path");
163
Error ("Cannot locate the 'cleartool' utility in the users PATH")
164
    unless ( LocateProgInPath('cleartool', '--All') );
165
 
166
 
167
#
168
#   Create dynamic views for the two views
169
#   Verify that the view are present
170
#
171
Message ("Constructing dynamic views");
172
my $path1 = create_dynamic_view( $opt_old_label );
173
my $path2 = create_dynamic_view( $opt_new_label );
174
 
175
Error ("Cannot locate view directory: $path1" ) unless (-d $path1);
176
Error ("Cannot locate view directory: $path2" ) unless (-d $path2);
177
 
178
#
179
#   If one of the paths is a dynamic view and the other is a local path
180
#   then attempt to locate the common directories
181
#
182
if ( $#view_tags == 0 )
183
{
184
    massage_paths();
185
}
186
 
187
 
188
Message ("Using Beyond Compare to compare two views",
189
         "Wait for BC2 to exit so that we can delete the views" );
190
System ( $BC2, $path1, $path2 );
191
exit 0;
192
 
193
#-------------------------------------------------------------------------------
194
# Function        : create_dynamic_view
195
#
196
# Description     : Create a dynamic view, based on a label
197
#
198
# Inputs          : $label          - Base label
199
#
200
# Returns         : Path to the view
201
#
202
sub create_dynamic_view
203
{
204
    my ($label) = @_;
205
 
206
    #
207
    #   Intercept and treat the special label 'current'
208
    #
209
    return create_path_view( $label )
210
        if ( $label eq 'current'  || $label =~ m~^dir=.+~ || $label =~ m~^current=.+~ );
211
 
212
    my $config = "${TMP}.config_ccview.txt";
213
 
214
    #
215
    #   Create a config spec
216
    #
217
    Verbose ("Create tmp file: $config");
218
    open (CF, ">$config" ) || Error ("Cannot create temp config spec file");
219
    print CF "element * CHECKEDOUT\n";
220
    print CF "element .../lost+found -none\n";
221
    print CF "element * $label\n";
222
    close CF;
223
 
224
    my $tag = "${USER}_${MACHINENAME}_${opt_tag}_${label}";
225
    push @view_tags, $tag;
226
 
227
    ClearCmd ( "rmview -tag $tag" );
228
    ClearCmd ( "mkview -tag $tag -stgloc -auto" );
229
    ClearCmd ( "setcs  -tag $tag $config" );
230
 
231
    unlink $config;
232
 
233
    return "$opt_drive:/$tag";
234
}
235
 
236
#-------------------------------------------------------------------------------
237
# Function        : create_path_view
238
#
239
# Description     : Not using a view, using a path
240
#                   Return the path as requested
241
#
242
# Inputs          : $label                  - with embedded path
243
#
244
# Returns         : Path to the (dummy) view
245
#
246
sub create_path_view
247
{
248
    my ($label) = @_;
249
    my $path  = '.';
250
 
251
    $path = $1
252
        if ( $label =~ m~.+=(.+)~ );
253
 
254
    Error ("Directory not found: $path" )
255
        unless ( -d $path );
256
 
257
    $path = FullPath( $path );
258
    return $path;
259
}
260
 
261
#-------------------------------------------------------------------------------
262
# Function        : massage_paths
263
#
264
# Description     : Used when one of the paths is a view and the the other
265
#                   is a local directory.
266
#
267
#                   Attempt to locate the common root
268
#
269
# Inputs          : None
270
#
271
# Returns         : Modifies $path1 and $path2
272
#
273
sub massage_paths
274
{
275
    my $view_path = "$opt_drive:/" . $view_tags[0];
276
    my $user_path = $path1;
277
    $user_path = $path2 if ( $view_path eq $path1 );
278
 
279
    #
280
    #   Split the user path into its component directory entries
281
    #   Start at the top and look for one of these in the view
282
    #
283
    my @user_path = split ('/', $user_path );
284
    my $tpath = '';
285
    foreach my $dir ( @user_path )
286
    {
287
        if ( -d "$view_path/$dir" )
288
        {
289
            #
290
            #   Common directory found
291
            #   Set the user path to the previous directory
292
            #
293
            $user_path = $tpath;
294
            if ( $view_path eq $path1   )
295
            {
296
                $path2 = $user_path;
297
            }
298
            else
299
            {
300
                $path1 = $user_path;
301
            }
302
 
303
            #
304
            #   now add the common part
305
            #
306
            $path1 .= "/$dir";
307
            $path2 .= "/$dir";
308
            Message ("Setting common root path ($dir)", $path1, $path2);
309
            last;
310
        }
311
        $tpath .= '/' if ( $tpath );
312
        $tpath .= $dir;
313
    }
314
}
315
 
316
 
317
#-------------------------------------------------------------------------------
318
# Function        : END
319
#
320
# Description     : This function will be called as the program exits
321
#                   It will also be called under error conditions
322
#                   Close down stuff we created
323
#
324
# Inputs          : 
325
#
326
# Returns         : 
327
#
328
 
329
sub END
330
{
331
    Message ("Cleaning up views - Please wait") if @view_tags;
332
    foreach my $tag ( @view_tags )
333
    {
334
#        Message ("NOT Cleaning up views");
335
        ClearCmd ( "rmview -tag $tag" );
336
    }
337
}
338
 
339
#-------------------------------------------------------------------------------
340
# Function        : ClearCmd
341
#
342
# Description     : Execute a cleartool command
343
#                   Capture error messages only
344
#
345
# Inputs          : Command to execute
346
#
347
# Returns         : Exit code
348
#                   Also the global @error_list
349
#
350
sub ClearCmd
351
{
352
    my( $cmd ) = @_;
353
    Verbose2 "cleartool $cmd";
354
 
355
        @error_list = ();
356
        open(CMD, "cleartool $cmd  2>&1 |")    || Error "can't run command: $!";
357
        while (<CMD>)
358
        {
359
            chomp;
360
            Verbose ($_);
361
            push @error_list, $_ if ( m~Error:~ );
362
        }
363
        close(CMD);
364
 
365
    Verbose2 "Exit Status: $?";
366
    return $? / 256;
367
}
368
 
369
#-------------------------------------------------------------------------------
370
#   Documentation
371
#
372
 
373
=pod
374
 
375
=head1 NAME
376
 
377
CCbc2 - ClearCase BeyondCompare Difference
378
 
379
=head1 SYNOPSIS
380
 
381
  jats CCbc2 [options] [[old_label] new-label]
382
 
383
 Options:
384
    -help              - brief help message
385
    -help -help        - Detailed help message
386
    -man               - Full documentation
387
    -old=label         - Old label (or dir=path)
388
    -new=label         - New label (or dir=path)
389
    -drive=path        - Alternate vob location
390
 
391
=head1 OPTIONS
392
 
393
=over 8
394
 
395
=item B<-help>
396
 
397
Print a brief help message and exits.
398
 
399
=item B<-help -help>
400
 
401
Print a detailed help message with an explanation for each option.
402
 
403
=item B<-man>
404
 
405
Prints the manual page and exits.
406
 
407
=item B<-old=label>
408
 
409
This option specifies the old, or base, label for the difference report. This
410
label is mandatory for the difference report.
411
 
412
The old and new labels may be provided on the command line, or via named
413
options, but not both.
414
 
415
The label may be of the form dir=path to force the utility to use a local
416
view or path.
417
 
418
=item B<-new=label>
419
 
420
This option specifies the new, or current, label for the difference report. This
421
label is mandatory for the difference report.
422
 
423
The old and new labels may be provided on the command line, or via named
424
options, but not both.
425
 
426
The label may be of the form dir=path to force the utility to use a local
427
view or path.
428
 
429
=item B<-drive=path>
430
 
431
This option allows the user to provide an alternate location for the
432
administration vob used by the program. The default location is:
433
 
434
=over 8
435
 
436
=item * Windows o:
437
 
438
=item * Unix /view
439
 
440
=back
441
 
442
=back
443
 
444
=head1 DESCRIPTION
445
 
446
This program simplifies the process of perform a code review between two ClearCase
447
labels by:
448
 
449
=over 8
450
 
451
=item # Creating a visual difference between two labels
452
 
453
=item # Creating a visual difference between a label and a directory
454
 
455
=item # Creating a visual difference between two directories.
456
 
457
=back
458
 
459
The program will:
460
 
461
=over 8
462
 
463
=item * Create two dynamic views based on the provided label
464
 
465
=item * Invoke BeyondCompare to allow visual inspection of the two software versions.
466
 
467
=item * Delete the views when the comparison is complete.
468
 
469
=back
470
 
471
If one of the labels is of the form:
472
 
473
=over 8
474
 
475
=item * current
476
 
477
=item * current=path
478
 
479
=item * dir=path
480
 
481
=back
482
 
483
Then the label will be treated as a directory and will be used for one side
484
of the comparison.
485
 
486
The program uses a global administration view for the purposes of determining
487
file versions.
488
 
489
Two dynamic views will be created. These should be deleted by this program,
490
but may remain if the command line program is terminated.
491
 
492
The user must have relevant VOBs mounted on there machine for this utility to
493
operate correctly.
494
 
495
=cut
496