mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-13 00:45:44 +01:00
Append uninstall links
This commit is contained in:
@@ -135,7 +135,14 @@ public final class InstalledPlugin implements Plugin
|
|||||||
this.markedForUninstall = markedForUninstall;
|
this.markedForUninstall = markedForUninstall;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
public boolean isUninstallable() {
|
||||||
|
return uninstallable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUninstallable(boolean uninstallable) {
|
||||||
|
this.uninstallable = uninstallable;
|
||||||
|
}
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
/** plugin class loader */
|
/** plugin class loader */
|
||||||
private final ClassLoader classLoader;
|
private final ClassLoader classLoader;
|
||||||
@@ -151,5 +158,6 @@ public final class InstalledPlugin implements Plugin
|
|||||||
|
|
||||||
private final boolean core;
|
private final boolean core;
|
||||||
|
|
||||||
private boolean markedForUninstall;
|
private boolean markedForUninstall = false;
|
||||||
|
private boolean uninstallable = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,10 +74,9 @@ public abstract class PluginDtoMapper {
|
|||||||
) {
|
) {
|
||||||
links.single(link("update", resourceLinks.availablePlugin().install(information.getName())));
|
links.single(link("update", resourceLinks.availablePlugin().install(information.getName())));
|
||||||
}
|
}
|
||||||
if (!plugin.isCore()
|
if (plugin.isUninstallable()
|
||||||
&& (!availablePlugin.isPresent() || !availablePlugin.get().isPending())
|
&& (!availablePlugin.isPresent() || !availablePlugin.get().isPending())
|
||||||
&& PluginPermissions.manage().isPermitted()
|
&& PluginPermissions.manage().isPermitted()
|
||||||
// TODO check if plugin is no dependency of another plugin
|
|
||||||
) {
|
) {
|
||||||
links.single(link("uninstall", resourceLinks.installedPlugin().uninstall(information.getName())));
|
links.single(link("uninstall", resourceLinks.installedPlugin().uninstall(information.getName())));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,15 +82,16 @@ public class DefaultPluginManager implements PluginManager {
|
|||||||
this.center = center;
|
this.center = center;
|
||||||
this.installer = installer;
|
this.installer = installer;
|
||||||
|
|
||||||
this.computeRequiredPlugins();
|
this.computeInstallationDependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
synchronized void computeRequiredPlugins() {
|
synchronized void computeInstallationDependencies() {
|
||||||
loader.getInstalledPlugins()
|
loader.getInstalledPlugins()
|
||||||
.stream()
|
.stream()
|
||||||
.map(InstalledPlugin::getDescriptor)
|
.map(InstalledPlugin::getDescriptor)
|
||||||
.forEach(dependencyTracker::addInstalled);
|
.forEach(dependencyTracker::addInstalled);
|
||||||
|
updateMayUninstallFlag();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -166,6 +167,7 @@ public class DefaultPluginManager implements PluginManager {
|
|||||||
for (AvailablePlugin plugin : plugins) {
|
for (AvailablePlugin plugin : plugins) {
|
||||||
try {
|
try {
|
||||||
PendingPluginInstallation pending = installer.install(plugin);
|
PendingPluginInstallation pending = installer.install(plugin);
|
||||||
|
dependencyTracker.addInstalled(plugin.getDescriptor());
|
||||||
pendingInstallations.add(pending);
|
pendingInstallations.add(pending);
|
||||||
} catch (PluginInstallException ex) {
|
} catch (PluginInstallException ex) {
|
||||||
cancelPending(pendingInstallations);
|
cancelPending(pendingInstallations);
|
||||||
@@ -178,6 +180,7 @@ public class DefaultPluginManager implements PluginManager {
|
|||||||
restart("plugin installation");
|
restart("plugin installation");
|
||||||
} else {
|
} else {
|
||||||
pendingQueue.addAll(pendingInstallations);
|
pendingQueue.addAll(pendingInstallations);
|
||||||
|
updateMayUninstallFlag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,6 +200,23 @@ public class DefaultPluginManager implements PluginManager {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new PluginException("could not mark plugin " + name + " in path " + installed.getDirectory() + " for uninstall", e);
|
throw new PluginException("could not mark plugin " + name + " in path " + installed.getDirectory() + " for uninstall", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (restartAfterInstallation) {
|
||||||
|
restart("plugin installation");
|
||||||
|
} else {
|
||||||
|
updateMayUninstallFlag();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateMayUninstallFlag() {
|
||||||
|
loader.getInstalledPlugins()
|
||||||
|
.forEach(p -> p.setUninstallable(isUninstallable(p)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isUninstallable(InstalledPlugin p) {
|
||||||
|
return !p.isCore()
|
||||||
|
&& !p.isMarkedForUninstall()
|
||||||
|
&& dependencyTracker.mayUninstall(p.getDescriptor().getInformation().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -127,4 +127,15 @@ class PluginDtoMapperTest {
|
|||||||
PluginDto dto = mapper.mapAvailable(plugin);
|
PluginDto dto = mapper.mapAvailable(plugin);
|
||||||
assertThat(dto.getDependencies()).containsOnly("one", "two");
|
assertThat(dto.getDependencies()).containsOnly("one", "two");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldAppendUninstallLink() {
|
||||||
|
when(subject.isPermitted("plugin:manage")).thenReturn(true);
|
||||||
|
InstalledPlugin plugin = createInstalled(createPluginInformation());
|
||||||
|
when(plugin.isUninstallable()).thenReturn(true);
|
||||||
|
|
||||||
|
PluginDto dto = mapper.mapInstalled(plugin, emptyList());
|
||||||
|
assertThat(dto.getLinks().getLinkBy("uninstall").get().getHref())
|
||||||
|
.isEqualTo("https://hitchhiker.com/v2/plugins/installed/scm-cas-plugin/uninstall");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.nio.file.Path;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
import static java.util.Collections.singleton;
|
import static java.util.Collections.singleton;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@@ -328,7 +329,7 @@ class DefaultPluginManagerTest {
|
|||||||
when(reviewPlugin.getDescriptor().getDependencies()).thenReturn(singleton("scm-mail-plugin"));
|
when(reviewPlugin.getDescriptor().getDependencies()).thenReturn(singleton("scm-mail-plugin"));
|
||||||
|
|
||||||
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(mailPlugin, reviewPlugin));
|
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(mailPlugin, reviewPlugin));
|
||||||
manager.computeRequiredPlugins();
|
manager.computeInstallationDependencies();
|
||||||
|
|
||||||
assertThrows(ScmConstraintViolationException.class, () -> manager.uninstall("scm-mail-plugin", false));
|
assertThrows(ScmConstraintViolationException.class, () -> manager.uninstall("scm-mail-plugin", false));
|
||||||
}
|
}
|
||||||
@@ -369,6 +370,51 @@ class DefaultPluginManagerTest {
|
|||||||
|
|
||||||
assertThat(temp.resolve("uninstall")).doesNotExist();
|
assertThat(temp.resolve("uninstall")).doesNotExist();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldMarkUninstallablePlugins() {
|
||||||
|
InstalledPlugin mailPlugin = createInstalled("scm-mail-plugin");
|
||||||
|
InstalledPlugin reviewPlugin = createInstalled("scm-review-plugin");
|
||||||
|
when(reviewPlugin.getDescriptor().getDependencies()).thenReturn(singleton("scm-mail-plugin"));
|
||||||
|
|
||||||
|
when(loader.getInstalledPlugins()).thenReturn(asList(mailPlugin, reviewPlugin));
|
||||||
|
|
||||||
|
manager.computeInstallationDependencies();
|
||||||
|
|
||||||
|
verify(reviewPlugin).setUninstallable(true);
|
||||||
|
verify(mailPlugin).setUninstallable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldUpdateMayUninstallFlagAfterDependencyIsUninstalled() {
|
||||||
|
InstalledPlugin mailPlugin = createInstalled("scm-mail-plugin");
|
||||||
|
InstalledPlugin reviewPlugin = createInstalled("scm-review-plugin");
|
||||||
|
when(reviewPlugin.getDescriptor().getDependencies()).thenReturn(singleton("scm-mail-plugin"));
|
||||||
|
|
||||||
|
when(loader.getInstalledPlugins()).thenReturn(asList(mailPlugin, reviewPlugin));
|
||||||
|
|
||||||
|
manager.computeInstallationDependencies();
|
||||||
|
|
||||||
|
manager.uninstall("scm-review-plugin", false);
|
||||||
|
|
||||||
|
verify(mailPlugin).setUninstallable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldUpdateMayUninstallFlagAfterDependencyIsInstalled() {
|
||||||
|
InstalledPlugin mailPlugin = createInstalled("scm-mail-plugin");
|
||||||
|
AvailablePlugin reviewPlugin = createAvailable("scm-review-plugin");
|
||||||
|
when(reviewPlugin.getDescriptor().getDependencies()).thenReturn(singleton("scm-mail-plugin"));
|
||||||
|
|
||||||
|
when(loader.getInstalledPlugins()).thenReturn(singletonList(mailPlugin));
|
||||||
|
when(center.getAvailable()).thenReturn(singleton(reviewPlugin));
|
||||||
|
|
||||||
|
manager.computeInstallationDependencies();
|
||||||
|
|
||||||
|
manager.install("scm-review-plugin", false);
|
||||||
|
|
||||||
|
verify(mailPlugin).setUninstallable(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
Reference in New Issue
Block a user