diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 918ac0f87..5a01c9642 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -4,6 +4,8 @@ This file documents all notable changes to https://github.com/devonfw/IDEasy[IDE == 2026.07.002 +* https://github.com/devonfw/IDEasy/issues/2102[#2102]: Make context.getIdeRoot() consistent during initial install + Release with new features and bugfixes: diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index dac769796..fbd560518 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -111,7 +111,7 @@ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatt private Path ideHome; - private final Path ideRoot; + private Path ideRoot; private Path confPath; @@ -587,6 +587,12 @@ public Path getIdeRoot() { return this.ideRoot; } + @Override + public void setIdeRoot(Path ideRoot) { + + this.ideRoot = ideRoot; + } + @Override public Path getIdePath() { diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java index e8279c717..c058b7373 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java @@ -51,7 +51,7 @@ *
  • {@link #getGitContext() git context} (for git operations like clone, fetch, pull, etc.)
  • *
  • {@link #getSystemInfo() system info} (for information about OS and CPU architecture)
  • *
  • {@link #getVariables() environment variables} (to access and modify IDEasy variables according to our configuration layout)
  • - * + * *
  • {@link #question(Object[], String, Object...) question} (for interaction to let the end-user decide)
  • *
  • {@link #getUrls() url metadata} (access ide-urls to find versions, download URLs, dependency and security metadata)
  • *
  • {@link #getDefaultToolRepository() tool repository} (for abstraction of version resolution and download of tools)
  • @@ -409,6 +409,13 @@ default void requireOnline(String purpose, boolean explicitOnlineCheck) { */ Path getIdeRoot(); + /** + * @param ideRoot the new value of {@link #getIdeRoot() IDE_ROOT}. Typically detected automatically from the environment and working directory, but may need + * to be set explicitly (e.g. during the initial installation where the {@code IDE_ROOT} environment variable is not yet available but the install target + * is already known). + */ + void setIdeRoot(Path ideRoot); + /** * @return the {@link Path} to the {@link #FOLDER_UNDERSCORE_IDE}. * @see #getIdeRoot() diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/IdeasyCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/IdeasyCommandlet.java index a762cd2c2..7f0683425 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/IdeasyCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/IdeasyCommandlet.java @@ -266,6 +266,9 @@ private boolean isSameSnapshotVersion(String installed, String latest) { */ public void installIdeasy(Path cwd) { Path ideRoot = determineIdeRoot(cwd); + // During a fresh (MSI) installation the IDE_ROOT environment variable is not yet available, so context.getIdeRoot() would return null for the whole run. + // The install target is already known here, so we make the context consistent for any downstream code reading context.getIdeRoot() (see #1517). + this.context.setIdeRoot(ideRoot); Path idePath = ideRoot.resolve(IdeContext.FOLDER_UNDERSCORE_IDE); Path installationPath = idePath.resolve(IdeContext.FOLDER_INSTALLATION); Path ideasySoftwarePath = idePath.resolve(IdeContext.FOLDER_SOFTWARE).resolve(MvnRepository.ID).resolve(IdeasyCommandlet.TOOL_NAME) 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 84022d2a0..5928b3b55 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 @@ -55,10 +55,6 @@ public class AbstractIdeTestContext extends AbstractIdeContext { private TestCommandletManager testCommandletManager; - private Path ideRoot; - - private boolean ideRootSet; - private Path urlsPath; protected final WireMockRuntimeInfo wireMockRuntimeInfo; @@ -299,24 +295,6 @@ public void setUserHome(Path dummyUserHome) { super.setUserHome(dummyUserHome); } - @Override - public Path getIdeRoot() { - - if (this.ideRootSet) { - return this.ideRoot; - } - return super.getIdeRoot(); - } - - /** - * @param ideRoot the new value of {@link #getIdeRoot()}. - */ - public void setIdeRoot(Path ideRoot) { - - this.ideRoot = ideRoot; - this.ideRootSet = true; - } - @Override public Path getUrlsPath() { diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/IdeasyCommandletTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/IdeasyCommandletTest.java index 945e7fc19..487dcefab 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/IdeasyCommandletTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/IdeasyCommandletTest.java @@ -114,6 +114,35 @@ void testInstallIdeasy(String os) { + addedRcLines); } + /** + * Test that {@link IdeasyCommandlet#installIdeasy(Path)} updates {@link IdeContext#getIdeRoot()} to the derived install target when {@code IDE_ROOT} is not + * set in the environment (as is the case during a fresh MSI installation). This ensures downstream code reading {@link IdeContext#getIdeRoot()} during the + * same install run gets a consistent value. See #1517 for reference. + * + * @param os to use + */ + @ParameterizedTest + @ValueSource(strings = { "windows", "mac", "linux" }) + void testInstallIdeasyUpdatesIdeRoot(String os) { + + // arrange + SystemInfo systemInfo = SystemInfoMock.of(os); + IdeTestContext context = newContext("install"); + context.setIdeRoot(null); + context.setSystemInfo(systemInfo); + context.getStartContext().setForceMode(true); + Path gitconfigPath = context.getUserHome().resolve(".gitconfig"); + FileAccess fileAccess = new FileAccessImpl(context); + fileAccess.writeFileContent("", gitconfigPath); + Path ideRoot = context.getUserHome().resolve("projects"); + IdeasyCommandlet ideasy = new IdeasyCommandlet(context); + assertThat(context.getIdeRoot()).as("IDE_ROOT is not set before install").isNull(); + // act + ideasy.installIdeasy(context.getUserHome().resolve("Downloads/ide-cli")); + // assert + assertThat(context.getIdeRoot()).isEqualTo(ideRoot); + } + /** * Test of {@link IdeasyCommandlet#configureWindowsTerminalGitBash()}, also when {@code IDE_ROOT} is not yet set, as is the case during MSI installation. *