Skip to content

Comments

Feat/cli severity exit code#139

Open
quentinlebourles-packmind wants to merge 10 commits intomainfrom
feat/cli-severity-exit-code
Open

Feat/cli severity exit code#139
quentinlebourles-packmind wants to merge 10 commits intomainfrom
feat/cli-severity-exit-code

Conversation

@quentinlebourles-packmind
Copy link
Contributor

Explanation

Relates to #

Type of Change

  • Bug fix
  • New feature
  • Improvement/Enhancement
  • Refactoring
  • Documentation
  • Breaking change

Affected Components

  • Domain packages affected:
  • Frontend / Backend / Both:
  • Breaking changes (if any):

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing completed
  • Test coverage maintained or improved

Test Details:

TODO List

  • CHANGELOG Updated
  • Documentation Updated

Reviewer Notes

- Add DetectionSeverity to LinterExecutionProgram and LinterExecutionViolation
- Add severity to GetDetectionProgramsForPackagesResponse
- Add DetectionProgramWithSeverity to active/draft detection program response types
- Update existing tests with severity field

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add formatWarning utility for yellow text
- Update HumanReadableLogger with severity-based formatting and counts
- Update IDELintLogger with severity label
- Add tests for both loggers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…or summary spacing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@greptile-apps
Copy link

greptile-apps bot commented Feb 20, 2026

Greptile Summary

This PR implements severity-based exit codes and filtering for the CLI linter. Previously, any violations caused exit code 1; now only ERROR-severity violations trigger failure, while WARNINGs allow exit code 0. The --level flag enables filtering violations by minimum severity threshold.

Key changes:

  • Exit code logic now checks for ERROR severity specifically, not just violation count
  • Added --level CLI flag to filter displayed violations by severity threshold
  • Propagated severity field through the entire linting pipeline (types → execution → display)
  • Separated error/warning counts in console output with distinct formatting (red errors, yellow warnings)
  • Fixed duplicate violations from overlapping configs by deduplicating programs based on standard:rule:language key
  • Added comprehensive test coverage for new severity-based behavior

Issue found:

  • File count in error/warning summaries shows total files with any violations, not per-severity counts (see inline comment)

Confidence Score: 4/5

  • Safe to merge with one minor display bug in file counts
  • Well-structured implementation with comprehensive test coverage, clean separation of concerns, and proper type propagation. The file count display issue is cosmetic and doesn't affect functionality. The deduplication fix prevents actual bugs.
  • apps/cli/src/infra/repositories/HumanReadableLogger.ts - file count logic shows total files rather than per-severity counts

Important Files Changed

Filename Overview
apps/cli/src/infra/commands/lintHandler.ts Added --level flag filtering and severity-based exit codes; exit code 1 only on errors, not warnings
apps/cli/src/infra/commands/LinterCommand.ts Added --level option with validation for error/warning filtering
apps/cli/src/infra/repositories/HumanReadableLogger.ts Separated error/warning counts with distinct formatting; file count may be incorrect when files have mixed severities
apps/cli/src/application/useCases/LintFilesFromConfigUseCase.ts Added program deduplication to prevent duplicate violations from overlapping configs; propagated severity field
packages/linter-execution/src/application/useCases/ExecuteLinterProgramsUseCase.ts Propagated severity from program to violation output
packages/types/src/linter/contracts/IExecuteLinterProgramsUseCase.ts Added severity field to program and violation types

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[CLI: lint command] --> B{--level flag?}
    B -->|Yes| C[Parse severity threshold]
    B -->|No| D[No filtering]
    
    C --> E[LintHandler]
    D --> E
    
    E --> F{--rule specified?}
    F -->|Yes| G[LintFilesAgainstRule]
    F -->|No| H[LintFilesFromConfig]
    
    G --> I[ExecuteLinterPrograms]
    H --> J[Deduplicate programs]
    J --> I
    
    I --> K[Violations with severity]
    
    K --> L{--level filter?}
    L -->|Yes| M[Filter by severity threshold]
    L -->|No| N[All violations]
    
    M --> O[Log filtered violations]
    N --> O
    
    O --> P{Has ERROR severity?}
    P -->|Yes| Q[Exit code 1]
    P -->|No| R[Exit code 0]
    
    style Q fill:#f88
    style R fill:#8f8
    style M fill:#ff8
    style J fill:#8ff
Loading

Last reviewed commit: 2fc9f0a

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

22 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +34 to 42
if (errorCount > 0) {
logErrorConsole(
`❌ Found ${formatBold(String(totalViolationCount))} violation(s) in ${formatBold(String(violations.length))} file(s)`,
`❌ Found ${formatBold(String(errorCount))} error(s) in ${formatBold(String(violations.length))} file(s)`,
);
}
if (warningCount > 0) {
logWarningConsole(
`⚠️ Found ${formatBold(String(warningCount))} warning(s) in ${formatBold(String(violations.length))} file(s)`,
);
Copy link

Choose a reason for hiding this comment

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

File count in summary uses total violations.length, which counts all files with any violations, not files with that specific severity. If file A has errors and file B has warnings, both summaries show "2 file(s)".

Consider tracking file counts per severity:

Suggested change
if (errorCount > 0) {
logErrorConsole(
`❌ Found ${formatBold(String(totalViolationCount))} violation(s) in ${formatBold(String(violations.length))} file(s)`,
`❌ Found ${formatBold(String(errorCount))} error(s) in ${formatBold(String(violations.length))} file(s)`,
);
}
if (warningCount > 0) {
logWarningConsole(
`⚠️ Found ${formatBold(String(warningCount))} warning(s) in ${formatBold(String(violations.length))} file(s)`,
);
const filesWithErrors = violations.filter((v) =>
v.violations.some((d) => d.severity === DetectionSeverity.ERROR),
).length;
const filesWithWarnings = violations.filter((v) =>
v.violations.some((d) => d.severity === DetectionSeverity.WARNING),
).length;
if (errorCount > 0) {
logErrorConsole(
`❌ Found ${formatBold(String(errorCount))} error(s) in ${formatBold(String(filesWithErrors))} file(s)`,
);
}
if (warningCount > 0) {
logWarningConsole(
`⚠️ Found ${formatBold(String(warningCount))} warning(s) in ${formatBold(String(filesWithWarnings))} file(s)`,
);
}

@sonarqubecloud
Copy link

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant