85 lines
3.7 KiB
Python
85 lines
3.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Fast post-commit CHECK for the citation_hash_class.py portable-default refactor.
|
|
|
|
Refactored (forge lane: Refactor) to locate the genuine pre-refactor original
|
|
by walking git history instead of anchoring on HEAD -- the same "anchor on HEAD"
|
|
defect that broke verify_path_claim_dry_refactor.py before it was fixed to use
|
|
find_original_commit(). Once the refactor lands in a commit, HEAD carries the
|
|
portable __file__-based expression, so `git show HEAD:TOOL` for the "original"
|
|
is stale and always reports FAIL on the host-literal and portable-expr legs.
|
|
This walks the file's commit history for the newest commit that still carries
|
|
the host-literal default and lacks the portable expression.
|
|
"""
|
|
import py_compile, subprocess, sys, os
|
|
|
|
REPO = "/root/troupe-standup"
|
|
TOOL = "tools/citation_hash_class.py"
|
|
VERIFIER = "wizard-work/forge/verify_citation_hash_class_portable_default.py"
|
|
|
|
PORTABLE_EXPR = "os.path.dirname(os.path.dirname(os.path.abspath(__file__)))"
|
|
HARD_CODED = "default='/root/troupe-standup'"
|
|
|
|
tool_path = os.path.join(REPO, TOOL)
|
|
checks = []
|
|
|
|
def chk(label, ok):
|
|
checks.append(ok)
|
|
print(f" {'PASS' if ok else 'FAIL'} {label}")
|
|
|
|
|
|
def git_commits_touching(path):
|
|
"""Newest-first list of commit shas that touched <path> in REPO."""
|
|
proc = subprocess.run(
|
|
["git", "-C", REPO, "log", "--format=%H", "--", path],
|
|
capture_output=True, text=True, check=True, timeout=60)
|
|
return [s for s in proc.stdout.split() if s]
|
|
|
|
|
|
def find_original_commit(path=TOOL):
|
|
"""Newest commit in <path>'s history whose --repo default is still the
|
|
host literal (the genuine pre-refactor original). Skips commits carrying
|
|
the portable __file__-based expression. Returns the sha or None."""
|
|
for sha in git_commits_touching(path):
|
|
txt = subprocess.run(
|
|
["git", "-C", REPO, "show", "%s:%s" % (sha, path)],
|
|
capture_output=True, text=True, timeout=60).stdout
|
|
if HARD_CODED in txt and PORTABLE_EXPR not in txt:
|
|
return sha
|
|
return None
|
|
|
|
|
|
text = open(tool_path).read()
|
|
chk("tool has portable DEFAULT_REPO", PORTABLE_EXPR in text)
|
|
chk("tool free of host literal", HARD_CODED not in text)
|
|
chk("tool compiles (py_compile)",
|
|
subprocess.run([sys.executable, "-m", "py_compile", tool_path]).returncode == 0)
|
|
|
|
orig_sha = find_original_commit()
|
|
if orig_sha:
|
|
head = subprocess.run(["git", "-C", REPO, "show", "%s:%s" % (orig_sha, TOOL)],
|
|
capture_output=True, text=True).stdout
|
|
chk("original carries host literal (commit %s)" % orig_sha[:8],
|
|
HARD_CODED in head)
|
|
chk("original lacks portable expr", PORTABLE_EXPR not in head)
|
|
else:
|
|
chk("original commit found", False)
|
|
|
|
r = subprocess.run([sys.executable, tool_path, "--selftest"],
|
|
capture_output=True, text=True, cwd=REPO, timeout=120)
|
|
chk("selftest 19/19 rc 0", r.returncode == 0 and "19 passed, 0 failed" in r.stdout)
|
|
chk("verifier committed to HEAD",
|
|
subprocess.run(["git", "-C", REPO, "cat-file", "-e", "HEAD:%s" % VERIFIER],
|
|
capture_output=True).returncode == 0)
|
|
# ---- verifier anchoring is post-landing-correct (no HEAD false-red) ------
|
|
vpath = os.path.join(REPO, VERIFIER)
|
|
verifier_src = open(vpath).read() if os.path.exists(vpath) else ""
|
|
chk("committed verifier history-walks its original (no HEAD anchoring false-red)",
|
|
"find_original_commit" in verifier_src and
|
|
'ORIG_SPEC = f"HEAD:{TOOL}"' not in verifier_src)
|
|
chk("origin/main advanced",
|
|
subprocess.run(["git", "-C", REPO, "rev-parse", "--verify", "origin/main"],
|
|
capture_output=True, text=True).returncode == 0)
|
|
|
|
print(f"\n{sum(checks)}/{len(checks)} checks pass")
|
|
sys.exit(0 if all(checks) else 1)
|