Skip to content

#1953: Complete cleanup commandlet implementation and review handoverShow more lines - #2230

Open
Caylipp wants to merge 31 commits into
devonfw:mainfrom
Caylipp:feature/1953-cleanup-commandlet-handover
Open

#1953: Complete cleanup commandlet implementation and review handoverShow more lines#2230
Caylipp wants to merge 31 commits into
devonfw:mainfrom
Caylipp:feature/1953-cleanup-commandlet-handover

Conversation

@Caylipp

@Caylipp Caylipp commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

This PR fixes #1953

This PR completes and supersedes #1957 after the original author left the team.

Implemented changes:

  • Reused the existing global -f / --force mode instead of introducing a cleanup-specific force option.
  • Removed the obsolete --force-delete help entries.
  • Kept cleanup discovery stateless by creating the discovered-tool list locally for each execution.
  • Moved the cleanup model into reusable top-level classes in the lowercase commandlet.cleanup package.
  • Scanned all repositories below _ide/software, including default, maven, and custom repository IDs.
  • Matched project software references against resolved installation paths instead of relying on fixed path positions.
  • Supported project links to subdirectories of an installation, such as Contents/MacOS.
  • Supported the following software link structures:
    • software/<tool>
    • software/extra/<tool>
    • software/extra/<tool>/<name>
  • Stored project usage only on the concrete tool edition version.
  • Derived the unused state of editions and tools from their child versions.
  • Improved JavaDoc for the cleanup model and its properties.

Testing instructions

Please add conscise, understandable instructions on how a reviewer can test/verify the functionality of your contribution here:

  1. mvn -pl cli -Dtest=CleanupCommandletTest test
  2. mvn clean test

Related

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). If no issue ID exists, title only.
  • PR top-level comment summarizes 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 labeled
    with internal
  • You have formulated clear instructions on how to test your contribution under "Testing instructions"

Checklist for tool commandlets

Have you added a new «tool» as commandlet? There are the following additional checks:

  • The tool can be installed automatically (during setup via settings) or via the commandlet call
  • The tool is isolated in its IDEasy project, see Sandbox Principle
  • The new tool is added to the table of tools in LICENSE.asciidoc
  • The new commandlet is a command-wrapper for «tool»
  • Proper help texts for all supported languages are added here
  • The new commandlet installs potential dependencies automatically
  • The variables «TOOL»_VERSION and «TOOL»_EDITION are honored by your commandlet
  • The new commandlet is tested on all platforms it is available for or tested on all platforms that are in scope of the linked issue

areinicke and others added 29 commits May 15, 2026 16:05
- scan all global software repositories
- detect used versions by resolved installation paths
- support links to installation subfolders and nested extra tools
- make cleanup discovery stateless
- track project usage only on version level
- reuse the global force mode for confirmation
- add regression tests for used and unused installations
@github-project-automation github-project-automation Bot moved this to 🆕 New in IDEasy board Jul 29, 2026
@Caylipp Caylipp self-assigned this Jul 29, 2026
@Caylipp Caylipp moved this from 🆕 New to Team Review in IDEasy board Jul 29, 2026
@Caylipp Caylipp moved this from Team Review to 👀 In review in IDEasy board Jul 29, 2026
@Caylipp Caylipp moved this from 👀 In review to Team Review in IDEasy board Jul 29, 2026
@Caylipp Caylipp added commandlet ide sub-command enhancement New feature or request labels Jul 29, 2026
@coveralls

coveralls commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 30448595757

Coverage increased (+0.2%) to 72.801%

