From 661ea6ad052eb80b768f5ca28338faf3feaa533f Mon Sep 17 00:00:00 2001 From: ndemirca <157051033+ndemirca@users.noreply.github.com> Date: Mon, 15 Apr 2024 11:00:43 +0200 Subject: [PATCH] #206: Implemented UninstallCommandlet (#258) --- .../ide/commandlet/CommandletManagerImpl.java | 15 ++-- .../ide/commandlet/UninstallCommandlet.java | 53 +++++++++++++ .../commandlet/UninstallCommandletTest.java | 77 +++++++++++++++++++ .../ide/context/AbstractIdeTestContext.java | 21 +++-- .../basic/project/software/npm/bin/readme | 1 + 5 files changed, 155 insertions(+), 12 deletions(-) create mode 100644 cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java create mode 100644 cli/src/test/java/com/devonfw/tools/ide/commandlet/UninstallCommandletTest.java create mode 100644 cli/src/test/resources/ide-projects/basic/project/software/npm/bin/readme diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java index 17b02a0a1..ef80dbaea 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java @@ -1,11 +1,5 @@ package com.devonfw.tools.ide.commandlet; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.property.KeywordProperty; import com.devonfw.tools.ide.property.Property; @@ -18,6 +12,7 @@ import com.devonfw.tools.ide.tool.gh.Gh; import com.devonfw.tools.ide.tool.gradle.Gradle; import com.devonfw.tools.ide.tool.helm.Helm; +import com.devonfw.tools.ide.tool.jasypt.Jasypt; import com.devonfw.tools.ide.tool.java.Java; import com.devonfw.tools.ide.tool.jmc.Jmc; import com.devonfw.tools.ide.tool.kotlinc.Kotlinc; @@ -30,7 +25,12 @@ import com.devonfw.tools.ide.tool.sonar.Sonar; import com.devonfw.tools.ide.tool.terraform.Terraform; import com.devonfw.tools.ide.tool.vscode.Vscode; -import com.devonfw.tools.ide.tool.jasypt.Jasypt; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Implementation of {@link CommandletManager}. @@ -70,6 +70,7 @@ public CommandletManagerImpl(IdeContext context) { add(new EditionListCommandlet(context)); add(new VersionCommandlet(context)); add(new RepositoryCommandlet(context)); + add(new UninstallCommandlet(context)); add(new UpdateCommandlet(context)); add(new CreateCommandlet(context)); add(new Gh(context)); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java new file mode 100644 index 000000000..10eecea34 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java @@ -0,0 +1,53 @@ +package com.devonfw.tools.ide.commandlet; + +import java.nio.file.Files; +import java.nio.file.Path; + +import com.devonfw.tools.ide.context.IdeContext; +import com.devonfw.tools.ide.io.FileAccess; +import com.devonfw.tools.ide.property.ToolProperty; + +/** + * An internal {@link Commandlet} to uninstall a tool. + */ +public class UninstallCommandlet extends Commandlet { + + /** The tool to uninstall. */ + public final ToolProperty tool; + + /** + * The constructor. + * + * @param context the {@link IdeContext}. + */ + public UninstallCommandlet(IdeContext context) { + + super(context); + addKeyword(getName()); + this.tool = add(new ToolProperty("", true, "tool")); + } + + @Override + public String getName() { + + return "uninstall"; + } + + @Override + public void run() { + + String commandletName = this.tool.getValue().getName(); + Path softwarePath = context.getSoftwarePath().resolve(commandletName); + if (Files.exists(softwarePath)) { + FileAccess fileAccess = context.getFileAccess(); + try { + fileAccess.delete(softwarePath); + this.context.success("Successfully uninstalled " + commandletName); + } catch (Exception e) { + throw new IllegalStateException("Couldn't uninstall " + commandletName, e); + } + } else { + this.context.info("An installed version of " + commandletName + " does not exist"); + } + } +} diff --git a/cli/src/test/java/com/devonfw/tools/ide/commandlet/UninstallCommandletTest.java b/cli/src/test/java/com/devonfw/tools/ide/commandlet/UninstallCommandletTest.java new file mode 100644 index 000000000..82808a81b --- /dev/null +++ b/cli/src/test/java/com/devonfw/tools/ide/commandlet/UninstallCommandletTest.java @@ -0,0 +1,77 @@ +package com.devonfw.tools.ide.commandlet; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; + +import java.nio.file.Files; +import java.nio.file.Path; + +import org.junit.jupiter.api.Test; + +import com.devonfw.tools.ide.context.AbstractIdeContextTest; +import com.devonfw.tools.ide.context.IdeTestContext; +import com.devonfw.tools.ide.io.FileAccess; +import com.devonfw.tools.ide.log.IdeLogLevel; + +/** + * Integration test of {@link UninstallCommandlet}. + */ +public class UninstallCommandletTest extends AbstractIdeContextTest { + + /** + * Test of {@link UninstallCommandlet} run. + * + */ + @Test + public void testUninstallCommandletRun_WithExistingCommandlet() { + + // arrange + String toolName = "npm"; + IdeTestContext context = newContext(PROJECT_BASIC); + UninstallCommandlet uninstallCommandlet = context.getCommandletManager().getCommandlet(UninstallCommandlet.class); + uninstallCommandlet.tool.setValueAsString(toolName, context); + // act + uninstallCommandlet.run(); + // assert + assertLogMessage(context, IdeLogLevel.SUCCESS, "Successfully uninstalled " + toolName); + assertThat(Files.notExists(context.getSoftwarePath().resolve(toolName))); + } + + @Test + public void testUninstallCommandletRun_WithNonExistingCommandlet() { + + // arrange + String toolName = "eclipse"; + IdeTestContext context = newContext(PROJECT_BASIC); + UninstallCommandlet uninstallCommandlet = context.getCommandletManager().getCommandlet(UninstallCommandlet.class); + uninstallCommandlet.tool.setValueAsString(toolName, context); + // act + uninstallCommandlet.run(); + // assert + assertLogMessage(context, IdeLogLevel.INFO, "An installed version of " + toolName + " does not exist"); + assertThat(Files.notExists(context.getSoftwarePath().resolve(toolName))); + } + + @Test + public void testUninstallCommandletRun_ThrowsException() { + + // arrange + String toolName = "npm"; + IdeTestContext context = newContext(PROJECT_BASIC); + + FileAccess mockFileAccess = mock(FileAccess.class); + doThrow(new IllegalStateException()).when(mockFileAccess).delete(any(Path.class)); + context.setMockFileAccess(mockFileAccess); + + UninstallCommandlet uninstallCommandlet = context.getCommandletManager().getCommandlet(UninstallCommandlet.class); + uninstallCommandlet.tool.setValueAsString(toolName, context); + // act + try { + uninstallCommandlet.run(); + } catch (IllegalStateException e) { + // assert + assertThat(e).hasMessageContaining("Couldn't uninstall " + toolName); + } + } +} diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java index 0cfa42719..8e0f6624c 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java @@ -1,5 +1,11 @@ package com.devonfw.tools.ide.context; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +import com.devonfw.tools.ide.io.FileAccess; import com.devonfw.tools.ide.io.IdeProgressBar; import com.devonfw.tools.ide.io.IdeProgressBarTestImpl; import com.devonfw.tools.ide.log.IdeLogLevel; @@ -8,11 +14,6 @@ import com.devonfw.tools.ide.repo.DefaultToolRepository; import com.devonfw.tools.ide.repo.ToolRepository; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; - /** * Implementation of {@link IdeContext} for testing. */ @@ -26,6 +27,8 @@ public class AbstractIdeTestContext extends AbstractIdeContext { private SystemInfo systemInfo; + private FileAccess mockFileAccess; + /** * The constructor. * @@ -93,4 +96,12 @@ public void setSystemInfo(SystemInfo systemInfo) { this.systemInfo = systemInfo; } + + + /** + * @param fileAccess the {@link FileAccess} to use for testing. + */ + public void setMockFileAccess(FileAccess fileAccess){ + this.mockFileAccess = fileAccess; + } } diff --git a/cli/src/test/resources/ide-projects/basic/project/software/npm/bin/readme b/cli/src/test/resources/ide-projects/basic/project/software/npm/bin/readme new file mode 100644 index 000000000..ed366f6d3 --- /dev/null +++ b/cli/src/test/resources/ide-projects/basic/project/software/npm/bin/readme @@ -0,0 +1 @@ +this is npm software of basic \ No newline at end of file