--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/releasing/cbrtools/perl/EnvDifferencer.pm Fri Jun 25 18:37:20 2010 +0800
@@ -0,0 +1,386 @@
+# Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#
+
+package EnvDifferencer;
+
+use strict;
+use RelData;
+
+sub New {
+ my $class = shift;
+ my $self = bless {}, (ref $class || $class);
+ $self->{iniData} = shift;
+ $self->{verbose} = shift;
+ $self->{startcomp} = undef;
+ $self->{endcomp} = undef;
+ $self->{startver} = undef;
+ $self->{endver} = undef;
+ $self->{reldatacache} = {}; # keyed by concatenated of comp and ver
+ $self->{results} = undef;
+ if ($self->{verbose}) {
+ require Data::Dumper ;
+ Data::Dumper->import();
+ }
+ return $self;
+}
+
+sub SetStartCompVer {
+ my $self = shift;
+ my $comp = shift;
+ my $ver = shift;
+ $self->Reset();
+ $self->{startcomp} = $comp;
+ $self->{startver} = $ver;
+}
+
+sub SetEndCompVer {
+ my $self = shift;
+ my $comp = shift;
+ my $ver = shift;
+ $self->Reset();
+ $self->{endcomp} = $comp;
+ $self->{endver} = $ver;
+}
+
+sub Reset {
+ my $self = shift;
+ $self->{results} = undef;
+}
+
+# Accessor methods
+
+sub StartEnvReldata {
+ my $self = shift;
+ die "Start component not defined" unless $self->{startcomp};
+ die "Start version not defined" unless $self->{startver};
+ return $self->RelData($self->{startcomp}, $self->{startver});
+}
+
+sub EndEnvReldata {
+ my $self = shift;
+ die "End component not defined" unless $self->{endcomp};
+ die "End version not defined" unless $self->{endver};
+ return $self->RelData($self->{endcomp}, $self->{endver});
+}
+
+sub StartReldata {
+ my $self = shift;
+ my $comp = shift;
+ return $self->RelData($comp, $self->StartVersion($comp));
+}
+
+sub EndReldata {
+ my $self = shift;
+ my $comp = shift;
+ return $self->RelData($comp, $self->EndVersion($comp));
+}
+
+sub StartVersion {
+ my $self = shift;
+ my $comp = shift;
+ return $self->GetStartEnv()->{$comp};
+}
+
+sub EndVersion {
+ my $self = shift;
+ my $comp = shift;
+ return $self->GetEndEnv()->{$comp};
+}
+
+sub ChangedComps {
+ my $self = shift;
+ $self->DoDiff;
+ return $self->{results}->{diff}->{changed};
+}
+
+sub NewerComps {
+ my $self = shift;
+ $self->CompareDiffDates;
+ return $self->{results}->{diffdates}->{newer};
+}
+
+sub OlderComps {
+ my $self = shift;
+ $self->CompareDiffDates;
+ return $self->{results}->{diffdates}->{older};
+}
+
+sub UnchangedComps {
+ my $self = shift;
+ $self->DoDiff;
+ return $self->{results}->{diff}->{same};
+}
+
+sub OnlyStart {
+ my $self = shift;
+ $self->DoDiff;
+ return $self->{results}->{diff}->{onlystart};
+}
+
+sub OnlyEnd {
+ my $self = shift;
+ $self->DoDiff;
+ return $self->{results}->{diff}->{onlyend};
+}
+
+sub IntermediateReldatas {
+ my $self = shift;
+ my $comp = shift;
+ my $relDataObjects = RelData->OpenSet($self->{iniData}, $comp, $self->{verbose});
+
+ my $startdate = $self->StartReldata($comp)->ReleaseTime();
+ my $enddate = $self->EndReldata($comp)->ReleaseTime();
+
+ # Specifically exclude the start and end reldatas... i.e use < > not <= >=
+ my @results = grep { $_->ReleaseTime() < $enddate and $_->ReleaseTime() > $startdate } @$relDataObjects;
+ return \@results;
+}
+
+sub GetStartEnv {
+ my $self = shift;
+ unless ($self->{results}->{startenv}) {
+ if ($self->{startcomp}) {
+ $self->{results}->{startenv} = $self->StartEnvReldata()->Environment();
+ } else {
+ $self->{results}->{startenv} = $self->CurrentEnv;
+ }
+ }
+ return $self->{results}->{startenv};
+}
+
+sub GetEndEnv {
+ my $self = shift;
+ unless ($self->{results}->{endenv}) {
+ if ($self->{endcomp}) {
+ $self->{results}->{endenv} = $self->EndEnvReldata()->Environment();
+ } else {
+ $self->{results}->{endenv} = $self->CurrentEnv;
+ }
+ }
+ return $self->{results}->{endenv};
+}
+
+### Private
+
+sub CurrentEnv {
+ my $self = shift;
+ my $envDb = EnvDb->Open($self->{iniData}, $self->{verbose});
+ return $envDb->VersionInfo();
+}
+
+sub DoDiff {
+ my $self = shift;
+
+ return if $self->{results}->{diff};
+
+ die "Neither environment was specified.\n" unless ($self->{startcomp} || $self->{endcomp});
+
+ my %env1 = %{$self->GetStartEnv()};
+ my %env2 = %{$self->GetEndEnv()};
+ # Deliberately make copies, as we will be deleting stuff from them
+
+ if ($self->{verbose}>1) {
+ print "Start environment is ".Dumper(\%env1)."\n";
+ print "End environment is ".Dumper(\%env2)."\n";
+ }
+
+ my @changed;
+ my @onlynew;
+ my @onlyold;
+ my @same;
+
+ # Compare $env1 against $env2 first.
+ foreach my $thisComp (keys %env1) {
+ my $ver1 = $env1{$thisComp};
+ my $ver2 = $env2{$thisComp};
+ if (not defined $ver2) {
+ push @onlyold, $thisComp;
+ }
+ elsif (lc($ver1) eq lc($ver2)) {
+ push @same, $thisComp;
+ }
+ else {
+ push @changed, $thisComp;
+ }
+
+ if (defined $ver2) {
+ # Remove this component from $env2 because it has been accounted for.
+ # Components left over in the $env2 hash are those not present in $env1.
+ delete $env2{$thisComp};
+ }
+ }
+
+ # List the components in $env2 but not in $env1.
+ @onlynew = keys %env2;
+
+ $self->{results}->{diff} = {
+ same => \@same,
+ onlyend => \@onlynew,
+ onlystart => \@onlyold,
+ changed => \@changed
+ };
+
+ print "At end of main comparison... with results ".Dumper($self->{results}->{diff})."\n" if $self->{verbose}>1;
+}
+
+sub CompareDiffDates {
+ my $self = shift;
+ return if $self->{results}->{diffdates};
+ $self->DoDiff; # returns if already completed
+
+ my @older;
+ my @newer;
+ foreach my $thisComp (@{$self->{results}->{diff}->{changed}}) {
+ my $relData1 = $self->StartReldata($thisComp);
+ my $relData2 = $self->EndReldata($thisComp);
+ if ($relData1->ReleaseTime() <= $relData2->ReleaseTime()) {
+ push @newer, $thisComp;
+ } else {
+ push @older, $thisComp;
+ }
+ }
+
+ $self->{results}->{diffdates} = {
+ older => \@older,
+ newer => \@newer
+ };
+ print "At end of date comparison... with results ".Dumper($self->{results}->{diffdates})."\n" if $self->{verbose}>1;
+}
+
+sub RelData {
+ my $self = shift;
+ my $comp = shift;
+ my $ver = shift;
+
+ print "Asked for reldata for $comp $ver\n" if $self->{verbose}>2;
+
+ die "Can't get reldata for undefined comp" unless $comp;
+ die "Can't get reldata for undefined version of $comp" unless $ver;
+
+ my $key = "$comp$ver";
+ unless ($self->{reldatacache}->{$key}) {
+ $self->{reldatacache}->{$key} = RelData->Open
+ ($self->{iniData}, $comp, $ver, $self->{verbose});
+ }
+ return $self->{reldatacache}->{$key};
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+EnvDifferencer.pm - A class to find differences between two environments.
+
+=head1 DESCRIPTION
+
+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.
+
+=head1 INTERFACE
+
+=head2 Necessary calls
+
+=head3 New
+
+Expects to be passed two arguments; firstly, an C<IniData> object, and secondly, a verbosity level.
+
+=head3 SetStartCompVer
+
+=head3 SetEndCompVer
+
+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.
+
+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.
+
+=head3 Reset
+
+This method should never be needed. It resets the object so that it performs a new diff the next time some information is requested.
+
+=head2 Accessor Methods
+
+Any of these may trigger a differencing to happen.
+
+=head3 StartReldata
+
+=head3 EndReldata
+
+Takes a component name. Returns a C<RelData> object corresponding to that component in the start or the end environment.
+
+=head3 StartVersion
+
+=head3 EndVersion
+
+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.
+
+=head3 GetStartEnv
+
+=head3 GetEndEnv
+
+Returns a hashref of the components and version numbers in each environment.
+
+=head3 StartEnvReldata
+
+=head3 EndEnvReldata
+
+Returns the C<RelData> object corresponding to the environment itself.
+
+=head3 ChangedComps
+
+Returns a list of component names in both environments, but with different version numbers.
+
+=head3 UnchangedComps
+
+Returns a similar list of those components which are identical in both environments.
+
+=head3 OnlyStart
+
+=head3 OnlyEnd
+
+Return lists of those components only in one or other environment.
+
+=head3 NewerComps
+
+=head3 OlderComps
+
+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.
+
+=head3 IntermediateReldatas
+
+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.
+
+=head1 KNOWN BUGS
+
+None.
+
+=head1 COPYRIGHT
+
+ Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ This component and the accompanying materials are made available
+ under the terms of the License "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ Nokia Corporation - initial contribution.
+
+ Contributors:
+
+ Description:
+
+
+=cut