|
1 #!perl |
|
2 # Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of the License "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # |
|
16 # |
|
17 |
|
18 use strict; |
|
19 use FindBin; |
|
20 use lib "$FindBin::Bin"; |
|
21 use Getopt::Long; |
|
22 use IniData; |
|
23 use EnvDb; |
|
24 use Utils; |
|
25 use PrepRel; |
|
26 use CommandController; |
|
27 |
|
28 |
|
29 # |
|
30 # Constants. |
|
31 # |
|
32 |
|
33 use constant UPDATED => 0; |
|
34 use constant UNCHANGED => 1; |
|
35 |
|
36 |
|
37 # |
|
38 # Globals. |
|
39 # |
|
40 |
|
41 my $verbose = 0; |
|
42 my $newMrpName; |
|
43 my $inputFile; |
|
44 my $comp; |
|
45 my $ver; |
|
46 my $intVer; |
|
47 my $iniData = IniData->New(); |
|
48 my $commandController = CommandController->New($iniData, 'PrepEnv'); |
|
49 my $envDb; |
|
50 my $mode; |
|
51 my $samemrps; |
|
52 my $fixedIntVer; |
|
53 my $printlatestversion; |
|
54 my $skipPendingRelease; |
|
55 |
|
56 |
|
57 # |
|
58 # Main. |
|
59 # |
|
60 |
|
61 ProcessCommandLine(); |
|
62 PrepEnv(); |
|
63 |
|
64 |
|
65 # |
|
66 # Subs. |
|
67 # |
|
68 |
|
69 sub ProcessCommandLine { |
|
70 Getopt::Long::Configure ("bundling"); |
|
71 my $help; |
|
72 GetOptions("h" => \$help, "v+" => \$verbose, "m" => \$samemrps, "i=s" => \$fixedIntVer, "l" => \$printlatestversion, "p" => \$skipPendingRelease); |
|
73 |
|
74 if ($help) { |
|
75 Usage(0); |
|
76 } |
|
77 |
|
78 $inputFile = shift @ARGV; |
|
79 |
|
80 unless ($#ARGV == -1) { |
|
81 print "Error: Invalid number of arguments\n"; |
|
82 Usage(1); |
|
83 } |
|
84 if ($printlatestversion && $inputFile) { |
|
85 print "Error: can't use -l with an input file\n"; |
|
86 Usage(1); |
|
87 } |
|
88 if ($skipPendingRelease && $inputFile) { |
|
89 print "Error: can't use -p with an input file\n"; |
|
90 Usage(1); |
|
91 } |
|
92 |
|
93 $envDb = EnvDb->Open($iniData, $verbose); |
|
94 } |
|
95 |
|
96 sub Usage { |
|
97 my $exitCode = shift; |
|
98 |
|
99 Utils::PrintDeathMessage($exitCode, "\nUsage: prepenv [options] [<input_file_name>] |
|
100 |
|
101 options: |
|
102 |
|
103 -h help |
|
104 -v verbose output (-vv very verbose) |
|
105 -m don't query for MRP location (assume same as previously) |
|
106 -i <number> use this internal version number for each component |
|
107 |
|
108 Options only valid in interactive mode: |
|
109 -l print latest version number |
|
110 -p skip those components that are pending release |
|
111 |
|
112 Note: if prepenv is failing to recognise some components are dirty, |
|
113 run 'envinfo -f' then run 'prepenv' again.\n"); |
|
114 } |
|
115 |
|
116 sub PrepEnv { |
|
117 if (defined $inputFile) { |
|
118 HandleInputFile(); |
|
119 } |
|
120 else { |
|
121 HandleInteractive(); |
|
122 } |
|
123 } |
|
124 |
|
125 sub HandleInputFile { |
|
126 open (IN, $inputFile) or die "Error: Couldn't open $inputFile: $!\n"; |
|
127 my $numEntriesUpdated = 0; |
|
128 my $numEntriesAdded = 0; |
|
129 my $numErrors = 0; |
|
130 my $lineNum = 0; |
|
131 while (my $line = <IN>) { |
|
132 ++$lineNum; |
|
133 # Remove line feed, white space and comments. |
|
134 chomp $line; |
|
135 $line =~ s/^\s*$//; |
|
136 $line =~ s/#.*//; |
|
137 if ($line eq '') { |
|
138 # Nothing left. |
|
139 next; |
|
140 } |
|
141 |
|
142 local @ARGV; |
|
143 @ARGV = split (/\s+/, $line); |
|
144 my $mrpName; |
|
145 GetOptions("m=s" => \$mrpName); |
|
146 (my $comp, my $ver, my $intVer) = @ARGV; |
|
147 unless (defined $comp and defined $ver and $#ARGV <= 2) { |
|
148 die "Error: Line $lineNum contains invalid arguments in \"$inputFile\"\n"; |
|
149 } |
|
150 $intVer ||= undef; |
|
151 $mrpName ||= undef; |
|
152 if (!defined $mrpName && $samemrps) { |
|
153 eval { |
|
154 $mrpName = $envDb->MrpName($comp); |
|
155 }; |
|
156 if ($@) { |
|
157 die "Error: Could not get MRP location for \"$comp\", because $@\n"; |
|
158 } |
|
159 } |
|
160 if (!defined $intVer && $fixedIntVer) { |
|
161 $intVer = $fixedIntVer; |
|
162 } |
|
163 my $updating = $envDb->Version($comp); |
|
164 if ($verbose) { |
|
165 if (defined $updating) { |
|
166 print "Updating $comp $ver...\n"; |
|
167 } |
|
168 else { |
|
169 print "Adding $comp $ver...\n"; |
|
170 } |
|
171 } |
|
172 eval { |
|
173 PrepRel::PrepRel($iniData, $envDb, $comp, $ver, $intVer, $mrpName); |
|
174 }; |
|
175 if ($@) { |
|
176 print $@; |
|
177 ++$numErrors; |
|
178 } |
|
179 elsif (defined $updating) { |
|
180 ++$numEntriesUpdated; |
|
181 } |
|
182 else { |
|
183 ++$numEntriesAdded; |
|
184 } |
|
185 } |
|
186 close (IN); |
|
187 print "$numEntriesAdded component(s) added, $numEntriesUpdated component(s) updated, $numErrors error(s)\n"; |
|
188 } |
|
189 |
|
190 sub HandleInteractive { |
|
191 my $verInfo = $envDb->VersionInfo(); |
|
192 my $numUpdatedEntries = 0; |
|
193 my $numUnchangedEntries = 0; |
|
194 foreach my $thisComp (sort keys %{$verInfo}) { |
|
195 my $thisStatus = $envDb->Status($thisComp); |
|
196 if ($thisStatus == EnvDb::STATUS_DIRTY or $thisStatus == EnvDb::STATUS_DIRTY_SOURCE or ($thisStatus == EnvDb::STATUS_PENDING_RELEASE && !$skipPendingRelease)) { |
|
197 my $action = DoInteraction($thisComp, $verInfo->{$thisComp}); |
|
198 if ($action == UPDATED) { |
|
199 ++$numUpdatedEntries; |
|
200 } |
|
201 else { |
|
202 ++$numUnchangedEntries; |
|
203 } |
|
204 } |
|
205 } |
|
206 print "$numUpdatedEntries component(s) updated, $numUnchangedEntries component(s) unchanged\n"; |
|
207 if ($numUpdatedEntries + $numUnchangedEntries == 0) { |
|
208 my $pendingReleaseString = $skipPendingRelease?"":" or pending release"; |
|
209 print <<ENDGIBBER; |
|
210 No components appeared dirty$pendingReleaseString. If you were expecting to see more dirty |
|
211 components, run 'envinfo -f' then run prepenv again. |
|
212 ENDGIBBER |
|
213 } |
|
214 } |
|
215 |
|
216 sub DoInteraction { |
|
217 my $comp = shift; |
|
218 my $ver = shift; |
|
219 my $modified = 0; |
|
220 |
|
221 ShowLatestVer($comp) if $printlatestversion; |
|
222 |
|
223 print "$comp version [$ver] "; |
|
224 |
|
225 my $newVer = <STDIN>; |
|
226 chomp $newVer; |
|
227 if ($newVer) { |
|
228 $modified = 1; |
|
229 } |
|
230 else { |
|
231 undef $newVer; |
|
232 } |
|
233 |
|
234 my $newIntVer; |
|
235 if ($fixedIntVer) { |
|
236 $newIntVer = $fixedIntVer; |
|
237 } else { |
|
238 my $intVer = $envDb->InternalVersion($comp); |
|
239 print "$comp internal version "; |
|
240 if (defined $intVer and !defined $newVer) { |
|
241 print "[$intVer] "; |
|
242 } |
|
243 $newIntVer = <STDIN>; |
|
244 chomp $newIntVer; |
|
245 if ($newIntVer) { |
|
246 $modified = 1; |
|
247 } |
|
248 else { |
|
249 undef $newIntVer; |
|
250 } |
|
251 } |
|
252 |
|
253 my $mrpName = $envDb->MrpName($comp); |
|
254 my $newMrpName; |
|
255 if ($samemrps) { |
|
256 $newMrpName = $mrpName; |
|
257 } else { |
|
258 print "$comp mrp name [$mrpName] "; |
|
259 $newMrpName = <STDIN>; |
|
260 chomp $newMrpName; |
|
261 if ($newMrpName) { |
|
262 $modified = 1; |
|
263 } |
|
264 else { |
|
265 undef $newMrpName; |
|
266 } |
|
267 } |
|
268 |
|
269 my $return = UNCHANGED; |
|
270 if ($modified) { |
|
271 eval { |
|
272 PrepRel::PrepRel($iniData, $envDb, $comp, $newVer, $newIntVer, $newMrpName); |
|
273 }; |
|
274 if ($@) { |
|
275 print $@; |
|
276 } |
|
277 else { |
|
278 $return = UPDATED; |
|
279 } |
|
280 } |
|
281 |
|
282 print "\n"; |
|
283 return $return; |
|
284 } |
|
285 |
|
286 sub ShowLatestVer { |
|
287 my $comp = shift; |
|
288 my $reldata = RelData->OpenSet($iniData, $comp, $verbose); |
|
289 if ($reldata) { |
|
290 my $reldatum = $reldata->[0]; |
|
291 if ($reldatum) { |
|
292 print "$comp: Latest version: ".$reldatum->Version . " (internal version ".$reldatum->InternalVersion.")\n"; |
|
293 return; |
|
294 } |
|
295 } |
|
296 print "No previous versions.\n"; |
|
297 } |
|
298 |
|
299 __END__ |
|
300 |
|
301 =head1 NAME |
|
302 |
|
303 PrepEnv - Prepares an environment for release. |
|
304 |
|
305 =head1 SYNOPSIS |
|
306 |
|
307 prepenv [options] [<input_file_name>] |
|
308 |
|
309 options: |
|
310 |
|
311 -h help |
|
312 -v verbose output (-vv very verbose) |
|
313 -i <internal> use this internal version number instead of prompting |
|
314 -m don't prompt for MRP location |
|
315 |
|
316 Options valid only in interactive mode: |
|
317 |
|
318 -l show latest version number |
|
319 -p skip those components that are pending release |
|
320 |
|
321 =head1 DESCRIPTION |
|
322 |
|
323 Before an environment can be released, the status of each component that needs to be released must be set to I<pending release> and the new versions and F<mrp> names must be specified. C<PrepEnv> provides two ways of manipulating this information in the environment database: |
|
324 |
|
325 =over 4 |
|
326 |
|
327 =item 1 Interactively |
|
328 |
|
329 If no arguments are given to C<PrepEnv>, it will enter an interactive mode asking for version, internal version and mrp name for each component in the database with a status of I<dirty> or I<binaries clean, source dirty> (or I<pending release> unless -p is specified). It won't ask for internal version or MRP name if you have used the -i or -m respectively. The current value of each will be presented in square brackets. Hitting I<return> will preserve the current value. If all the current values are selected for a particular component, it's environment database entry will not be changed, otherwise the values will be updated and its status will be set to I<pending release>. |
|
330 |
|
331 =item 3 Via an input file |
|
332 |
|
333 The name of an input file may be specified as an argument. The structure of each line in the file must be as follows: |
|
334 |
|
335 <component_name> <version> [<internal_version>] [-m <mrp_name>] |
|
336 |
|
337 Note, you can optionally specify internal version (assuming the F<reltools.ini> keyword C<require_internal_versions> has not been specified) and F<mrp> name. You can also optionally specify a new F<mrp> name, but to distinguish this from an internal version you much precede it with '-m'. |
|
338 |
|
339 =back |
|
340 |
|
341 Note, C<PrepEnv> (and its counterpart C<PrepRel>) do nothing more than update your the environment database. You can execute these commands as many times as you like before running C<MakeEnv> to actually release the environment. |
|
342 |
|
343 C<PrepEnv> does not always identify dirty components correctly. If you've just made a component dirty, then run C<prepenv> immediately afterwards, it will not notice that dirty component. To solve this you should run C<EnvInfo -f> before running C<PrepEnv>. C<PrepEnv> will then ask you about components correctly. This is a deliberate design decision: otherwise, C<PrepEnv> would have to do a slow environment scan before prompting you. Normally, you'll have run C<envinfo -f> first, so the environment scan is redundant. |
|
344 |
|
345 =head1 KNOWN BUGS |
|
346 |
|
347 None. |
|
348 |
|
349 =head1 COPYRIGHT |
|
350 |
|
351 Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
352 All rights reserved. |
|
353 This component and the accompanying materials are made available |
|
354 under the terms of the License "Eclipse Public License v1.0" |
|
355 which accompanies this distribution, and is available |
|
356 at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
357 |
|
358 Initial Contributors: |
|
359 Nokia Corporation - initial contribution. |
|
360 |
|
361 Contributors: |
|
362 |
|
363 Description: |
|
364 |
|
365 |
|
366 =cut |