Add per-module code review tree under code-reviews/
Set up the code review process scaffolding adapted to mxaccessgw and
record a full per-module review of every src/MxGateway.* project at
commit 6c64030.
- code-reviews/_template/findings.md: per-module findings template
- code-reviews/regen-readme.py: generates README.md from findings.md
files; --check fails if stale
- code-reviews/<Module>/findings.md: reviews for Contracts, Server,
Worker, Tests, Worker.Tests, IntegrationTests (74 findings:
1 Critical, 10 High, 23 Medium, 40 Low; all Open)
- code-reviews/README.md: generated cross-module index
- REVIEW-PROCESS.md: review process document
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Regenerate code-reviews/README.md from the per-module findings.md files.
|
||||
|
||||
The per-module findings.md files are the source of truth. This script aggregates
|
||||
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
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
README = ROOT / "README.md"
|
||||
|
||||
PENDING_STATUSES = {"Open", "In Progress"}
|
||||
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 -->"
|
||||
)
|
||||
|
||||
|
||||
def cell(value: str) -> str:
|
||||
"""Escape a value for safe inclusion in a markdown table cell."""
|
||||
return value.replace("|", "\\|").strip()
|
||||
|
||||
|
||||
def summarize(value: str, limit: int = 240) -> str:
|
||||
"""Trim a long description to a single-cell-friendly summary."""
|
||||
value = value.strip()
|
||||
if len(value) <= limit:
|
||||
return value
|
||||
return value[: limit - 1].rstrip() + "…"
|
||||
|
||||
|
||||
def first_table(text: str) -> dict[str, str]:
|
||||
"""Parse the first contiguous block of '| key | value |' rows into a dict."""
|
||||
rows: dict[str, str] = {}
|
||||
started = False
|
||||
for line in text.splitlines():
|
||||
stripped = line.strip()
|
||||
if stripped.startswith("|"):
|
||||
started = True
|
||||
cells = [c.strip() for c in stripped.strip("|").split("|")]
|
||||
if len(cells) >= 2:
|
||||
key, value = cells[0], cells[1]
|
||||
if key and not set(key) <= {"-", ":"} and key != "Field":
|
||||
rows[key] = value
|
||||
elif started:
|
||||
break
|
||||
return rows
|
||||
|
||||
|
||||
def parse_module(findings_path: Path) -> dict:
|
||||
"""Parse one module's findings.md into its header and finding list."""
|
||||
text = findings_path.read_text(encoding="utf-8")
|
||||
module = findings_path.parent.name
|
||||
parts = re.split(r"^##\s+Findings\s*$", text, maxsplit=1, flags=re.M)
|
||||
header = first_table(parts[0])
|
||||
findings: list[dict] = []
|
||||
if len(parts) > 1:
|
||||
for chunk in re.split(r"^###\s+", parts[1], flags=re.M)[1:]:
|
||||
fid = chunk.splitlines()[0].strip()
|
||||
tbl = first_table(chunk)
|
||||
desc_m = re.search(
|
||||
r"\*\*Description:\*\*\s*(.*?)(?=\n\*\*|\Z)", chunk, re.S
|
||||
)
|
||||
desc = re.sub(r"\s+", " ", desc_m.group(1)).strip() if desc_m else ""
|
||||
findings.append(
|
||||
{
|
||||
"id": fid,
|
||||
"severity": tbl.get("Severity", ""),
|
||||
"category": tbl.get("Category", ""),
|
||||
"location": tbl.get("Location", ""),
|
||||
"status": tbl.get("Status", ""),
|
||||
"description": desc,
|
||||
}
|
||||
)
|
||||
return {"module": module, "header": header, "findings": findings}
|
||||
|
||||
|
||||
def build_readme(modules: list[dict]) -> str:
|
||||
modules = sorted(modules, key=lambda m: m["module"])
|
||||
all_findings = [
|
||||
dict(f, module=m["module"]) for m in modules for f in m["findings"]
|
||||
]
|
||||
pending = [f for f in all_findings if f["status"] in PENDING_STATUSES]
|
||||
closed = [
|
||||
f
|
||||
for f in all_findings
|
||||
if f["status"] and f["status"] not in PENDING_STATUSES
|
||||
]
|
||||
|
||||
def sev_key(f: dict) -> tuple:
|
||||
return (SEVERITY_ORDER.get(f["severity"], 9), f["id"])
|
||||
|
||||
pending.sort(key=sev_key)
|
||||
closed.sort(key=sev_key)
|
||||
|
||||
out: list[str] = [
|
||||
"# Code Reviews",
|
||||
"",
|
||||
GENERATED_NOTE,
|
||||
"",
|
||||
"Cross-module code review index for the `mxaccessgw` codebase. The review "
|
||||
"process is defined in [../REVIEW-PROCESS.md](../REVIEW-PROCESS.md).",
|
||||
"",
|
||||
"Each module's `findings.md` is the source of truth; this file is generated "
|
||||
"from them by `regen-readme.py` and must not be edited by hand.",
|
||||
"",
|
||||
"## Module status",
|
||||
"",
|
||||
"| Module | Reviewer | Date | Commit | Status | Open | Total |",
|
||||
"|---|---|---|---|---|---|---|",
|
||||
]
|
||||
for m in modules:
|
||||
h = m["header"]
|
||||
open_n = sum(
|
||||
1 for f in m["findings"] if f["status"] in PENDING_STATUSES
|
||||
)
|
||||
out.append(
|
||||
f"| [{m['module']}]({m['module']}/findings.md) "
|
||||
f"| {cell(h.get('Reviewer', ''))} "
|
||||
f"| {cell(h.get('Review date', ''))} "
|
||||
f"| {cell(h.get('Commit reviewed', ''))} "
|
||||
f"| {cell(h.get('Status', ''))} "
|
||||
f"| {open_n} | {len(m['findings'])} |"
|
||||
)
|
||||
|
||||
out += ["", "## Pending findings", ""]
|
||||
out.append(
|
||||
"Findings with status `Open` or `In Progress`, ordered by severity."
|
||||
)
|
||||
out.append("")
|
||||
if pending:
|
||||
out.append("| ID | Severity | Category | Location | Description |")
|
||||
out.append("|---|---|---|---|---|")
|
||||
for f in pending:
|
||||
out.append(
|
||||
f"| {cell(f['id'])} | {cell(f['severity'])} "
|
||||
f"| {cell(f['category'])} | {cell(f['location'])} "
|
||||
f"| {cell(summarize(f['description']))} |"
|
||||
)
|
||||
else:
|
||||
out.append("_No pending findings._")
|
||||
|
||||
out += ["", "## Closed findings", ""]
|
||||
out.append("Findings with status `Resolved`, `Won't Fix`, or `Deferred`.")
|
||||
out.append("")
|
||||
if closed:
|
||||
out.append("| ID | Severity | Status | Category | Location |")
|
||||
out.append("|---|---|---|---|---|")
|
||||
for f in closed:
|
||||
out.append(
|
||||
f"| {cell(f['id'])} | {cell(f['severity'])} "
|
||||
f"| {cell(f['status'])} | {cell(f['category'])} "
|
||||
f"| {cell(f['location'])} |"
|
||||
)
|
||||
else:
|
||||
out.append("_No closed findings._")
|
||||
|
||||
return "\n".join(out) + "\n"
|
||||
|
||||
|
||||
def main(argv: list[str]) -> int:
|
||||
check = "--check" in argv[1:]
|
||||
module_dirs = sorted(
|
||||
d
|
||||
for d in ROOT.iterdir()
|
||||
if d.is_dir() and d.name != "_template" and (d / "findings.md").is_file()
|
||||
)
|
||||
modules = [parse_module(d / "findings.md") for d in module_dirs]
|
||||
content = build_readme(modules)
|
||||
if check:
|
||||
current = README.read_text(encoding="utf-8") if README.exists() else ""
|
||||
if current != content:
|
||||
print(
|
||||
"code-reviews/README.md is stale - run regen-readme.py",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
print("code-reviews/README.md is up to date.")
|
||||
return 0
|
||||
README.write_text(content, encoding="utf-8", newline="\n")
|
||||
print(f"Wrote {README} ({len(modules)} modules).")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main(sys.argv))
|
||||
Reference in New Issue
Block a user