Open
Conversation
Add a new CLI tool that validates code metrics against configurable thresholds for use in CI/CD pipelines. The tool uses UnifiedParser internally to analyze code and reports violations when metrics exceed specified limits. Features: - Validates file-level metrics from UnifiedParser (rloc, complexity, etc.) - Supports YAML and JSON configuration files via Jackson - Reports violations sorted by severity (worst offenders first) - Color-coded console output with formatted tables - Exit codes: 0 (pass), 1 (violations), 2 (errors) - Interactive mode support via Dialog - Comprehensive documentation with usage examples Implementation: - New module: analysers/tools/MetricThresholdChecker - Dependencies: Jackson 2.18.2 (databind, dataformat-yaml, module-kotlin) - Registered in Ccsh and settings.gradle.kts - Added YAML/YML file extensions to FileExtension enum 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Document the new MetricThresholdChecker tool in the unreleased section of the CHANGELOG. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive documentation for the new MetricThresholdChecker tool to the GitHub Pages site. Includes: - Tool overview and features - Configuration format (YAML/JSON) - Available metrics from UnifiedParser - Usage examples and parameters - CI/CD integration examples for GitHub Actions, GitLab CI, and Jenkins - Tips for prioritizing fixes and iterative improvement - Common use cases 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add 22 test cases covering MetricThreshold validation logic - Test min/max threshold violations and boundary conditions - Test violation type detection (BELOW_MIN, ABOVE_MAX) - Test edge cases: decimals, negatives, zero, large numbers - Test threshold value retrieval by violation type - All tests follow Arrange-Act-Assert pattern - Achieves comprehensive coverage of threshold validation logic 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add 14 test cases for config file loading and parsing - Test JSON and YAML format parsing (yml, yaml extensions) - Test edge cases: empty metrics, missing keys, decimals - Test error scenarios: invalid syntax, non-existent files - Test validation: unsupported extensions, non-numeric values - Test case-insensitive extension handling - Add 11 test resource files for various scenarios - All tests follow Arrange-Act-Assert pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add 16 test cases for threshold validation logic - Test min/max violation detection for file metrics - Test nested folder structure traversal - Test multiple files and multiple metric violations - Test edge cases: empty projects, only folders, no metrics - Test node type filtering (skip Class, Method, Package nodes) - Test boundary conditions and decimal values - Test non-numeric attribute value handling - Test path construction for violations - All tests follow Arrange-Act-Assert pattern with helper functions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add 18 test cases for violation output formatting - Test success and failure message formatting - Test violation grouping by metric name - Test table formatting with headers and data - Test excess amount calculation and display (+/- signs) - Test threshold value display (min/max) - Test number formatting (integers vs decimals) - Test violation sorting by excess amount - Test multiple metrics with different violation counts - Test long path truncation - Handle locale-dependent decimal separators - All tests follow Arrange-Act-Assert pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add 16 integration test cases for main CLI tool - Test successful execution with passing thresholds - Test CLI parameter handling (verbose, exclude, file-extensions) - Test input validation (null paths, non-existent files) - Test bypass-gitignore flag functionality - Test single file and directory analysis - Test multiple exclude patterns and file extensions - Test interface methods (isApplicable, getDialog) - Test constants (NAME, DESCRIPTION) - Add sample code files and test configurations - Handle exitProcess(1) limitations in testing - All tests follow Arrange-Act-Assert pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Move inline comments to separate lines per ktlint rules - Fix argument formatting in test cases - All tests still pass with 82% branch coverage 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Reorganized test resource files into logical subdirectories: - config/: Valid configuration files for positive test cases - config-invalid/: Invalid configurations for error handling tests - sample-code/: Test source code files (already existed) Updated test file paths in MetricThresholdCheckerTest and ThresholdConfigurationLoaderTest to reflect new structure. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…ation Reorganize MetricThresholdChecker from flat 17-file structure into logical subdirectories following patterns used in other analysers: - model/ - Data model classes (ThresholdConfiguration, etc.) - config/ - Configuration loading (ThresholdConfigurationLoader) - validation/ - Validation logic (ThresholdValidator) - output/ - Output formatting with subdirectories: - renderers/ - High-level rendering (SummaryRenderer, ViolationTableRenderer, ViolationGroupRenderer) - formatters/ - Low-level formatting utilities (NumberFormatter, PathFormatter, etc.) All files moved with git mv to preserve history. All package declarations and imports updated. Build, tests (131 passing), and ktlint checks verified. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Fixed multiple alignment issues in violation table rendering: 1. ANSI color code handling - Replaced broken substring() approach with manual padding that accounts for invisible ANSI color codes 2. Table width overflow - Added MAX_PATH_WIDTH=50 cap to prevent table from becoming too wide for terminal 3. Path truncation - Changed from middle truncation to start truncation (e.g., "...ectories/File.kt") to keep filename visible 4. Path alignment - Right-aligned path column so filenames line up vertically for easier scanning Updated PathFormatterTest to match new truncation behavior with exact expected output assertions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
MetricThresholdChecker was duplicating UnifiedParser's scanning logic, requiring manual AttributeDescriptor registration which was bug-prone. Changes: - Add UnifiedParser.parse() as public API for library usage - Refactor MetricThresholdChecker to use UnifiedParser.parse() - Remove duplicated ProjectScanner setup code - AttributeDescriptors now included automatically This eliminates code duplication and ensures MetricThresholdChecker benefits from any UnifiedParser improvements. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
ChristianHuehn
commented
Nov 6, 2025
...bornwolff/codecharta/analysers/tools/metricthresholdchecker/output/formatters/TextWrapper.kt
Show resolved
Hide resolved
...codecharta/analysers/tools/metricthresholdchecker/output/renderers/ViolationGroupRenderer.kt
Show resolved
Hide resolved
...codecharta/analysers/tools/metricthresholdchecker/output/renderers/ViolationTableRenderer.kt
Outdated
Show resolved
Hide resolved
...bornwolff/codecharta/analysers/tools/metricthresholdchecker/validation/ThresholdValidator.kt
Outdated
Show resolved
Hide resolved
...bornwolff/codecharta/analysers/tools/metricthresholdchecker/validation/ThresholdValidator.kt
Outdated
Show resolved
Hide resolved
Refactored MetricThresholdChecker code based on PR #4334 review feedback: - TextWrapper.wrap(): Simplified complex logic inline, reduced conditional complexity, and made flow more linear - ViolationGroupRenderer.render(): Extracted into smaller focused methods (addViolationsHeader, renderMetricGroup, addMetricDescription, sortViolationsByExcess) for better readability - ViolationTableRenderer: Replaced string concatenation with Kotlin template strings and added intermediate variables to fix ktlint line length violations - ThresholdValidator.validateNode(): Used else branch instead of comma-separated node types for cleaner when statement - ThresholdValidator.validateFileMetrics(): Reduced nesting depth from 3 to 1 level using guard clauses with continue statements All 131 tests passing. Code style checks passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
ChristianHuehn
commented
Nov 10, 2025
...maibornwolff/codecharta/analysers/tools/metricthresholdchecker/MetricThresholdCheckerTest.kt
Outdated
Show resolved
Hide resolved
...maibornwolff/codecharta/analysers/tools/metricthresholdchecker/MetricThresholdCheckerTest.kt
Show resolved
Hide resolved
...maibornwolff/codecharta/analysers/tools/metricthresholdchecker/MetricThresholdCheckerTest.kt
Outdated
Show resolved
Hide resolved
...nwolff/codecharta/analysers/tools/metricthresholdchecker/model/ThresholdConfigurationTest.kt
Show resolved
Hide resolved
...bornwolff/codecharta/analysers/tools/metricthresholdchecker/validation/ThresholdValidator.kt
Outdated
Show resolved
Hide resolved
...bornwolff/codecharta/analysers/tools/metricthresholdchecker/output/formatters/TextWrapper.kt
Show resolved
Hide resolved
...wolff/codecharta/analysers/tools/metricthresholdchecker/output/formatters/NumberFormatter.kt
Show resolved
Hide resolved
...lff/codecharta/analysers/tools/metricthresholdchecker/config/ThresholdConfigurationLoader.kt
Outdated
Show resolved
Hide resolved
Nereboss
reviewed
Nov 10, 2025
Comment on lines
+51
to
+79
| fun parse( | ||
| inputFile: File, | ||
| excludePatterns: List<String> = emptyList(), | ||
| fileExtensions: List<String> = emptyList(), | ||
| bypassGitignore: Boolean = false, | ||
| verbose: Boolean = false | ||
| ): Project { | ||
| val projectBuilder = ProjectBuilder() | ||
| val useGitignore = !bypassGitignore | ||
|
|
||
| val projectScanner = ProjectScanner( | ||
| inputFile, | ||
| projectBuilder, | ||
| excludePatterns, | ||
| fileExtensions, | ||
| emptyMap(), | ||
| useGitignore | ||
| ) | ||
|
|
||
| projectScanner.traverseInputProject(verbose) | ||
|
|
||
| if (!projectScanner.foundParsableFiles()) { | ||
| Logger.warn { "No parsable files found in the given input path" } | ||
| } | ||
|
|
||
| projectBuilder.addAttributeDescriptions(getAttributeDescriptors()) | ||
|
|
||
| return projectBuilder.build() | ||
| } |
Collaborator
There was a problem hiding this comment.
This function mirrors a lot of the functionality of the private "scanInputProject" function without:
- handling of piped input
- logic to adjust exclusion patterns based on gitignore files
- reporting result of the unifiedparser
This should be refactored to avoid duplicated code
…entry (#4334) Added missing issue reference to MetricThresholdChecker tool entry in CHANGELOG.md as requested in PR review. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Removed javax-activation dependency from libs.versions.toml as it is no longer used in the codebase. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Added proper Arrange/Act/Assert comments to all tests - Moved class-level comment about exitProcess limitations to top - Removed redundant inline comments - Renamed unclear test methods to better reflect what they test - All tests still passing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…idatorTest (#4334) Replaced all [0] array access with .first() for better Kotlin idioms and null safety. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
) Changed ambiguous regex that accepted both 75.56 and 75.57 to explicit expectation of 75.57 for round-half-up behavior. Test name updated to reflect rounding mode. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Added validation to throw IllegalArgumentException when max is less than min in MetricThreshold. Includes test coverage for this edge case. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Refactored ThresholdValidator to use functional approach without side effects: - Changed validateNode() to return List<ThresholdViolation> instead of mutating parameter - Use flatMap for collecting child violations - Use mapNotNull for collecting file metric violations - All functions now return new lists instead of modifying mutable state 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Refactored TextWrapper to be more self-explanatory: - Extracted helper methods with descriptive names (shouldStartNewLine, hasContent, etc.) - Replaced cryptic variable names with clear ones (hasContentAlready instead of needsSpace) - Simplified main wrap() method to read like plain English - Renamed WORD_SEPARATOR_LENGTH to SPACE_LENGTH for clarity 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…4334) Changed NumberFormatter to explicitly use BigDecimal with RoundingMode.HALF_UP instead of relying on String.format's default banker's rounding. This ensures consistent and predictable rounding behavior for all decimal values. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…gurationLoader (#4334) Refactored to use type-safe Jackson deserialization: - Removed all @Suppress annotations for unchecked casts - Removed unsafe type casts - Introduced DTOs (ConfigurationDTO, MetricThresholdDTO) for type-safe deserialization - Added proper Jackson configuration to ignore unknown properties - Cleaner separation between JSON/YAML parsing and domain models 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Closes: #4333
Description
Definition of Done
A PR is only ready for merge once all the following acceptance criteria are fulfilled:
Screenshots or gifs