|
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 CommandController; |
|
26 |
|
27 |
|
28 # |
|
29 # Globals. |
|
30 # |
|
31 |
|
32 my $verbose = 0; |
|
33 my $iniData = IniData->New(); |
|
34 my $commandController = CommandController->New($iniData, 'DiffRel'); |
|
35 my $comp; |
|
36 my $ver1; |
|
37 my $ver2; |
|
38 my $specifiedLocalDir; |
|
39 my $specifiedReleaseDir; |
|
40 my $specifiedDiffTool; |
|
41 |
|
42 |
|
43 # |
|
44 # Main. |
|
45 # |
|
46 |
|
47 ProcessCommandLine(); |
|
48 DoDiff(); |
|
49 |
|
50 |
|
51 # |
|
52 # Subs. |
|
53 # |
|
54 |
|
55 sub ProcessCommandLine { |
|
56 Getopt::Long::Configure ("bundling"); |
|
57 my $help; |
|
58 GetOptions('h' => \$help, 'l=s' => \$specifiedLocalDir, 'r=s' => \$specifiedReleaseDir, 'v+' => \$verbose, 't=s' => \$specifiedDiffTool); |
|
59 |
|
60 if ($help) { |
|
61 Usage(0); |
|
62 } |
|
63 |
|
64 $comp = shift @ARGV; |
|
65 $ver1 = shift @ARGV; |
|
66 $ver2 = shift @ARGV; |
|
67 |
|
68 unless ($comp and $#ARGV = -1) { |
|
69 print "Error: Invalid arguments\n"; |
|
70 Usage(1); |
|
71 } |
|
72 |
|
73 if ($ver2 and $specifiedLocalDir) { |
|
74 print "Warning: The '-l' switch has no effect when specifying a pair of versions to difference\n"; |
|
75 } |
|
76 |
|
77 if ($ver2 and $specifiedReleaseDir) { |
|
78 print "Warning: The '-r' switch has no effect when specifying a pair of versions to difference\n"; |
|
79 } |
|
80 |
|
81 if ($specifiedReleaseDir and $specifiedReleaseDir !~ /^\\/) { |
|
82 die "Error: Release directories must be absolute (i.e. start with '\\')\n"; |
|
83 } |
|
84 |
|
85 if ($specifiedLocalDir) { |
|
86 Utils::AbsoluteFileName(\$specifiedLocalDir); |
|
87 } |
|
88 } |
|
89 |
|
90 sub Usage { |
|
91 my $exitCode = shift; |
|
92 |
|
93 Utils::PrintDeathMessage($exitCode, "\nUsage: diffrel [options] <component> [<version_1>] [<version_2>] |
|
94 |
|
95 options: |
|
96 |
|
97 -h help |
|
98 -l <local_dir> specify a specific local directory to difference against |
|
99 -r <release_dir> specify a specific directory within the release zip file to difference against |
|
100 -t <tool> specify a particular diffing tool to use (instead of that specified in reltools.ini) |
|
101 -v verbose output (-vv very verbose)\n"); |
|
102 } |
|
103 |
|
104 sub DoDiff { |
|
105 my $diffTool = $specifiedDiffTool || $iniData->DiffTool(); |
|
106 unless (defined $diffTool) { |
|
107 die "Error: No differencing tool specified - use diff_tool keyword in reltools.ini\n"; |
|
108 } |
|
109 |
|
110 my $envDb = EnvDb->Open($iniData, $verbose); |
|
111 unless ($ver1) { |
|
112 $ver1 = $envDb->Version($comp); |
|
113 unless ($ver1) { |
|
114 die "Error: $comp not currently installed\n"; |
|
115 } |
|
116 } |
|
117 |
|
118 Utils::InitialiseTempDir($iniData); |
|
119 eval { |
|
120 if ($ver2) { |
|
121 DiffPair($envDb, $diffTool); |
|
122 } |
|
123 else { |
|
124 DiffAgainstLocalDir($envDb, $diffTool); |
|
125 } |
|
126 }; |
|
127 Utils::RemoveTempDir(); |
|
128 if ($@) { |
|
129 die $@; |
|
130 } |
|
131 } |
|
132 |
|
133 sub DiffAgainstLocalDir { |
|
134 my $envDb = shift; |
|
135 my $diffTool = shift; |
|
136 my $tempDir = Utils::TempDir(); |
|
137 $envDb->UnpackSource($comp, $ver1, $tempDir, 0, 0, 1); # 0 = overwrite, 0 = do not show progress, 1 = validate |
|
138 my $significantDir = Utils::SignificantDir($tempDir); |
|
139 |
|
140 my $localDir; |
|
141 if ($specifiedLocalDir) { |
|
142 $localDir = $specifiedLocalDir; |
|
143 } |
|
144 else { |
|
145 $localDir = $significantDir; |
|
146 $localDir =~ s/\Q$tempDir\E//; |
|
147 unless ($localDir) { |
|
148 $localDir = '\\'; |
|
149 } |
|
150 $localDir = Utils::PrependSourceRoot($localDir); |
|
151 } |
|
152 # UnpackSource does not return a success status so we check the dir manually |
|
153 if (!-d $localDir) { |
|
154 warn "Nothing to do".($verbose ? '' : ' (run with -v for more info)').".\n"; |
|
155 return; |
|
156 } |
|
157 |
|
158 my $releaseDir; |
|
159 if ($specifiedReleaseDir) { |
|
160 $releaseDir = "$tempDir$specifiedReleaseDir"; |
|
161 } |
|
162 else { |
|
163 $releaseDir = $significantDir; |
|
164 } |
|
165 # UnpackSource does not return a success status so we check the dir manually |
|
166 if (!-d $releaseDir) { |
|
167 warn "Nothing to do".($verbose ? '' : ' (run with -v for more info)').".\n"; |
|
168 return; |
|
169 } |
|
170 |
|
171 if ($localDir eq '\\') { |
|
172 print "Warning: About to diff \"$releaseDir\" against the root of your development environment. |
|
173 You could alternatively use the -l and -r options to specify which directories to diff. |
|
174 Are you sure you want to continue? [y/n] "; |
|
175 my $response = <STDIN>; |
|
176 chomp $response; |
|
177 unless ($response eq 'y') { |
|
178 warn "Aborting...\n"; |
|
179 return; |
|
180 } |
|
181 } |
|
182 |
|
183 $localDir =~ s/^[\\\/]// unless ($localDir =~ m/^[\\\/][\\\/]/); |
|
184 if ($verbose) { print "Envoking \"call $diffTool \"$releaseDir\" \"$localDir\"\"\n"; } |
|
185 system "call \"$diffTool\" \"$releaseDir\" \"$localDir\""; |
|
186 } |
|
187 |
|
188 sub DiffPair { |
|
189 my $envDb = shift; |
|
190 my $diffTool = shift; |
|
191 my $tempDir = Utils::TempDir(); |
|
192 my $ver1Dir = "$tempDir\\1"; |
|
193 my $ver2Dir = "$tempDir\\2"; |
|
194 |
|
195 $envDb->UnpackSource($comp, $ver1, $ver1Dir, 0, 0, 1); # 0 = overwrite, 0 = do not show progress, 1 = validate |
|
196 $envDb->UnpackSource($comp, $ver2, $ver2Dir, 0, 0, 1); # 0 = overwrite, 0 = do not show progress, 1 = validate |
|
197 |
|
198 if (!-d $ver1Dir or !-d $ver2Dir) { |
|
199 warn "Nothing to do".($verbose ? '' : ' (run with -v for more info)').".\n"; |
|
200 return; |
|
201 } |
|
202 |
|
203 if ($verbose) { print "Envoking \"call $diffTool $ver1Dir $ver2Dir\"\n"; } |
|
204 system "call \"$diffTool\" \"$ver1Dir\" \"$ver2Dir\""; |
|
205 } |
|
206 |
|
207 |
|
208 =head1 NAME |
|
209 |
|
210 DiffRel - Displays the source differences between two component releases. |
|
211 |
|
212 =head1 SYNOPSIS |
|
213 |
|
214 diffrel [options] <component> [<version_1>] [<version_2>] |
|
215 |
|
216 options: |
|
217 |
|
218 -h help |
|
219 -l <local_dir> specify a specific local directory to difference against |
|
220 -r <release_dir> specify a specific directory within the release zip file to difference against |
|
221 -t <diff_tool> specify a particular diffing tool to use (instead of that in reltools.ini) |
|
222 -v verbose output (-vv very verbose) |
|
223 |
|
224 =head1 DESCRIPTION |
|
225 |
|
226 C<DiffRel> allows you to lauch a differencing tool of your choice to anyalise the source differences between either a pair of releases or a single release and the source in your development drive. The differencing tool to be used must be specified in C<reltools.ini> using the keyword C<diff_tool> and it must support differencing a pair of directories specified as command line arguments. |
|
227 |
|
228 There are three main ways of envoking C<DiffRel>: |
|
229 |
|
230 =over 4 |
|
231 |
|
232 =item * Specifying a component and a pair of versions |
|
233 |
|
234 C<DiffRel> will difference the source of a pair of component releases. It will unpack the source from the specified versions into two temporary directories. The differencing tool will then be launched with the names of the temporary directories passed as command line arguments. |
|
235 |
|
236 =item * Specifying a component and a single version |
|
237 |
|
238 C<DiffRel> will difference the source of the specified version against that present in your development drive. It will unpack the source from the specified version into a temporary directory. It will then attempt to find a suitable pair of directories to difference (this process described in detail later) and then launch the differencing tool, passing the directory names as command line arguments. |
|
239 |
|
240 =item * Specifying just a component name |
|
241 |
|
242 As above, except the source of the currently installed version of the component will be differenced against that in your development drive. |
|
243 |
|
244 =back |
|
245 |
|
246 As mentioned previously, when C<DiffRel> is asked to perform a diff against the source code in your development drive, it attempts find a suitable pair of directories to pass to your differencing tool. The source code belonging to a particular component often lives in a deeply nested directory structure containing the source for other components also. C<DiffRel> therefore attempts to find the deepest sub-directory that captures all the source belonging to a particular component. It does this as follows: |
|
247 |
|
248 =over 4 |
|
249 |
|
250 =item 1 |
|
251 |
|
252 C<DiffRel> unpacks the source belonging to the component to be differenced against into a temporary directory. |
|
253 |
|
254 =item 2 |
|
255 |
|
256 C<DiffRel> then examines the sub-directories of the temporary directory, looking for the deepest sub-directory that captures all files. |
|
257 |
|
258 =item 3 |
|
259 |
|
260 By default the full path to this sub-directory is used as the first argument to the differencing tool. Optionally, this argument can be manually specified using the C<-r> option. In this case, C<DiffRel> with add the name of the temporary directory to the start of the path you specify. |
|
261 |
|
262 =item 4 |
|
263 |
|
264 By default, the sub-directory found in (2), minus the leading temporary directory name is used as the second argument to your differencing tool. Optionally, this argument can be manually specified using the C<-l> option. In this case, C<DiffRel> will use the path you specify unaltered. |
|
265 |
|
266 =back |
|
267 |
|
268 Normally C<DiffRel>'s default behaviour will do the right thing. Situations where you may want to use the C<-r> and / or the C<-l> option include: |
|
269 |
|
270 =over 4 |
|
271 |
|
272 =item 1 |
|
273 |
|
274 If the source of the component you need to difference is in a different location in your development environment compared to that of the released version. |
|
275 |
|
276 =item 2 |
|
277 |
|
278 If the source of the component you need to difference is contained in two or more root level directories. In this case C<DiffRel> will warn that it is about to difference against the root of your development drive (which is unlikely to be a good idea since there are likely to be source directories of other components at this level). |
|
279 |
|
280 =back |
|
281 |
|
282 =head1 KNOWN BUGS |
|
283 |
|
284 None. |
|
285 |
|
286 =head1 COPYRIGHT |
|
287 |
|
288 Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
289 All rights reserved. |
|
290 This component and the accompanying materials are made available |
|
291 under the terms of the License "Eclipse Public License v1.0" |
|
292 which accompanies this distribution, and is available |
|
293 at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
294 |
|
295 Initial Contributors: |
|
296 Nokia Corporation - initial contribution. |
|
297 |
|
298 Contributors: |
|
299 |
|
300 Description: |
|
301 |
|
302 |
|
303 =cut |