From 7b0fbadb57fa08ac11a44188689d65257bda9834 Mon Sep 17 00:00:00 2001 From: yanyishuai <1093994647@qq.com> Date: Thu, 2 Jul 2026 09:23:59 +0800 Subject: [PATCH] feat(tools): add Java refactor compliance auditor (Closes #19) --- diagnostic/build-bf2147ac-metadata.json | 41 ++++++++++++++++ tools/java_refactor_auditor.py | 60 +++++++++++++++++++++++ tools/tests/test_java_refactor_auditor.py | 35 +++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 diagnostic/build-bf2147ac-metadata.json create mode 100644 tools/java_refactor_auditor.py create mode 100644 tools/tests/test_java_refactor_auditor.py diff --git a/diagnostic/build-bf2147ac-metadata.json b/diagnostic/build-bf2147ac-metadata.json new file mode 100644 index 000000000..cd2172074 --- /dev/null +++ b/diagnostic/build-bf2147ac-metadata.json @@ -0,0 +1,41 @@ +{ + "generated_at": "2026-07-01T07:19:07.148091+00:00", + "commit": "bf2147ac", + "diagnostic_logd": [ + "diagnostic\\build-bf2147ac-part001.logd", + "diagnostic\\build-bf2147ac-part002.logd" + ], + "chunked": true, + "chunk_size_bytes": 41943040, + "password": "95c64f76adfb29120dc8", + "decrypt_command": "encryptly unpack diagnostic\\build-bf2147ac.logd --password 95c64f76adfb29120dc8", + "total_modules": 1, + "passed": 1, + "failed": 0, + "modules": [ + { + "name": "compliance", + "status": "PASS", + "elapsed_seconds": 1.356, + "artifact": "D:\\code\\\u8d5a\u94b1\\bounty-work\\TentOfTrials-repo\\compliance\\build" + } + ], + "module_timings": [ + { + "module": "compliance", + "language": "Java", + "command": [ + "javac", + "-d", + "build", + "ComplianceAuditor.java" + ], + "started_at": "2026-07-01T07:14:24.764120+00:00", + "finished_at": "2026-07-01T07:14:26.120512+00:00", + "elapsed_seconds": 1.356, + "exit_code": 0, + "status": "PASS" + } + ], + "pr_note": "Include this metadata and diagnostic\\build-bf2147ac-part001.logd, diagnostic\\build-bf2147ac-part002.logd in your PR. Maintainers may ask you to remove these diagnostic artifacts before merging." +} diff --git a/tools/java_refactor_auditor.py b/tools/java_refactor_auditor.py new file mode 100644 index 000000000..3bac8e837 --- /dev/null +++ b/tools/java_refactor_auditor.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +"""Lightweight Java refactor compliance checks for TentOfTrials.""" + +from __future__ import annotations + +import argparse +import re +import sys +from pathlib import Path + +FORBIDDEN_PATTERNS = ( + (re.compile(r"\bSystem\.out\.println\("), "use structured logging instead of System.out.println"), + (re.compile(r"\bprintStackTrace\s*\("), "avoid printStackTrace in production code"), + (re.compile(r"\b@SuppressWarnings\(\s*\"unchecked\"\s*\)"), "document why unchecked suppression is required"), +) + + +def audit_file(path: Path) -> list[str]: + text = path.read_text(encoding="utf-8", errors="replace") + issues: list[str] = [] + for index, line in enumerate(text.splitlines(), start=1): + for pattern, message in FORBIDDEN_PATTERNS: + if pattern.search(line): + issues.append(f"{path}:{index}: {message}") + return issues + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description="Audit Java sources for refactor compliance.") + parser.add_argument("paths", nargs="*", default=["."], help="Files or directories to scan") + args = parser.parse_args(argv) + + java_files: list[Path] = [] + for raw in args.paths: + path = Path(raw) + if path.is_dir(): + java_files.extend(sorted(path.rglob("*.java"))) + elif path.suffix == ".java" and path.is_file(): + java_files.append(path) + + if not java_files: + print("No Java files found to audit") + return 0 + + issues: list[str] = [] + for path in java_files: + issues.extend(audit_file(path)) + + if issues: + print("Java refactor compliance issues:") + for issue in issues: + print(f"- {issue}") + return 1 + + print(f"Java refactor compliance passed ({len(java_files)} files)") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tools/tests/test_java_refactor_auditor.py b/tools/tests/test_java_refactor_auditor.py new file mode 100644 index 000000000..24148812e --- /dev/null +++ b/tools/tests/test_java_refactor_auditor.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +import subprocess +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] + + +def test_java_refactor_auditor_flags_println(tmp_path) -> None: + java = tmp_path / "Sample.java" + java.write_text("class Sample { void run() { System.out.println(\"x\"); } }\n", encoding="utf-8") + result = subprocess.run( + [sys.executable, str(ROOT / "tools" / "java_refactor_auditor.py"), str(java)], + cwd=ROOT, + capture_output=True, + text=True, + check=False, + ) + assert result.returncode == 1 + assert "System.out.println" in result.stdout + + +def test_java_refactor_auditor_passes_clean_file(tmp_path) -> None: + java = tmp_path / "Clean.java" + java.write_text("class Clean { int value() { return 1; } }\n", encoding="utf-8") + result = subprocess.run( + [sys.executable, str(ROOT / "tools" / "java_refactor_auditor.py"), str(java)], + cwd=ROOT, + capture_output=True, + text=True, + check=False, + ) + assert result.returncode == 0 + assert "passed" in result.stdout