Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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:


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatt

private Path ideHome;

private final Path ideRoot;
private Path ideRoot;

private Path confPath;

Expand Down Expand Up @@ -587,6 +587,12 @@ public Path getIdeRoot() {
return this.ideRoot;
}

@Override
public void setIdeRoot(Path ideRoot) {

this.ideRoot = ideRoot;
}

@Override
public Path getIdePath() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
* <li>{@link #getGitContext() git context} (for git operations like clone, fetch, pull, etc.)</li>
* <li>{@link #getSystemInfo() system info} (for information about OS and CPU architecture)</li>
* <li>{@link #getVariables() environment variables} (to access and modify IDEasy variables according to our configuration layout)</li>
*
*
* <li>{@link #question(Object[], String, Object...) question} (for interaction to let the end-user decide)</li>
* <li>{@link #getUrls() url metadata} (access ide-urls to find versions, download URLs, dependency and security metadata)</li>
* <li>{@link #getDefaultToolRepository() tool repository} (for abstraction of version resolution and download of tools)</li>
Expand Down Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <a href="https://github.com/devonfw/IDEasy/issues/1517">#1517</a> 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.
*
Expand Down
Loading