| 227 |
dpurdie |
1 |
#! perl
|
|
|
2 |
########################################################################
|
|
|
3 |
# Copyright ( C ) 2004 ERG Limited, All rights reserved
|
|
|
4 |
#
|
|
|
5 |
# Module name : jats.sh
|
|
|
6 |
# Module type : Makefile system
|
|
|
7 |
# Compiler(s) : n/a
|
|
|
8 |
# Environment(s): jats
|
|
|
9 |
#
|
|
|
10 |
# Description : Save a rewritten build.pl file back into version control
|
|
|
11 |
# This script is a dedicated part of the auto build system
|
|
|
12 |
#
|
|
|
13 |
# Usage:
|
|
|
14 |
#
|
|
|
15 |
# Version Who Date Description
|
|
|
16 |
#
|
|
|
17 |
#......................................................................#
|
|
|
18 |
|
| 255 |
dpurdie |
19 |
require 5.006_001;
|
| 227 |
dpurdie |
20 |
use strict;
|
|
|
21 |
use warnings;
|
|
|
22 |
use JatsError;
|
|
|
23 |
use Getopt::Long;
|
|
|
24 |
use Pod::Usage; # required for help support
|
|
|
25 |
|
|
|
26 |
################################################################################
|
|
|
27 |
# Option variables
|
|
|
28 |
#
|
|
|
29 |
|
|
|
30 |
my $VERSION = "1.2.0"; # Update this
|
|
|
31 |
my $opt_verbose = 0;
|
|
|
32 |
my $opt_infile = "auto.pl";
|
|
|
33 |
my $opt_ofile = "build.pl";
|
|
|
34 |
my $opt_help = 0;
|
|
|
35 |
my $opt_manual;
|
|
|
36 |
my $opt_label;
|
|
|
37 |
my $opt_branch_default = "AutoBuilder";
|
|
|
38 |
my $opt_branch;
|
|
|
39 |
my $opt_newbranch;
|
|
|
40 |
|
|
|
41 |
#
|
|
|
42 |
# Globals
|
|
|
43 |
#
|
|
|
44 |
my @error_list;
|
|
|
45 |
my $last_result;
|
| 241 |
dpurdie |
46 |
my @last_results;
|
| 227 |
dpurdie |
47 |
|
|
|
48 |
my $result = GetOptions (
|
|
|
49 |
"help+" => \$opt_help, # flag, multiple use allowed
|
|
|
50 |
"manual" => \$opt_manual, # flag
|
|
|
51 |
"verbose+" => \$opt_verbose, # flag
|
|
|
52 |
"outfile=s" => \$opt_ofile, # string
|
|
|
53 |
"infile=s" => \$opt_infile, # string
|
|
|
54 |
"label=s" => \$opt_label, # string
|
|
|
55 |
"branch=s" => \$opt_branch, # string
|
|
|
56 |
"newbranch" => \$opt_newbranch, # string
|
|
|
57 |
);
|
|
|
58 |
|
|
|
59 |
#
|
|
|
60 |
# Process help and manual options
|
|
|
61 |
#
|
|
|
62 |
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
|
|
|
63 |
pod2usage(-verbose => 1) if ($opt_help == 2 );
|
|
|
64 |
pod2usage(-verbose => 2) if ($opt_manual || ($opt_help > 2));
|
|
|
65 |
|
|
|
66 |
#
|
|
|
67 |
# Configure the error reporting process now that we have the user options
|
|
|
68 |
#
|
|
|
69 |
ErrorConfig( 'name' =>'ASAVE',
|
|
|
70 |
'verbose' => $opt_verbose,
|
|
|
71 |
'on_exit' => \&display_error_list
|
|
|
72 |
);
|
|
|
73 |
|
|
|
74 |
Error ("No label")
|
|
|
75 |
unless ( $opt_label );
|
|
|
76 |
|
|
|
77 |
Error ("Input and output file are the same: $opt_infile" )
|
|
|
78 |
if ( $opt_infile eq $opt_ofile );
|
|
|
79 |
|
|
|
80 |
Error ("Input file not found: $opt_infile" )
|
|
|
81 |
unless ( -f $opt_infile );
|
|
|
82 |
|
|
|
83 |
Error ("Output file not found: $opt_ofile" )
|
|
|
84 |
unless ( -f $opt_ofile );
|
|
|
85 |
|
|
|
86 |
Error ("Must provide a branch when usng newbranch option")
|
|
|
87 |
if ( $opt_newbranch && ! $opt_branch );
|
|
|
88 |
|
|
|
89 |
$opt_branch = $opt_branch_default
|
|
|
90 |
unless ( $opt_branch );
|
|
|
91 |
|
|
|
92 |
#
|
|
|
93 |
# Determine the name of the Branch to be used
|
|
|
94 |
# This is based on the branch that the file is already on as ClearCase does
|
|
|
95 |
# not allow multiple instances of a branch on different sub-branches
|
|
|
96 |
#
|
|
|
97 |
ClearCmd ("describe -fmt \"%n\" \"$opt_ofile\"");
|
|
|
98 |
Error ("Program Terminated") if ( @error_list );
|
|
|
99 |
Error ("File may not be a VOB object: $opt_ofile" ) unless ( $last_result );
|
|
|
100 |
my $full_name = $last_result;
|
|
|
101 |
|
|
|
102 |
$last_result =~ m~(.*)/([^/]+)$~;
|
|
|
103 |
my $full_path = $1;
|
|
|
104 |
|
|
|
105 |
$last_result =~ m~(.*)/([^/]+)/([^/]+)~;
|
|
|
106 |
my $current_branch = $2;
|
|
|
107 |
|
|
|
108 |
$last_result =~ m~@@(.*)/([^/]+)~;
|
|
|
109 |
my $full_branch = $1;
|
|
|
110 |
my $target_branch = $full_branch;
|
|
|
111 |
my $branch_point = "";
|
|
|
112 |
|
|
|
113 |
Error ("Cannot determine full pathname of the file: $full_name") unless ( $full_path );
|
|
|
114 |
|
|
|
115 |
Verbose2 ("FullName : $full_name" );
|
|
|
116 |
Verbose2 ("FullPath : $full_path" );
|
|
|
117 |
Verbose2 ("Branch : $current_branch" );
|
|
|
118 |
Verbose2 ("Userb : $opt_branch" );
|
|
|
119 |
Verbose2 ("FullBranch : $full_branch" );
|
|
|
120 |
#
|
|
|
121 |
#
|
|
|
122 |
# Determine the branch that the file is on
|
|
|
123 |
# If it is not on the desired branch then we will need to create the branch
|
|
|
124 |
#
|
|
|
125 |
# Ensure that the required branch exists in the current VOB
|
|
|
126 |
# Need to handle some legacy branches that were created with the name AutoBuilder
|
|
|
127 |
# by not creating AutoBuild/AutoBuilder.AutoBuilder branches but retaining the
|
|
|
128 |
# existing AutoBuilder branch.
|
|
|
129 |
#
|
|
|
130 |
if ( $opt_newbranch )
|
|
|
131 |
{
|
|
|
132 |
#
|
|
|
133 |
# User has asked for a new branch
|
|
|
134 |
# Place the file on /main/xxxxx
|
|
|
135 |
#
|
|
|
136 |
$branch_point = "-version /main/0";
|
|
|
137 |
$target_branch = "/main/$opt_branch";
|
|
|
138 |
|
|
|
139 |
}
|
|
|
140 |
elsif ( $current_branch =~ m/^$opt_branch/ )
|
|
|
141 |
{
|
|
|
142 |
#
|
|
|
143 |
# Current branch has the same name ( prefix) as the desired branch
|
|
|
144 |
# Use it
|
|
|
145 |
#
|
|
|
146 |
$opt_branch = $current_branch;
|
|
|
147 |
}
|
|
|
148 |
else
|
|
|
149 |
{
|
|
|
150 |
#
|
|
|
151 |
# Current branch has a different name
|
|
|
152 |
# Construct new branch name
|
|
|
153 |
#
|
|
|
154 |
$opt_branch = "$opt_branch.$current_branch";
|
|
|
155 |
$target_branch .= "/$opt_branch";
|
|
|
156 |
}
|
|
|
157 |
|
|
|
158 |
Verbose2 ("TargetBranch : $target_branch" );
|
|
|
159 |
Verbose2 ("BranchPoint : $branch_point" );
|
|
|
160 |
|
|
|
161 |
#
|
|
|
162 |
# Ensure that the specified label exists
|
|
|
163 |
# Determine if it is locked too
|
|
|
164 |
#
|
|
|
165 |
ClearCmd ("describe -fmt %[locked]p lbtype:$opt_label" );
|
|
|
166 |
Error ("Program Terminated") if ( @error_list );
|
|
|
167 |
my $was_locked = 1 unless ( $last_result =~ m~unlocked~ );
|
|
|
168 |
|
|
|
169 |
#
|
|
|
170 |
# Create the desired branch if it does not already exist
|
|
|
171 |
# Dtected locked element and unlock it
|
|
|
172 |
#
|
|
|
173 |
ClearCmd ("lstype -short brtype:$opt_branch" );
|
|
|
174 |
if ( $last_result =~ m~\(locked\)~ )
|
|
|
175 |
{
|
|
|
176 |
ClearCmd( "unlock -c \"Unlocked by JATS ASAVE\" brtype:$opt_branch" );
|
|
|
177 |
}
|
|
|
178 |
elsif ( $last_result ne $opt_branch )
|
|
|
179 |
{
|
|
|
180 |
ClearCmd ("mkbrtype -c \"Contains saved versions of $opt_ofile files created by the AutoBuild system\" $opt_branch" );
|
|
|
181 |
Error ("Program Terminated") if ( @error_list );
|
|
|
182 |
}
|
|
|
183 |
|
|
|
184 |
#
|
|
|
185 |
# Ensure that the file is not locked
|
|
|
186 |
# Unlock the file - can't do anything to a 'locked' file
|
|
|
187 |
#
|
|
|
188 |
ClearCmd ("lslock -short $opt_ofile" );
|
|
|
189 |
if ( $last_result )
|
|
|
190 |
{
|
|
|
191 |
ClearCmd( "unlock -c \"Unlocked by JATS ASAVE\" $opt_ofile" );
|
|
|
192 |
}
|
|
|
193 |
|
|
|
194 |
if ( $current_branch ne $opt_branch )
|
|
|
195 |
{
|
|
|
196 |
#
|
|
|
197 |
# Need to create the initial branch point, but only if one does not already
|
|
|
198 |
# exists
|
|
|
199 |
#
|
|
|
200 |
Verbose ("Does a branch exist" );
|
|
|
201 |
if ( ClearCmd( "find $opt_ofile -version \"brtype($opt_branch)\" -print" ) )
|
|
|
202 |
{
|
|
|
203 |
Error ("Internal error. Cleartool find should not fail");
|
|
|
204 |
}
|
|
|
205 |
if ( $last_result )
|
|
|
206 |
{
|
|
|
207 |
#
|
|
|
208 |
# A branch already exists - and there can only be one
|
|
|
209 |
#
|
|
|
210 |
$last_result =~ m~@@(.*)/([^/]+)~;
|
|
|
211 |
$target_branch = $1;
|
|
|
212 |
Error ("Cannot determine full branch path: $last_result") unless ( $target_branch );
|
|
|
213 |
Verbose2 ("Target Branch: $target_branch" );
|
|
|
214 |
}
|
|
|
215 |
else
|
|
|
216 |
{
|
|
|
217 |
Verbose ("Create the initial branch point" );
|
|
|
218 |
ClearCmd( "mkbranch -nco -nc -nwarn $branch_point $opt_branch $opt_ofile" );
|
|
|
219 |
}
|
|
|
220 |
}
|
|
|
221 |
|
|
|
222 |
#
|
|
|
223 |
# Ensure that the branch with the target auto builder file on is not locked
|
|
|
224 |
#
|
|
|
225 |
ClearCmd ("lslock -short \"$opt_ofile\@\@$target_branch\"" );
|
|
|
226 |
if ( $last_result )
|
|
|
227 |
{
|
|
|
228 |
ClearCmd( "unlock -c \"Unlocked by JATS ASAVE\" \"$opt_ofile\@\@$target_branch\"" );
|
|
|
229 |
}
|
|
|
230 |
|
|
|
231 |
|
|
|
232 |
#
|
|
|
233 |
# Look for a checked out file on the target branch
|
|
|
234 |
# It may be reserved - this will kill the process, so unreserve it
|
|
|
235 |
#
|
|
|
236 |
if ( ClearCmd( "lsco -long -brtype $opt_branch $opt_ofile" ) )
|
|
|
237 |
{
|
|
|
238 |
Error ("Internal error. Cleartool lsco should not fail");
|
|
|
239 |
}
|
|
|
240 |
|
| 241 |
dpurdie |
241 |
#
|
|
|
242 |
# Can only have one 'reserved' checkout on the branch, but it may not
|
|
|
243 |
# be the first one listed.
|
|
|
244 |
# Lines are in sets of 3
|
|
|
245 |
# 1) Not used
|
|
|
246 |
# 2) Has keyword reserved
|
|
|
247 |
# 3) Has full path to view server
|
|
|
248 |
# Need veiew server path, iff its a reserved checkout
|
|
|
249 |
#
|
|
|
250 |
my $reserved = undef;
|
|
|
251 |
foreach ( @last_results )
|
| 227 |
dpurdie |
252 |
{
|
|
|
253 |
#
|
| 241 |
dpurdie |
254 |
# Once reserved has been seen, the next line will contain the view path
|
| 227 |
dpurdie |
255 |
#
|
| 241 |
dpurdie |
256 |
if ( $reserved )
|
|
|
257 |
{
|
|
|
258 |
m~\(\"(.+)\"\)~;
|
|
|
259 |
my $view = $1;
|
|
|
260 |
$view =~ s~/~\\~g unless ( $ENV{GBE_UNIX} );
|
|
|
261 |
Verbose2 ("Reserved checkout: Target View: $view" );
|
|
|
262 |
ClearCmd( "unreserve -comment \"Unreserved by JATS ASAVE\" -view \"$view\" $opt_ofile" );
|
|
|
263 |
|
|
|
264 |
#
|
|
|
265 |
# Only one reserved file can exist, so there is no more to do
|
|
|
266 |
#
|
|
|
267 |
last;
|
|
|
268 |
}
|
|
|
269 |
|
|
|
270 |
#
|
|
|
271 |
# Check to see if this line flags a reserved version
|
|
|
272 |
#
|
|
|
273 |
$reserved = m~\(reserved\)~;
|
| 227 |
dpurdie |
274 |
}
|
|
|
275 |
|
|
|
276 |
#
|
|
|
277 |
# Use clearcase to checkout the output file
|
|
|
278 |
#
|
|
|
279 |
ClearCmd ("co -nc -nq -ndata -nwarn -branch \"$target_branch\" $opt_ofile");
|
|
|
280 |
Error ("Program Terminated") if ( @error_list );
|
|
|
281 |
|
|
|
282 |
#
|
|
|
283 |
# Place the label on this file
|
|
|
284 |
# If the label is locked then unlock it first
|
|
|
285 |
# This is OK, because we are the builder ( or have permission )
|
|
|
286 |
#
|
|
|
287 |
ClearCmd ("unlock lbtype:$opt_label" ) if $was_locked;
|
|
|
288 |
|
|
|
289 |
ClearCmd ("mklabel -replace $opt_label \"$opt_ofile\"" );
|
|
|
290 |
my @delayed_error = @error_list;
|
|
|
291 |
|
|
|
292 |
ClearCmd ("lock lbtype:$opt_label" ) if $was_locked;
|
|
|
293 |
|
|
|
294 |
#
|
|
|
295 |
# Place a Hyperlink Merge arrow between the two files if it looks as though we
|
|
|
296 |
# have stolen the file or its label. If the original build file is on a different branch
|
|
|
297 |
# the we have stolen it.
|
|
|
298 |
#
|
|
|
299 |
Verbose ("Do we need to create a Hyperlink" );
|
|
|
300 |
|
|
|
301 |
my $target_name = $opt_ofile;
|
|
|
302 |
Verbose2 ("FullName: $full_name :Branch: $full_branch" );
|
|
|
303 |
Verbose2 ("TargetName: $target_name :Branch: $target_branch" );
|
|
|
304 |
|
|
|
305 |
if ( ( $full_branch ne $target_branch ) && ( !$opt_newbranch ) )
|
|
|
306 |
{
|
|
|
307 |
ClearCmd ("mkhlink Merge \"$full_name\" \"$target_name\" ");
|
|
|
308 |
}
|
|
|
309 |
|
|
|
310 |
#
|
|
|
311 |
# Check in the file auto.pl file as the new build.pl file
|
|
|
312 |
# This may get ugly if the current config-spec does not have a rule to
|
|
|
313 |
# select the "new" build.pl file. This is often the case
|
|
|
314 |
#
|
|
|
315 |
# Examine the error output and discard these errors
|
|
|
316 |
#
|
|
|
317 |
ClearCmd ("ci -c \"AutoBuilder checkin: $opt_label\" -identical -from \"$opt_infile\" \"$opt_ofile\"");
|
|
|
318 |
Error ("Program Terminated") unless ( $last_result =~ m/Checked in "$opt_ofile" version/ );
|
|
|
319 |
|
|
|
320 |
@error_list = @delayed_error;
|
|
|
321 |
Error ("Program Terminated") if ( @error_list );
|
|
|
322 |
|
|
|
323 |
exit 0;
|
|
|
324 |
|
|
|
325 |
#-------------------------------------------------------------------------------
|
|
|
326 |
# Function : ClearCmd
|
|
|
327 |
#
|
| 241 |
dpurdie |
328 |
# Description : Execute a ClearCase command and capture the reults
|
|
|
329 |
# Errors are held in one array
|
|
|
330 |
# Result are held in another
|
| 227 |
dpurdie |
331 |
#
|
|
|
332 |
# Inputs :
|
|
|
333 |
#
|
|
|
334 |
# Returns :
|
|
|
335 |
#
|
|
|
336 |
sub ClearCmd
|
|
|
337 |
{
|
|
|
338 |
my( $cmd ) = @_;
|
|
|
339 |
Verbose2( "cleartool $cmd" );
|
|
|
340 |
|
|
|
341 |
@error_list = ();
|
| 241 |
dpurdie |
342 |
@last_results = ();
|
| 227 |
dpurdie |
343 |
$last_result = undef;
|
|
|
344 |
|
|
|
345 |
open(CMD, "cleartool $cmd 2>&1 |") || Error( "can't run command: $!" );
|
|
|
346 |
while (<CMD>)
|
|
|
347 |
{
|
|
|
348 |
chomp;
|
|
|
349 |
$last_result = $_;
|
|
|
350 |
$last_result =~ tr~\\/~/~s;
|
| 241 |
dpurdie |
351 |
push @last_results, $last_result;
|
| 227 |
dpurdie |
352 |
|
|
|
353 |
Verbose ( "cleartool resp:" . $_);
|
|
|
354 |
push @error_list, $_ if ( m~Error:~ );
|
|
|
355 |
}
|
|
|
356 |
close(CMD);
|
|
|
357 |
|
|
|
358 |
Verbose2( "Exit Status: $?" );
|
|
|
359 |
return $? / 256;
|
|
|
360 |
}
|
|
|
361 |
|
|
|
362 |
#-------------------------------------------------------------------------------
|
|
|
363 |
# Function : display_error_list
|
|
|
364 |
#
|
|
|
365 |
# Description : Display the error list
|
|
|
366 |
# This function is registered as an Error callback function
|
|
|
367 |
# it will be called on error exit
|
|
|
368 |
#
|
|
|
369 |
# Inputs :
|
|
|
370 |
#
|
|
|
371 |
# Returns :
|
|
|
372 |
#
|
|
|
373 |
sub display_error_list
|
|
|
374 |
{
|
|
|
375 |
foreach ( @error_list )
|
|
|
376 |
{
|
|
|
377 |
print "$_\n";
|
|
|
378 |
}
|
|
|
379 |
}
|
|
|
380 |
|
|
|
381 |
#-------------------------------------------------------------------------------
|
|
|
382 |
# Documentation
|
|
|
383 |
#
|
|
|
384 |
|
|
|
385 |
=pod
|
|
|
386 |
|
|
|
387 |
=head1 NAME
|
|
|
388 |
|
|
|
389 |
jats_save_build - Save a modified build.pl/depends.xml file into version control
|
|
|
390 |
|
|
|
391 |
=head1 SYNOPSIS
|
|
|
392 |
|
|
|
393 |
jats etool jats_save_build [options]
|
|
|
394 |
|
|
|
395 |
Options:
|
|
|
396 |
-help - brief help message
|
|
|
397 |
-help -help - Detailed help message
|
|
|
398 |
-man - Full documentation
|
|
|
399 |
-verbose - Verbose operation
|
|
|
400 |
-infile xxx - Input file (auto.pl)
|
|
|
401 |
-outfile xxx - Output file (build.pl)
|
|
|
402 |
-label xxx - Label the new file (mandatory)
|
|
|
403 |
-branch xxx - Branch to create (AutoBuilder)
|
|
|
404 |
-newbranch - Force file to be on a new (project) branch
|
|
|
405 |
|
|
|
406 |
=head1 OPTIONS
|
|
|
407 |
|
|
|
408 |
=over 8
|
|
|
409 |
|
|
|
410 |
=item B<-help>
|
|
|
411 |
|
|
|
412 |
Print a brief help message and exits.
|
|
|
413 |
|
|
|
414 |
=item B<-help -help>
|
|
|
415 |
|
|
|
416 |
Print a detailed help message with an explanation for each option.
|
|
|
417 |
|
|
|
418 |
=item B<-man>
|
|
|
419 |
|
|
|
420 |
Prints the manual page and exits.
|
|
|
421 |
|
|
|
422 |
=item B<-newbranch>
|
|
|
423 |
|
|
|
424 |
This option will force the file to be checked into a new branch
|
|
|
425 |
The branch will be created on /main/0 unless it is already found elsewhere
|
|
|
426 |
|
|
|
427 |
This option allows a build.pl file to be placed on a new project branch.
|
|
|
428 |
|
|
|
429 |
=back
|
|
|
430 |
|
|
|
431 |
=head1 DESCRIPTION
|
|
|
432 |
|
|
|
433 |
This utility is used by the automated build system to place a modified build.pl
|
|
|
434 |
or a depends.xml file under version control, and then place a label on the file.
|
|
|
435 |
|
|
|
436 |
The utility will place the "new" build.pl file on a named branch of the branch
|
|
|
437 |
that contains the current build.pl file.
|
|
|
438 |
|
|
|
439 |
If the build.pl file is sourced from a different branch then a Merge arrow
|
|
|
440 |
will be created to indicate where the file and its label was taken from.
|
|
|
441 |
|
|
|
442 |
The operation will fail if that file is checked out "reserved". The program
|
|
|
443 |
can work around this - but its not done yet.
|
|
|
444 |
|
|
|
445 |
=cut
|
|
|
446 |
|