Harden code-review tooling and align REVIEW-PROCESS.md with mxaccessgw
- regen-readme.py: use `python` not the broken `python3` Store alias in the generated note and docstring; --check now also fails when a module header's "Open findings" count disagrees with finding statuses or a finding has an unrecognised Status (find_inconsistencies) - REVIEW-PROCESS.md: rewritten for mxaccessgw (was describing ScadaLink) — MxGateway.* modules, "mxaccessgw conventions" checklist category, gateway.md/docs/ design context, `python` command - scripts/check-code-reviews-readme.ps1: CI/pre-commit wrapper for regen-readme.py --check - code-reviews/test_regen_readme.py: dependency-free parser tests - code-reviews/README.md: regenerated Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,8 +6,12 @@ them into the single cross-module README.md (module status + pending/closed
|
||||
finding tables).
|
||||
|
||||
Usage:
|
||||
python3 code-reviews/regen-readme.py # rewrite README.md
|
||||
python3 code-reviews/regen-readme.py --check # exit 1 if README.md is stale
|
||||
python code-reviews/regen-readme.py # rewrite README.md
|
||||
python code-reviews/regen-readme.py --check # exit 1 if stale or inconsistent
|
||||
|
||||
`--check` fails when README.md is out of date OR when a module's header
|
||||
`Open findings` count disagrees with its finding statuses, or a finding
|
||||
carries an unrecognised Status value.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -19,11 +23,12 @@ ROOT = Path(__file__).resolve().parent
|
||||
README = ROOT / "README.md"
|
||||
|
||||
PENDING_STATUSES = {"Open", "In Progress"}
|
||||
KNOWN_STATUSES = {"Open", "In Progress", "Resolved", "Won't Fix", "Deferred"}
|
||||
SEVERITY_ORDER = {"Critical": 0, "High": 1, "Medium": 2, "Low": 3}
|
||||
|
||||
GENERATED_NOTE = (
|
||||
"<!-- GENERATED FILE - do not edit by hand. "
|
||||
"Regenerate with: python3 code-reviews/regen-readme.py -->"
|
||||
"Regenerate with: python code-reviews/regen-readme.py -->"
|
||||
)
|
||||
|
||||
|
||||
@@ -169,6 +174,32 @@ def build_readme(modules: list[dict]) -> str:
|
||||
return "\n".join(out) + "\n"
|
||||
|
||||
|
||||
def find_inconsistencies(modules: list[dict]) -> list[str]:
|
||||
"""Return human-readable problems in the per-module findings.md files.
|
||||
|
||||
Checks that each module header's `Open findings` count agrees with its
|
||||
finding statuses, and that every finding carries a known Status value.
|
||||
"""
|
||||
issues: list[str] = []
|
||||
for m in modules:
|
||||
open_n = sum(
|
||||
1 for f in m["findings"] if f["status"] in PENDING_STATUSES
|
||||
)
|
||||
declared = m["header"].get("Open findings", "").strip()
|
||||
if declared != str(open_n):
|
||||
issues.append(
|
||||
f"{m['module']}: header 'Open findings' = '{declared}' but "
|
||||
f"{open_n} finding(s) are Open/In Progress"
|
||||
)
|
||||
for f in m["findings"]:
|
||||
if f["status"] not in KNOWN_STATUSES:
|
||||
issues.append(
|
||||
f"{m['module']}: finding {f['id']} has unrecognised "
|
||||
f"Status '{f['status']}'"
|
||||
)
|
||||
return issues
|
||||
|
||||
|
||||
def main(argv: list[str]) -> int:
|
||||
check = "--check" in argv[1:]
|
||||
module_dirs = sorted(
|
||||
@@ -178,16 +209,24 @@ def main(argv: list[str]) -> int:
|
||||
)
|
||||
modules = [parse_module(d / "findings.md") for d in module_dirs]
|
||||
content = build_readme(modules)
|
||||
issues = find_inconsistencies(modules)
|
||||
if check:
|
||||
current = README.read_text(encoding="utf-8") if README.exists() else ""
|
||||
if current != content:
|
||||
stale = (
|
||||
README.read_text(encoding="utf-8") if README.exists() else ""
|
||||
) != content
|
||||
for issue in issues:
|
||||
print(f"inconsistent: {issue}", file=sys.stderr)
|
||||
if stale:
|
||||
print(
|
||||
"code-reviews/README.md is stale - run regen-readme.py",
|
||||
file=sys.stderr,
|
||||
)
|
||||
if stale or issues:
|
||||
return 1
|
||||
print("code-reviews/README.md is up to date.")
|
||||
print("code-reviews/README.md is up to date and consistent.")
|
||||
return 0
|
||||
for issue in issues:
|
||||
print(f"warning: {issue}", file=sys.stderr)
|
||||
README.write_text(content, encoding="utf-8", newline="\n")
|
||||
print(f"Wrote {README} ({len(modules)} modules).")
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user