Skip to content

#2190: IDEasy destroys my python installation - #2384

Open
Paras14 wants to merge 5 commits into
devonfw:mainfrom
Paras14:2190-ideasy-destroys-python-installation
Open

#2190: IDEasy destroys my python installation#2384
Paras14 wants to merge 5 commits into
devonfw:mainfrom
Paras14:2190-ideasy-destroys-python-installation

Conversation

@Paras14

@Paras14 Paras14 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

This PR fixes #2190

Implemented changes:

  • LocalToolCommandlet now really writes the .ide.software.version file when it is missing. The branch added in #2190: IDEasy destroys python installation #2212 logged "restoring it" but never called writeVersionFile, so the file stayed missing and every following command showed the warning again and asked for a CVE version selection.
  • Added an overridable hook detectInstalledVersion(installationPath, resolvedVersion). The default returns the requested version. Python overrides it and determines the version that is really installed, first from pyvenv.cfg (only if it contains a patch version, because uv writes just 3.13 for its own interpreters) and otherwise by calling python --version. This prevents writing a version file that claims a version the virtual environment does not have, which can happen because uv sync may recreate the venv with a different python version.
  • If the detected version differs from the requested one, the regular installation continues. It backs up the existing installation instead of deleting it.
  • Invalidates the cached installed edition and version from Improve support to get installed version and edition #2296, because the version file is changed outside of createToolInstallation.
  • Added a regression test to PythonTest that fails without these changes. The mocked python binary in the uv test project now answers --version.

Testing instructions

  1. Run mvn clean test in the cli module. The new test PythonTest.testInstallRestoresMissingVersionFileAndPreservesPackages covers this fix. It installs python, adds a file to site-packages, deletes .ide.software.version and installs again. It asserts that the version file is restored with the correct version, that the installed packages are preserved and that no "Deleting corrupted installation" happens.
  2. To see the test catch the bug, revert LocalToolCommandlet.java and Python.java to main and run PythonTest again. It fails because the version file is not restored.

Note for reviewers: the test pins the OS to SystemInfoMock.LINUX_X64, because the mocked python payload in the uv test project has a Unix style bin folder that collides with the bin to Scripts symlink created on Windows. Therefore the Windows specific parts of detectInstalledVersion (bin path resolution, .exe suffix, parsing the real interpreter output) are not covered by automated tests.


Checklist for this PR

Make sure everything is checked before merging this PR. For further info please also see
our DoD.

  • When running mvn clean test locally all tests pass and build is successful
  • PR title is of the form #«issue-id»: «brief summary» (e.g. #921: fixed setup.bat and not feature/921 fixed setup.bat). If no issue ID exists, title only.
  • PR top-level comment summaries what has been done and contains link to addressed issue(s)
  • PR and issue(s) have suitable labels
  • Issue is set to In Progress and assigned to you or there is no issue (might happen for very small PRs)
  • You followed all coding conventions
  • You have added the issue implemented by your PR in CHANGELOG.adoc unless issue is labelled
    with internal
  • You have not changed any dependency in pom.xml files or otherwise if runtime dependencies changed, you have updated our LICENSE.asciidoc
  • You have formulated clear instructions on how to test your contribution under "Testing instructions"

@github-project-automation github-project-automation Bot moved this to 🆕 New in IDEasy board Aug 27, 2026
@Paras14 Paras14 self-assigned this Aug 27, 2026
@Paras14 Paras14 moved this from 🆕 New to Team Review in IDEasy board Aug 27, 2026
@Paras14 Paras14 added python runtime for python language install installation process of IDE + tools and install commandlet uv fast Python package and project manager labels Aug 27, 2026
@coveralls

coveralls commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 33412176589

Coverage decreased (-0.03%) to 73.587%

