diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 7aaeb2ef88..75335de611 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -13,6 +13,7 @@ Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/issues/2039[#2039]: IDE logo not shown in mac task bar * https://github.com/devonfw/IDEasy/issues/2176[#2176]: Support 7z archive extraction * https://github.com/devonfw/IDEasy/issues/2100[#2100]: Fix Python not available for Mac x64 +* https://github.com/devonfw/IDEasy/issues/2188[#2188]: Fix Spyder commandlet starts spyder in foreground * https://github.com/devonfw/IDEasy/issues/2224[#2224]: Brew upgrade ideasy not working * https://github.com/devonfw/IDEasy/issues/1784[#1784]: GUI now supports displaying progress bars * https://github.com/devonfw/IDEasy/issues/1917[#1917]: Allow the creation of a desktop shortcut for the GUI diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/pip/PipBasedIdeToolCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/pip/PipBasedIdeToolCommandlet.java new file mode 100644 index 0000000000..30c8be9a3a --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/pip/PipBasedIdeToolCommandlet.java @@ -0,0 +1,31 @@ +package com.devonfw.tools.ide.tool.pip; + +import java.util.List; +import java.util.Set; + +import com.devonfw.tools.ide.common.Tag; +import com.devonfw.tools.ide.context.IdeContext; +import com.devonfw.tools.ide.process.ProcessMode; +import com.devonfw.tools.ide.process.ProcessResult; + +/** + * Base class for pip-based IDE tools that should launch in the background instead of blocking the terminal. + */ +public abstract class PipBasedIdeToolCommandlet extends PipBasedCommandlet { + + /** + * The constructor. + * + * @param context the {@link IdeContext}. + * @param tool the {@link #getName() tool name}. + * @param tags the {@link #getTags() tags} classifying the tool. + */ + public PipBasedIdeToolCommandlet(IdeContext context, String tool, Set tags) { + super(context, tool, tags); + } + + @Override + public ProcessResult runTool(List args) { + return runTool(ProcessMode.BACKGROUND, null, args); + } +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/spyder/Spyder.java b/cli/src/main/java/com/devonfw/tools/ide/tool/spyder/Spyder.java index 43edfec117..2a27df1c72 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/spyder/Spyder.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/spyder/Spyder.java @@ -4,14 +4,17 @@ import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.tool.ToolCommandlet; -import com.devonfw.tools.ide.tool.pip.Pip; -import com.devonfw.tools.ide.tool.pip.PipBasedCommandlet; +import com.devonfw.tools.ide.process.EnvironmentContext; +import com.devonfw.tools.ide.tool.ToolInstallation; +import com.devonfw.tools.ide.tool.pip.PipBasedIdeToolCommandlet; /** - * {@link PipBasedCommandlet} for Spyder. + * {@link PipBasedIdeToolCommandlet} for Spyder. */ -public class Spyder extends PipBasedCommandlet { +public class Spyder extends PipBasedIdeToolCommandlet { + + /** Environment variable that tells Spyder to use an IDEasy-managed config directory instead of the shared user config. */ + private static final String SPYDER_CONFIG_DIR = "SPYDER_CONFIG_DIR"; /** * The constructor. @@ -22,5 +25,13 @@ public Spyder(IdeContext context) { super(context, "spyder", Set.of(Tag.SPYDER)); } + @Override + public void setEnvironment(EnvironmentContext environmentContext, ToolInstallation toolInstallation, boolean additionalInstallation) { + super.setEnvironment(environmentContext, toolInstallation, additionalInstallation); + // Point Spyder to an IDEasy-managed config directory so its settings stay isolated per IDE_HOME. + if (this.context.getConfPath() != null) { + environmentContext.withEnvVar(SPYDER_CONFIG_DIR, this.context.getConfPath().resolve("spyder").toString()); + } + } } diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/spyder/SpyderTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/spyder/SpyderTest.java index 2b64e9760d..1c9326d282 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/spyder/SpyderTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/spyder/SpyderTest.java @@ -1,11 +1,17 @@ package com.devonfw.tools.ide.tool.spyder; +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.os.SystemInfoMock; +import com.devonfw.tools.ide.tool.ToolInstallation; +import com.devonfw.tools.ide.tool.claude.RecordingEnvironmentContext; import com.devonfw.tools.ide.tool.pip.PipBasedCommandlet; +import com.devonfw.tools.ide.tool.pip.PipBasedIdeToolCommandlet; +import com.devonfw.tools.ide.version.VersionIdentifier; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; import com.github.tomakehurst.wiremock.junit5.WireMockTest; @@ -43,7 +49,7 @@ void testSpyderInstall(WireMockRuntimeInfo wireMockRuntimeInfo) { * @param wireMockRuntimeInfo wireMock server on a random port */ @Test - void testSpyderIsPipBasedCommandlet(WireMockRuntimeInfo wireMockRuntimeInfo) { + void testSpyderIsPipBasedIdeToolCommandlet(WireMockRuntimeInfo wireMockRuntimeInfo) { // arrange IdeTestContext context = newContext(PROJECT_PIP, wireMockRuntimeInfo); @@ -53,6 +59,23 @@ void testSpyderIsPipBasedCommandlet(WireMockRuntimeInfo wireMockRuntimeInfo) { Spyder commandlet = new Spyder(context); // assert - assertThat(commandlet).isInstanceOf(PipBasedCommandlet.class); + assertThat(commandlet).isInstanceOf(PipBasedIdeToolCommandlet.class); + } + + @Test + void testSpyderSetEnvironmentUsesIsolatedConfigDir() { + + // arrange + IdeTestContext context = newContext(PROJECT_PIP); + Spyder commandlet = new Spyder(context); + Path rootDir = context.getSoftwarePath().resolve("spyder"); + ToolInstallation installation = new ToolInstallation(rootDir, rootDir, rootDir.resolve("bin"), VersionIdentifier.of("1.0.0"), false); + RecordingEnvironmentContext environmentContext = new RecordingEnvironmentContext(); + + // act + commandlet.setEnvironment(environmentContext, installation, false); + + // assert + assertThat(environmentContext.set).containsEntry("SPYDER_CONFIG_DIR", context.getConfPath().resolve("spyder").toString()); } }