|
1 # Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 # All rights reserved. |
|
3 # This component and the accompanying materials are made available |
|
4 # under the terms of the License "Eclipse Public License v1.0" |
|
5 # which accompanies this distribution, and is available |
|
6 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 # |
|
8 # Initial Contributors: |
|
9 # Nokia Corporation - initial contribution. |
|
10 # |
|
11 # Contributors: |
|
12 # |
|
13 # Description: |
|
14 # |
|
15 # |
|
16 |
|
17 package EnvDifferencer; |
|
18 |
|
19 use strict; |
|
20 use RelData; |
|
21 |
|
22 sub New { |
|
23 my $class = shift; |
|
24 my $self = bless {}, (ref $class || $class); |
|
25 $self->{iniData} = shift; |
|
26 $self->{verbose} = shift; |
|
27 $self->{startcomp} = undef; |
|
28 $self->{endcomp} = undef; |
|
29 $self->{startver} = undef; |
|
30 $self->{endver} = undef; |
|
31 $self->{reldatacache} = {}; # keyed by concatenated of comp and ver |
|
32 $self->{results} = undef; |
|
33 if ($self->{verbose}) { |
|
34 require Data::Dumper ; |
|
35 Data::Dumper->import(); |
|
36 } |
|
37 return $self; |
|
38 } |
|
39 |
|
40 sub SetStartCompVer { |
|
41 my $self = shift; |
|
42 my $comp = shift; |
|
43 my $ver = shift; |
|
44 $self->Reset(); |
|
45 $self->{startcomp} = $comp; |
|
46 $self->{startver} = $ver; |
|
47 } |
|
48 |
|
49 sub SetEndCompVer { |
|
50 my $self = shift; |
|
51 my $comp = shift; |
|
52 my $ver = shift; |
|
53 $self->Reset(); |
|
54 $self->{endcomp} = $comp; |
|
55 $self->{endver} = $ver; |
|
56 } |
|
57 |
|
58 sub Reset { |
|
59 my $self = shift; |
|
60 $self->{results} = undef; |
|
61 } |
|
62 |
|
63 # Accessor methods |
|
64 |
|
65 sub StartEnvReldata { |
|
66 my $self = shift; |
|
67 die "Start component not defined" unless $self->{startcomp}; |
|
68 die "Start version not defined" unless $self->{startver}; |
|
69 return $self->RelData($self->{startcomp}, $self->{startver}); |
|
70 } |
|
71 |
|
72 sub EndEnvReldata { |
|
73 my $self = shift; |
|
74 die "End component not defined" unless $self->{endcomp}; |
|
75 die "End version not defined" unless $self->{endver}; |
|
76 return $self->RelData($self->{endcomp}, $self->{endver}); |
|
77 } |
|
78 |
|
79 sub StartReldata { |
|
80 my $self = shift; |
|
81 my $comp = shift; |
|
82 return $self->RelData($comp, $self->StartVersion($comp)); |
|
83 } |
|
84 |
|
85 sub EndReldata { |
|
86 my $self = shift; |
|
87 my $comp = shift; |
|
88 return $self->RelData($comp, $self->EndVersion($comp)); |
|
89 } |
|
90 |
|
91 sub StartVersion { |
|
92 my $self = shift; |
|
93 my $comp = shift; |
|
94 return $self->GetStartEnv()->{$comp}; |
|
95 } |
|
96 |
|
97 sub EndVersion { |
|
98 my $self = shift; |
|
99 my $comp = shift; |
|
100 return $self->GetEndEnv()->{$comp}; |
|
101 } |
|
102 |
|
103 sub ChangedComps { |
|
104 my $self = shift; |
|
105 $self->DoDiff; |
|
106 return $self->{results}->{diff}->{changed}; |
|
107 } |
|
108 |
|
109 sub NewerComps { |
|
110 my $self = shift; |
|
111 $self->CompareDiffDates; |
|
112 return $self->{results}->{diffdates}->{newer}; |
|
113 } |
|
114 |
|
115 sub OlderComps { |
|
116 my $self = shift; |
|
117 $self->CompareDiffDates; |
|
118 return $self->{results}->{diffdates}->{older}; |
|
119 } |
|
120 |
|
121 sub UnchangedComps { |
|
122 my $self = shift; |
|
123 $self->DoDiff; |
|
124 return $self->{results}->{diff}->{same}; |
|
125 } |
|
126 |
|
127 sub OnlyStart { |
|
128 my $self = shift; |
|
129 $self->DoDiff; |
|
130 return $self->{results}->{diff}->{onlystart}; |
|
131 } |
|
132 |
|
133 sub OnlyEnd { |
|
134 my $self = shift; |
|
135 $self->DoDiff; |
|
136 return $self->{results}->{diff}->{onlyend}; |
|
137 } |
|
138 |
|
139 sub IntermediateReldatas { |
|
140 my $self = shift; |
|
141 my $comp = shift; |
|
142 my $relDataObjects = RelData->OpenSet($self->{iniData}, $comp, $self->{verbose}); |
|
143 |
|
144 my $startdate = $self->StartReldata($comp)->ReleaseTime(); |
|
145 my $enddate = $self->EndReldata($comp)->ReleaseTime(); |
|
146 |
|
147 # Specifically exclude the start and end reldatas... i.e use < > not <= >= |
|
148 my @results = grep { $_->ReleaseTime() < $enddate and $_->ReleaseTime() > $startdate } @$relDataObjects; |
|
149 return \@results; |
|
150 } |
|
151 |
|
152 sub GetStartEnv { |
|
153 my $self = shift; |
|
154 unless ($self->{results}->{startenv}) { |
|
155 if ($self->{startcomp}) { |
|
156 $self->{results}->{startenv} = $self->StartEnvReldata()->Environment(); |
|
157 } else { |
|
158 $self->{results}->{startenv} = $self->CurrentEnv; |
|
159 } |
|
160 } |
|
161 return $self->{results}->{startenv}; |
|
162 } |
|
163 |
|
164 sub GetEndEnv { |
|
165 my $self = shift; |
|
166 unless ($self->{results}->{endenv}) { |
|
167 if ($self->{endcomp}) { |
|
168 $self->{results}->{endenv} = $self->EndEnvReldata()->Environment(); |
|
169 } else { |
|
170 $self->{results}->{endenv} = $self->CurrentEnv; |
|
171 } |
|
172 } |
|
173 return $self->{results}->{endenv}; |
|
174 } |
|
175 |
|
176 ### Private |
|
177 |
|
178 sub CurrentEnv { |
|
179 my $self = shift; |
|
180 my $envDb = EnvDb->Open($self->{iniData}, $self->{verbose}); |
|
181 return $envDb->VersionInfo(); |
|
182 } |
|
183 |
|
184 sub DoDiff { |
|
185 my $self = shift; |
|
186 |
|
187 return if $self->{results}->{diff}; |
|
188 |
|
189 die "Neither environment was specified.\n" unless ($self->{startcomp} || $self->{endcomp}); |
|
190 |
|
191 my %env1 = %{$self->GetStartEnv()}; |
|
192 my %env2 = %{$self->GetEndEnv()}; |
|
193 # Deliberately make copies, as we will be deleting stuff from them |
|
194 |
|
195 if ($self->{verbose}>1) { |
|
196 print "Start environment is ".Dumper(\%env1)."\n"; |
|
197 print "End environment is ".Dumper(\%env2)."\n"; |
|
198 } |
|
199 |
|
200 my @changed; |
|
201 my @onlynew; |
|
202 my @onlyold; |
|
203 my @same; |
|
204 |
|
205 # Compare $env1 against $env2 first. |
|
206 foreach my $thisComp (keys %env1) { |
|
207 my $ver1 = $env1{$thisComp}; |
|
208 my $ver2 = $env2{$thisComp}; |
|
209 if (not defined $ver2) { |
|
210 push @onlyold, $thisComp; |
|
211 } |
|
212 elsif (lc($ver1) eq lc($ver2)) { |
|
213 push @same, $thisComp; |
|
214 } |
|
215 else { |
|
216 push @changed, $thisComp; |
|
217 } |
|
218 |
|
219 if (defined $ver2) { |
|
220 # Remove this component from $env2 because it has been accounted for. |
|
221 # Components left over in the $env2 hash are those not present in $env1. |
|
222 delete $env2{$thisComp}; |
|
223 } |
|
224 } |
|
225 |
|
226 # List the components in $env2 but not in $env1. |
|
227 @onlynew = keys %env2; |
|
228 |
|
229 $self->{results}->{diff} = { |
|
230 same => \@same, |
|
231 onlyend => \@onlynew, |
|
232 onlystart => \@onlyold, |
|
233 changed => \@changed |
|
234 }; |
|
235 |
|
236 print "At end of main comparison... with results ".Dumper($self->{results}->{diff})."\n" if $self->{verbose}>1; |
|
237 } |
|
238 |
|
239 sub CompareDiffDates { |
|
240 my $self = shift; |
|
241 return if $self->{results}->{diffdates}; |
|
242 $self->DoDiff; # returns if already completed |
|
243 |
|
244 my @older; |
|
245 my @newer; |
|
246 foreach my $thisComp (@{$self->{results}->{diff}->{changed}}) { |
|
247 my $relData1 = $self->StartReldata($thisComp); |
|
248 my $relData2 = $self->EndReldata($thisComp); |
|
249 if ($relData1->ReleaseTime() <= $relData2->ReleaseTime()) { |
|
250 push @newer, $thisComp; |
|
251 } else { |
|
252 push @older, $thisComp; |
|
253 } |
|
254 } |
|
255 |
|
256 $self->{results}->{diffdates} = { |
|
257 older => \@older, |
|
258 newer => \@newer |
|
259 }; |
|
260 print "At end of date comparison... with results ".Dumper($self->{results}->{diffdates})."\n" if $self->{verbose}>1; |
|
261 } |
|
262 |
|
263 sub RelData { |
|
264 my $self = shift; |
|
265 my $comp = shift; |
|
266 my $ver = shift; |
|
267 |
|
268 print "Asked for reldata for $comp $ver\n" if $self->{verbose}>2; |
|
269 |
|
270 die "Can't get reldata for undefined comp" unless $comp; |
|
271 die "Can't get reldata for undefined version of $comp" unless $ver; |
|
272 |
|
273 my $key = "$comp$ver"; |
|
274 unless ($self->{reldatacache}->{$key}) { |
|
275 $self->{reldatacache}->{$key} = RelData->Open |
|
276 ($self->{iniData}, $comp, $ver, $self->{verbose}); |
|
277 } |
|
278 return $self->{reldatacache}->{$key}; |
|
279 } |
|
280 |
|
281 1; |
|
282 |
|
283 __END__ |
|
284 |
|
285 =head1 NAME |
|
286 |
|
287 EnvDifferencer.pm - A class to find differences between two environments. |
|
288 |
|
289 =head1 DESCRIPTION |
|
290 |
|
291 This class is used by C<DiffEnv> and C<ViewNotes> to examine the differences between two environments. To use it, first create an object, then use the C<SetStartCompVer> and C<SetEndCompVer> methods to set the component name and version that you wish to compare. You can then use any of the other methods to access information about the differences between them. |
|
292 |
|
293 =head1 INTERFACE |
|
294 |
|
295 =head2 Necessary calls |
|
296 |
|
297 =head3 New |
|
298 |
|
299 Expects to be passed two arguments; firstly, an C<IniData> object, and secondly, a verbosity level. |
|
300 |
|
301 =head3 SetStartCompVer |
|
302 |
|
303 =head3 SetEndCompVer |
|
304 |
|
305 These two methods are each passed a component name a version number. These two environments are used for differencing. Note that no differencing is actually performed until information is requested by one of the accessor methods. These methods also call C<Reset>, which means that all results are deleted and a new diff will be performed whenever information is requested. |
|
306 |
|
307 If one of these is not called before the comparison, then the current environment (as returned by a C<EnvDb> object) will be used for the missing environment. |
|
308 |
|
309 =head3 Reset |
|
310 |
|
311 This method should never be needed. It resets the object so that it performs a new diff the next time some information is requested. |
|
312 |
|
313 =head2 Accessor Methods |
|
314 |
|
315 Any of these may trigger a differencing to happen. |
|
316 |
|
317 =head3 StartReldata |
|
318 |
|
319 =head3 EndReldata |
|
320 |
|
321 Takes a component name. Returns a C<RelData> object corresponding to that component in the start or the end environment. |
|
322 |
|
323 =head3 StartVersion |
|
324 |
|
325 =head3 EndVersion |
|
326 |
|
327 Given a component name, returns the version number of that component in the start or the end environment. The behaviour is undefined if that component doesn't exist in the given environment. |
|
328 |
|
329 =head3 GetStartEnv |
|
330 |
|
331 =head3 GetEndEnv |
|
332 |
|
333 Returns a hashref of the components and version numbers in each environment. |
|
334 |
|
335 =head3 StartEnvReldata |
|
336 |
|
337 =head3 EndEnvReldata |
|
338 |
|
339 Returns the C<RelData> object corresponding to the environment itself. |
|
340 |
|
341 =head3 ChangedComps |
|
342 |
|
343 Returns a list of component names in both environments, but with different version numbers. |
|
344 |
|
345 =head3 UnchangedComps |
|
346 |
|
347 Returns a similar list of those components which are identical in both environments. |
|
348 |
|
349 =head3 OnlyStart |
|
350 |
|
351 =head3 OnlyEnd |
|
352 |
|
353 Return lists of those components only in one or other environment. |
|
354 |
|
355 =head3 NewerComps |
|
356 |
|
357 =head3 OlderComps |
|
358 |
|
359 These two methods trigger some additional differencing, which compares the dates of each changed component. They then return a list of those components which are newer, or older, in the end environment. |
|
360 |
|
361 =head3 IntermediateReldatas |
|
362 |
|
363 Given a component name, this returns a list of C<RelData> objects belonging to releases of that component made between the start and end release. It specifically does not include the start or end release. |
|
364 |
|
365 =head1 KNOWN BUGS |
|
366 |
|
367 None. |
|
368 |
|
369 =head1 COPYRIGHT |
|
370 |
|
371 Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
372 All rights reserved. |
|
373 This component and the accompanying materials are made available |
|
374 under the terms of the License "Eclipse Public License v1.0" |
|
375 which accompanies this distribution, and is available |
|
376 at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
377 |
|
378 Initial Contributors: |
|
379 Nokia Corporation - initial contribution. |
|
380 |
|
381 Contributors: |
|
382 |
|
383 Description: |
|
384 |
|
385 |
|
386 =cut |