Run a single checker standalone with standard output formatting. Args: checker: Checker instance to run directories: List of directories to scan description: Human-readable description of what's being checked extensions: File extensions to check (default: [".cpp"
(
checker: FileContentChecker,
directories: list[str],
description: str,
extensions: list[str] | None = None,
)
| 350 | |
| 351 | |
| 352 | def run_checker_standalone( |
| 353 | checker: FileContentChecker, |
| 354 | directories: list[str], |
| 355 | description: str, |
| 356 | extensions: list[str] | None = None, |
| 357 | ) -> None: |
| 358 | """Run a single checker standalone with standard output formatting. |
| 359 | |
| 360 | Args: |
| 361 | checker: Checker instance to run |
| 362 | directories: List of directories to scan |
| 363 | description: Human-readable description of what's being checked |
| 364 | extensions: File extensions to check (default: [".cpp", ".h", ".hpp"]) |
| 365 | """ |
| 366 | import sys |
| 367 | |
| 368 | # Collect files |
| 369 | files_to_check = collect_files_to_check(directories, extensions) |
| 370 | |
| 371 | # Run checker |
| 372 | processor = MultiCheckerFileProcessor() |
| 373 | processor.process_files_with_checkers(files_to_check, [checker]) |
| 374 | |
| 375 | # Get violations (checkers store them in .violations attribute) |
| 376 | if not hasattr(checker, "violations"): |
| 377 | print(f"✅ {description}: No violations found.") |
| 378 | sys.exit(0) |
| 379 | |
| 380 | violations = getattr(checker, "violations") |
| 381 | |
| 382 | # Support both legacy dict format and new CheckerResults format |
| 383 | if isinstance(violations, CheckerResults): |
| 384 | results = violations |
| 385 | else: |
| 386 | # Legacy format - convert to CheckerResults |
| 387 | results = CheckerResults() |
| 388 | for file_path, violation_list in violations.items(): |
| 389 | if isinstance(violation_list, list): |
| 390 | for item in violation_list: # type: ignore[misc] |
| 391 | if isinstance(item, tuple) and len(item) >= 2: # type: ignore[arg-type] |
| 392 | line_num = int(item[0]) # type: ignore[arg-type] |
| 393 | content = str(item[1]) # type: ignore[arg-type] |
| 394 | results.add_violation(file_path, line_num, content) |
| 395 | elif isinstance(violation_list, str): |
| 396 | results.add_violation(file_path, 0, violation_list) |
| 397 | |
| 398 | if results.has_violations(): |
| 399 | total_violations = results.total_violations() |
| 400 | file_count = results.file_count() |
| 401 | |
| 402 | print(f"❌ {description} ({file_count} files, {total_violations} violations):") |
| 403 | print() |
| 404 | |
| 405 | # Sort files by relative path |
| 406 | for file_path in sorted(results.violations.keys()): |
| 407 | rel_path = file_path.replace(str(PROJECT_ROOT), "").lstrip("\\/") |
| 408 | # Normalize to forward slashes for consistent cross-platform output |
| 409 | rel_path = rel_path.replace("\\", "/") |