Details

  • Coverage decreased (-0.03%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 54 coverage regressions across 3 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

54 previously-covered lines in 3 files lost coverage.

File Lines Losing Coverage Coverage
com/devonfw/tools/ide/tool/LocalToolCommandlet.java 31 82.69%
com/devonfw/tools/ide/tool/python/Python.java 22 57.94%
com/devonfw/tools/ide/tool/ide/IdeToolCommandlet.java 1 87.42%

Coverage Stats

Coverage Status
Relevant Lines: 18402
Covered Lines: 14160
Line Coverage: 76.95%
Relevant Branches: 8164
Covered Branches: 5389
Branch Coverage: 66.01%
Branches in Coverage %: Yes
Coverage Strength: 3.28 hits per line

💛 - Coveralls

@Paras14 Paras14 changed the title #2190: Restore missing software version file instead of only logging it #2190: IDEasy destroys my python installation Aug 27, 2026
@Hiepiscus Hiepiscus self-assigned this Aug 27, 2026
@Hiepiscus
Hiepiscus self-requested a review August 27, 2026 11:55

@hohwille hohwille left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Paras14 thanks for your PR. The way how you detect the python version is perfectly implemented. Test covers the feature nicely and according python mocked script adoption makes sense for testing. 👍
I left some review suggestion how I thought we should connect #2296 with this to fix the problem properly. Please have a look,

// Restore the missing file
return createToolInstallation(installationPath, resolvedVersion, false, processContext, additionalInstallation);
// Version file is missing but tool allows this - restore the file and preserve the installation.
VersionIdentifier detectedVersion = detectInstalledVersion(installationPath, resolvedVersion);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that we would simply use the new infrastructure of #2296 and integrate that directly in computeInstalledEditionAndVersion. This way you will also fix the ide get-version python currently returns a wrong result if the version file is lost.
Also the .ide.software.version file is actually a kind of hack inherited from devonfw-ide (legacy file is .devonfw.software.version.
My plan is to get more away from this on the long run.
The installed edition of regular local tools is actually determined from the link target of the software folder in the software repository and the version can be determined in the same way.
I would therefore suggest, that we simply rely on getInstalledVersion() what is already used in the installation routine.

See here:

protected EditionAndVersion computeInstalledEditionAndVersion() {
Path toolPath = getToolPath();
if (isToolNotInstalled(toolPath)) {
return null;
}
// Resolve edition and version from a single tool-path lookup (one pass) instead of two separate lookups.
String edition = getInstalledEdition(toolPath);
VersionIdentifier version = getInstalledVersion(toolPath);
if (version == null) {
return null;
}
return new EditionAndVersion(edition, version);
}
/**
* @param toolPath the installation {@link Path} where to find the version file.
* @return the currently installed {@link VersionIdentifier version} of this tool or {@code null} if not installed.
*/
protected VersionIdentifier getInstalledVersion(Path toolPath) {
if (isToolNotInstalled(toolPath)) {
return null;
}
Path versionLookupPath = getInstalledSoftwareRepoPath(toolPath, false);
if (versionLookupPath == null) {
versionLookupPath = toolPath;
}
Path toolVersionFile = versionLookupPath.resolve(IdeContext.FILE_SOFTWARE_VERSION);
if (!Files.exists(toolVersionFile)) {
Path legacyToolVersionFile = versionLookupPath.resolve(IdeContext.FILE_LEGACY_SOFTWARE_VERSION);
if (Files.exists(legacyToolVersionFile)) {
toolVersionFile = legacyToolVersionFile;
} else {
LOG.warn("Tool {} is missing version file in {}", getName(), toolVersionFile);
return null;
}
}
String version = this.context.getFileAccess().readFileContent(toolVersionFile).trim();
return VersionIdentifier.of(version);
}

So Python can simply override getInstalledVersion() and if null is returned from super call, simply add fallbacks (what is currently in detectInstalledVersion).

Comment thread CHANGELOG.adoc

Release with new features and bugfixes:

* https://github.com/devonfw/IDEasy/issues/2190[#2190]: IDEasy destroys my python installation

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opened the next release. Please shift up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

install installation process of IDE + tools and install commandlet python runtime for python language uv fast Python package and project manager

Projects

Status: Team Review

Development

Successfully merging this pull request may close these issues.

Restore .ide.software.version from actual installed Python version IDEasy destroys my python installation

4 participants