From 8db2e76ecc0d384417477a1bf621d2b4fdc4d438 Mon Sep 17 00:00:00 2001 From: Eduard Heimbuch Date: Thu, 20 Oct 2022 20:38:58 +0200 Subject: [PATCH] Resolve plugin installation conflict were the same plugin was tried to be installed multiple times for one single action. (#2138) The pending queue is updated after all the plugins to be installed are collected, and then we already may have duplicate entries. Because of this we check right on the collecting step if the plugin was already added during this single action. --- .../plugin_installation_conflict.yaml | 2 ++ .../sonia/scm/plugin/DefaultPluginManager.java | 8 +++++++- .../scm/plugin/DefaultPluginManagerTest.java | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 gradle/changelog/plugin_installation_conflict.yaml diff --git a/gradle/changelog/plugin_installation_conflict.yaml b/gradle/changelog/plugin_installation_conflict.yaml new file mode 100644 index 0000000000..a06f0eedec --- /dev/null +++ b/gradle/changelog/plugin_installation_conflict.yaml @@ -0,0 +1,2 @@ +- type: fixed + description: Plugin installation conflict ([#2138](https://github.com/scm-manager/scm-manager/pull/2138)) diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java b/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java index 256f73eb9a..fd47cf5fdf 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java @@ -357,7 +357,13 @@ public class DefaultPluginManager implements PluginManager { } } - plugins.add(plugin); + if (pluginWasNotAddedYet(plugins, plugin)) { + plugins.add(plugin); + } + } + + private static boolean pluginWasNotAddedYet(List plugins, AvailablePlugin plugin) { + return plugins.stream().noneMatch(p -> p.getDescriptor().getInformation().getName().equals(plugin.getDescriptor().getInformation().getName())); } private boolean isInstalledOrPending(String name) { diff --git a/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java b/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java index 74ec7a0d14..698e2cfd40 100644 --- a/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java @@ -242,6 +242,24 @@ class DefaultPluginManagerTest { verify(installer).install(context, review); } + @Test + void shouldInstallMultipleSameDependingPluginsOnlyOnce() { + AvailablePlugin review = createAvailable("scm-review-plugin"); + AvailablePlugin ci = createAvailable("scm-ci-plugin", "1.1.0"); + InstalledPlugin oldCi = createInstalled("scm-ci-plugin", "1.0.0"); + when(review.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin", "scm-ci-plugin")); + AvailablePlugin mail = createAvailable("scm-mail-plugin"); + when(mail.getDescriptor().getOptionalDependencies()).thenReturn(ImmutableSet.of("scm-ci-plugin")); + when(center.getAvailablePlugins()).thenReturn(ImmutableSet.of(review, mail, ci)); + when(loader.getInstalledPlugins()).thenReturn(ImmutableSet.of(oldCi)); + + manager.install("scm-review-plugin", false); + + verify(installer).install(context, mail); + verify(installer).install(context, review); + verify(installer, times(1)).install(context, ci); + } + @Test void shouldNotInstallAlreadyInstalledDependenciesWhenUpToDate() { AvailablePlugin review = createAvailable("scm-review-plugin");