62 lines
1.7 KiB
Python
Executable File
62 lines
1.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Verify a standup draft contains required sections with at least one bullet each.
|
|
|
|
Required sections (case-insensitive headings):
|
|
Yesterday, Today, Blockers
|
|
|
|
Exit codes:
|
|
0 all required sections present and non-empty
|
|
1 one or more sections missing or empty
|
|
2 bad invocation or unreadable file
|
|
"""
|
|
import re
|
|
import sys
|
|
|
|
REQUIRED = ["yesterday", "today", "blockers"]
|
|
|
|
|
|
def verify(path: str):
|
|
try:
|
|
with open(path, "r", encoding="utf-8") as f:
|
|
text = f.read()
|
|
except OSError as exc:
|
|
return 2, [f"cannot read file: {exc}"]
|
|
|
|
lower = text.lower()
|
|
faults = []
|
|
for section in REQUIRED:
|
|
# Match heading line exactly, allowing optional ATX markers (##, ###, etc.)
|
|
if not re.search(rf"^#{{0,6}}\s*{re.escape(section)}\s*$", lower, re.MULTILINE):
|
|
faults.append(f"missing section: {section}")
|
|
continue
|
|
# Extract up to 400 chars after the heading
|
|
idx = lower.find(section)
|
|
chunk = lower[idx: idx + 400]
|
|
if not re.search(r"^\s*[-*]\s+.+", chunk, re.MULTILINE):
|
|
faults.append(f"section {section} has no bullets")
|
|
|
|
return (1 if faults else 0), faults
|
|
|
|
|
|
def main() -> int:
|
|
if len(sys.argv) < 2:
|
|
print("usage: verify_standup_draft.py <file>", file=sys.stderr)
|
|
return 2
|
|
|
|
rc, faults = verify(sys.argv[1])
|
|
if rc == 0:
|
|
print("VERDICT: PASS")
|
|
elif rc == 1:
|
|
print("VERDICT: FAIL")
|
|
for f in faults:
|
|
print(f" - {f}")
|
|
else:
|
|
print("VERDICT: UNGRADABLE")
|
|
for f in faults:
|
|
print(f" - {f}")
|
|
return rc
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|