Priority: Urgent
Current State: Closed
Released In: 1.1.10
Target Release: patch
Applies To: Engine
Component: Configure
Branches: master Release01x01
If an extension is updated because it's called out as a dependency, and the user also used the install checkbox to update the extension, it's installed multiple times.
For example,
ImagePlugin requires
JQueryPlugin, So the user who notices that both
ImagePlugin and
JQueryPlugin are backlevel and checks off both of the plugins in the FindMoreExtensions dialog, then
JQueryPlugin will be installed twice, as a dependency of
ImagePlugin and due to the UI Request.
--
GeorgeClark - 16 Jul 2012
Defer to 1.2. This issue has been around for a while now.
--
GeorgeClark - 02 Nov 2012
Note that this also results in an installer loop if two extensions are cross-dependent upon each other.
Fixed on 1.2, patch below for 1.1.9.
diff --git a/core/lib/Foswiki/Configure/Package.pm b/core/lib/Foswiki/Configure/Package.pm
index 0f63d04..5c4e614 100644
--- a/core/lib/Foswiki/Configure/Package.pm
+++ b/core/lib/Foswiki/Configure/Package.pm
@@ -71,6 +71,7 @@ Required for installer methods - used for checkin operations
(CPAN and external dependencies are not handled by this module.)
SIMULATE => 0/1 Set to 1 if actions should be simulated - no file system modifications other than temporary files.
CONTINUE => 0/1 If set to 1, the installation will continue even if errors are encountered. (future)
+ seen => \%seen Has of modules already seen, to be installed
}
=cut
@@ -79,6 +80,10 @@ sub new {
my ( $class, $root, $pkgname, $session, $options ) = @_;
my @deps;
+ my $seen = $options->{seen} || {};
+ $seen->{$pkgname} = 1;
+ $options->{seen} = $seen;
+
my $this = bless(
{
_root => $root,
@@ -98,6 +103,7 @@ sub new {
_logfile => undef, # Log filename for results of requested action
_messages =>
undef, # Messages returned to caller from requested action
+ _seen => $seen,
},
$class
);
@@ -129,6 +135,7 @@ sub finish {
undef $this->{_errors};
undef $this->{_logfile};
undef $this->{_messages};
+ undef $this->{_messages};
for (qw( preinstall postinstall preuninstall postuninstall )) {
undef &{$_};
@@ -1517,6 +1524,10 @@ sub installDependencies {
foreach my $dep ( @{ $this->checkDependencies('wiki') } ) {
my ( $ok, $msg ) = $dep->check();
unless ($ok) {
+ if ( $this->{_seen}{$dep->{name}} ) {
+ $rslt .= "Skipping duplicate package $dep->{name}\n";
+ next;
+ }
my $deppkg = new Foswiki::Configure::Package(
$this->{_root}, $dep->{name},
$this->{_session}, $this->{_options}
diff --git a/core/lib/Foswiki/Configure/UIs/EXTEND.pm b/core/lib/Foswiki/Configure/UIs/EXTEND.pm
index 9c56c75..81510ea 100755
--- a/core/lib/Foswiki/Configure/UIs/EXTEND.pm
+++ b/core/lib/Foswiki/Configure/UIs/EXTEND.pm
@@ -41,6 +41,7 @@ the caller early feedback.
sub install {
my $this = shift;
my $query = $Foswiki::query;
+ my $seen = {};
# The safest directory to use for the foswiki root is probably DataDir.
# bin is possibly relocated to a cgi-bin, and pub might be in a webroot.
@@ -91,7 +92,7 @@ sub install {
my $extensionName = $2;
print "Bad extension name" unless $extensionName && $repositoryPath;
- $this->_install( $repositoryPath, $extensionName, $processExt );
+ $this->_install( $repositoryPath, $extensionName, $processExt, $seen );
}
}
@@ -160,7 +161,7 @@ sub _depreport {
}
sub _install {
- my ( $this, $repositoryPath, $extension, $processExt ) = @_;
+ my ( $this, $repositoryPath, $extension, $processExt, $seen ) = @_;
my $err;
my $feedback = '';
@@ -190,6 +191,7 @@ sub _install {
{
SIMULATE => $simulate,
NODEPS => $nodeps,
+ seen => $seen,
}
);