602
|
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
|