Skip to content

#2338: Add a new check commandlet - #2355

Open
Hiepiscus wants to merge 11 commits into
devonfw:mainfrom
Hiepiscus:2338-basic-check-commandlet
Open

#2338: Add a new check commandlet#2355
Hiepiscus wants to merge 11 commits into
devonfw:mainfrom
Hiepiscus:2338-basic-check-commandlet

Conversation

@Hiepiscus

@Hiepiscus Hiepiscus commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

This PR fixes #2338

Implemented changes:

  • Added the new check commandlet.
  • Added repository root detection based on the .git directory.
  • Added validation for the existence of a .gitignore file in the repository root.
  • Added validation for the required .gitignore rules: .* and !.gitignore
  • Added automatic fixing of detected issues via --fix.
  • Added tests for check commandlet

Testing instructions

  1. Create a new project that is not a Git repository and run ide check
  2. verify that an issue is reported
  3. Create a Git repository (e.g. git init) without a .gitignore file and run ide check
  4. verify that an issue is reported
  5. Run ide check --fix and verify that .gitignore is created containing .* and !.gitignore
  6. Remove .* or !.gitignore from .gitignore and verify that the issue is detected.
  7. Run ide check --fix and verify that the missing rule is added.

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 20, 2026
@Hiepiscus Hiepiscus self-assigned this Aug 20, 2026
@Hiepiscus Hiepiscus added the commandlet ide sub-command label Aug 20, 2026
@Hiepiscus Hiepiscus moved this from 🆕 New to Team Review in IDEasy board Aug 20, 2026
@coveralls

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 32373870031

Coverage increased (+0.04%) to 72.987%

Details

  • Coverage increased (+0.04%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 9 coverage regressions across 3 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

9 previously-covered lines in 3 files lost coverage.

File Lines Losing Coverage Coverage
com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java 7 92.02%
com/devonfw/tools/ide/git/GitContextImpl.java 1 38.99%
com/devonfw/tools/ide/tool/ide/IdeToolCommandlet.java 1 78.69%

Coverage Stats

Coverage Status
Relevant Lines: 17657
Covered Lines: 13438
Line Coverage: 76.11%
Relevant Branches: 7797
Covered Branches: 5140
Branch Coverage: 65.92%
Branches in Coverage %: Yes
Coverage Strength: 3.23 hits per line

💛 - Coveralls

@majesteSil
majesteSil self-requested a review August 20, 2026 13:33
@majesteSil majesteSil self-assigned this Aug 20, 2026
@majesteSil

majesteSil commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

so thanks you for adding the basics for the new check commandlet, it looks good actually but i still have some issue that should be quick to fix

/**
* {@link Commandlet} to check the current repository for best-practices, starting from the current working directory (CWD).
*/
public class CheckCommandlet extends Commandlet {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think CheckCommandlet should live directly in com.devonfw.tools.ide.commandlet like all the other commandlets (Build, Install, Status, …) every commandlet class is in that package today. The test is already there (CheckCommandletTest), so the main class would even sit next to its test again.

But i wil makes sure this match the convention

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the review. I followed the existing structure used by CleanupCommandlet, which is also in a subpackage. However I am happy to move it if we want to place all commandletts in com.devonfw.tools.ide.commandlet.

private void checkGitIgnore(Path repositoryRoot, List<CheckIssue> issues) {

Path gitignore = repositoryRoot.resolve(MissingGitignoreIssue.GITIGNORE);
if (!Files.exists(gitignore)) {

@majesteSil majesteSil Aug 25, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

so here you do use java.nio for File existence check but we already have an intern class that can help you do so and stay consistent (fileAccess).

my suggestion use
fileAccess.isFile(gitignore)

Comment on lines +94 to +99
try {
lines = Files.readAllLines(gitignore);
} catch (IOException e) {
LOG.warn("Failed to read{}", gitignore, e);
return;
}

@majesteSil majesteSil Aug 25, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

it will also help you avoid this try catch block because the IOException you try to catch here is already wrappt in readFileLines (instead of the Classic readAllLines) as IllegalStateException

my suggestion see:
readFileLines in FileAccessImpl


boolean open = false;
for (CheckIssue issue : issues) {
IdeLogLevel.WARNING.log(LOG, "{}", issue);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

you log this Issue two times here and at line 132, i think just one time will be okay

}

/**
* Test that {@code ide check} reports a missing .gitignore and fails (exit code 0) without --fix.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

just small improvment the description don't match the reality the exit code is 1 not 0

}

/**
* @return the line number this warning refers to, or {@code null} if not applicable.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This Issue not Warning

}

/**
* @return {@code true} if this warning can be automatically fixed via {@link #fix(IdeContext)}, {@code false} otherwise.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Issue

}

/**
* Attempts to fix the problem that caused this warning.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Issue

public boolean fix(IdeContext context) {

List<String> lines = new ArrayList<>(context.getFileAccess().readFileLines(getPath()));
lines.add(this.rule);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

so two things here
first: an ArrayList is not really needed here because ReadFileLines is a List itself

second: you send return true here but if readFileLines() return null this will throw an NPE.
my suggestion here is to first check that lines are not null such as

List<String> lines = context.getFileAccess().readFileLines(getPath());
if (lines == null){ 
 return false; 
}
 lines.add(this.rule);
context.getFileAccess().writeFileLines(lines, getPath());
return true;

you don't need to log it yourself because readFileLines already do it

@Hiepiscus

Copy link
Copy Markdown
Contributor Author

@majesteSil Thanks for the review! I've applied your suggestions.

@majesteSil

Copy link
Copy Markdown
Contributor

@Hiepiscus
this look proper to me, i understand that you used this structure because of the Cleanup which also seems to be very new so for me you can move it to the next step and when needed ask Jorg if it is okay like this

@Hiepiscus Hiepiscus moved this from Team Review to 👀 In review in IDEasy board Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commandlet ide sub-command

Projects

Status: 👀 In review

Development

Successfully merging this pull request may close these issues.

Create first basic version of check commandlet only capable of checking for top-level .gitignore and common patterns inside

3 participants