From b6ca84cd6c5cdf63b42b202bdf7eb1cb2e019d70 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Tue, 21 Jul 2020 15:17:40 +0200 Subject: [PATCH] upgrade optional dependencies on plugin installation/upgrade --- .../scm/plugin/DefaultPluginManager.java | 39 ++++++++++++++----- .../scm/plugin/DefaultPluginManagerTest.java | 29 ++++++++++++++ .../scm/plugin/PluginCenterDtoMapperTest.java | 3 ++ 3 files changed, 61 insertions(+), 10 deletions(-) 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 ef1f4e6873..69fc876704 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java @@ -253,21 +253,40 @@ public class DefaultPluginManager implements PluginManager { private void collectPluginsToInstallOrUpdate(List plugins, String name) { if (!isInstalledOrPending(name) || isUpdatable(name)) { - AvailablePlugin plugin = getAvailable(name).orElseThrow(() -> NotFoundException.notFound(entity(AvailablePlugin.class, name))); - - Set dependencies = plugin.getDescriptor().getDependencies(); - if (dependencies != null) { - for (String dependency : dependencies) { - collectPluginsToInstallOrUpdate(plugins, dependency); - } - } - - plugins.add(plugin); + collectDependentPlugins(plugins, name); } else { LOG.info("plugin {} is already installed or installation is pending, skipping installation", name); } } + private void collectOptionalPluginToInstallOrUpdate(List plugins, String name) { + if (isInstalledOrPending(name) && isUpdatable(name)) { + collectDependentPlugins(plugins, name); + } else { + LOG.info("optional plugin {} is not installed or not updatable", name); + } + } + + private void collectDependentPlugins(List plugins, String name) { + AvailablePlugin plugin = getAvailable(name).orElseThrow(() -> NotFoundException.notFound(entity(AvailablePlugin.class, name))); + + Set dependencies = plugin.getDescriptor().getDependencies(); + if (dependencies != null) { + for (String dependency : dependencies) { + collectPluginsToInstallOrUpdate(plugins, dependency); + } + } + + Set optionalDependencies = plugin.getDescriptor().getOptionalDependencies(); + if (dependencies != null) { + for (String optionalDependency : optionalDependencies) { + collectOptionalPluginToInstallOrUpdate(plugins, optionalDependency); + } + } + + plugins.add(plugin); + } + private boolean isInstalledOrPending(String name) { return getInstalled(name).isPresent() || getPending(name).isPresent(); } 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 b1b1db9efe..b16d010c5d 100644 --- a/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java @@ -260,6 +260,35 @@ class DefaultPluginManagerTest { verify(installer).install(review); } + @Test + void shouldUpdateAlreadyInstalledOptionalDependenciesWhenNewerVersionIsAvailable() { + AvailablePlugin review = createAvailable("scm-review-plugin"); + when(review.getDescriptor().getOptionalDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin")); + AvailablePlugin mail = createAvailable("scm-mail-plugin", "1.1.0"); + when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail)); + + InstalledPlugin installedMail = createInstalled("scm-mail-plugin", "1.0.0"); + when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(installedMail)); + + manager.install("scm-review-plugin", false); + + verify(installer).install(mail); + verify(installer).install(review); + } + + @Test + void shouldNotUpdateOptionalDependenciesWhenNewerVersionIsAvailableButItIsNotInstalled() { + AvailablePlugin review = createAvailable("scm-review-plugin"); + when(review.getDescriptor().getOptionalDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin")); + AvailablePlugin mail = createAvailable("scm-mail-plugin", "1.1.0"); + when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail)); + + manager.install("scm-review-plugin", false); + + verify(installer, never()).install(mail); + verify(installer).install(review); + } + @Test void shouldRollbackOnFailedInstallation() { AvailablePlugin review = createAvailable("scm-review-plugin"); diff --git a/scm-webapp/src/test/java/sonia/scm/plugin/PluginCenterDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/plugin/PluginCenterDtoMapperTest.java index 42ecf64da4..96ceccfb54 100644 --- a/scm-webapp/src/test/java/sonia/scm/plugin/PluginCenterDtoMapperTest.java +++ b/scm-webapp/src/test/java/sonia/scm/plugin/PluginCenterDtoMapperTest.java @@ -67,6 +67,7 @@ class PluginCenterDtoMapperTest { "555000444", new Condition(Collections.singletonList("linux"), "amd64","2.0.0"), ImmutableSet.of("scm-review-plugin"), + ImmutableSet.of(), ImmutableMap.of("download", new Link("http://download.hitchhiker.com")) ); @@ -101,6 +102,7 @@ class PluginCenterDtoMapperTest { "12345678aa", new Condition(Collections.singletonList("linux"), "amd64","2.0.0"), ImmutableSet.of("scm-review-plugin"), + ImmutableSet.of(), ImmutableMap.of("download", new Link("http://download.hitchhiker.com/review")) ); @@ -115,6 +117,7 @@ class PluginCenterDtoMapperTest { "555000444", new Condition(Collections.singletonList("linux"), "amd64","2.0.0"), ImmutableSet.of("scm-review-plugin"), + ImmutableSet.of(), ImmutableMap.of("download", new Link("http://download.hitchhiker.com/hitchhiker")) );