Details

  • Coverage increased (+0.2%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 7 coverage regressions across 1 file.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

7 previously-covered lines in 1 file lost coverage.

File Lines Losing Coverage Coverage
com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java 7 91.9%

Coverage Stats

Coverage Status
Relevant Lines: 17193
Covered Lines: 13045
Line Coverage: 75.87%
Relevant Branches: 7679
Covered Branches: 5062
Branch Coverage: 65.92%
Branches in Coverage %: Yes
Coverage Strength: 3.22 hits per line

💛 - Coveralls

@quando632 quando632 self-assigned this Jul 29, 2026

@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.

We are closing the finishing line 👍
Still I found some points...

private final Path path;

/** A flag indicating whether the tool is marked for deletion. */
private boolean delete;

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.

Seems some of my review feedback got lost (was maybe set to resolved by original author):
Please use OOP and avoid pointless redundancies.
We have these 3 classes that all should have a common abstract super-class.
Each of them has

  • name (simply generalize to just name instead of toolName, editionName, versionName)
  • path
  • delete

Also include methods like getters with JavaDoc, setter, etc.
BTW: I also suggested a simplification to have delete flag only in CleanupIdeToolEditionVersion so the consistency of the state gets trivial while with the current design it is complex. E.g. assume we later reuse this in the GUI and the user may see this as a tree with checkboxes and wants to unselect something manually to prevent deletion and then the parent deletion flag would need to be updated.
Simply when you iterate over the structure to perform the actual deletion check if the parent directory (edition or tool) now is empty after deletion of children and then also delete it.

List<CleanupIdeTool> installedCleanupIdeTools = discoverInstalledSoftware();

// Scan for IDEasy projects
List<Path> ideasyProjects = this.context.getFileAccess().listChildren(this.context.getIdeRoot(), Files::isDirectory);

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.

We have the same logic also in our GUI. It would make sense to add a method IdeContext.findProjects() for this.
And as a motivation why I always insist on creating reusable structures:
This implementation is incorrect. It will also include _ide as well as folders somehow created by the end-user that are not really IDEasy projects. When we create a method and once get it right, then we can reuse it everywhere. Even if there still is a bug, we can fix it in once place instead of multiple places because of copy&paste.

Comment on lines +60 to +62
if (ideasyProject.getFileName().toString().equals("_ide")) {
continue;
}

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.

This would then be part of the central method.

Path softwareRepositoryPath = this.context.getSoftwareRepositoryPath();
List<Path> repositoryFolders = this.context.getFileAccess().listChildren(softwareRepositoryPath, Files::isDirectory);
for (Path repositoryFolder : repositoryFolders) {
discoverInstalledSoftwareRepository(installedCleanupIdeTools, repositoryFolder);

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.

This is correct for default and maven but not for custom-tools:
https://github.com/devonfw/IDEasy/blob/main/documentation/software.adoc#custom-tools
For the given example URL
https://some-file-server.company.com/projects/my-project
We would have some-file-server.company.com as repositoryFolder here, but the actual repo with tool/edition/version structure is in the sub-path projects/my-project.
Sorry for this extra complication. I also missed this point in the review of the old PR.
So IMHO we should instead explicitly go to subfolders ToolRepository.ID_DEFAULT and MvnRepository.ID as well as this.context.getCustomToolRepository().getId(). The latter ID may be custom and that folder will typically not exist. Anyhow code should always be robust and handle non existing directories even when expected (I could delete entire _ide/software folder and that should not break ide cleanup - actually ide update should automatically repair my project if I did such evil deletion manually).

Comment on lines +99 to +100
installedCleanupIdeTools.add(tool);
discoverInstalledEditions(toolFolder, tool);

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.

Just as a thought, the methods could return a boolean, if some tool/edition/version was found that looks sane. Then you could skip adding if nothing sane was found like this:

boolean success = discoverInstalledEditions(toolFolder, tool);
if (success) {
  installedCleanupIdeTools.add(tool);
}

I am just still thinking if we have a reliable way of detecting "sanity".
We could obviously check for existence of .ide.software.version what would be my preferred way, but assuming this file was deleted by accident (see also #2197) it would IMHO still make sense to delete the tool installation if unused.
Then I was thinking that version folder should have a name that is a valid version.
However, we have seen some tools violating our own rules for what we think is a valid version.
Also checking that there is at least one digit in the version is wrong since we have version latest.
Maybe checking for latest or "at least one digit" might make sense.
So far just my thoughts - we can still ignore this for now and consider as improvement after the merge.

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

Labels

commandlet ide sub-command enhancement New feature or request

Projects

Status: Team Review

Development

Successfully merging this pull request may close these issues.

Implement Base Functionality of Cleanup Commandlet

6 participants