39 lines
1.5 KiB
Python
39 lines
1.5 KiB
Python
#!/usr/bin/env python3
|
|
# build_2026-10-31_ledger_dir_census.py
|
|
# Extract: rebuild the committed artifact '2026-10-31-ledger-dir-census.csv'
|
|
# from the LIVE filesystem of wizard-work/ledger/ (rel_path, size_bytes, sha256),
|
|
# byte-for-byte matching verify_ledger_dir_census.py's re_derive().
|
|
# Usage: python3 build_2026-10-31_ledger_dir_census.py [out_csv]
|
|
import os, sys, csv, hashlib
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__)) # wizard-work/ledger
|
|
REPO_ROOT = os.path.abspath(os.path.join(HERE, "..", "..")) # troupe-standup root
|
|
ARTIFACT = os.path.join(REPO_ROOT, "wizard-work", "ledger", "2026-10-31-ledger-dir-census.csv")
|
|
OUT = sys.argv[1] if len(sys.argv) > 1 else ARTIFACT
|
|
|
|
def sha256_of(path):
|
|
h = hashlib.sha256()
|
|
with open(path, "rb") as f:
|
|
for chunk in iter(lambda: f.read(1024 * 1024), b""):
|
|
h.update(chunk)
|
|
return h.hexdigest()
|
|
|
|
rows = []
|
|
for dirpath, dirnames, filenames in os.walk(HERE):
|
|
dirnames.sort()
|
|
for fn in sorted(filenames):
|
|
full = os.path.join(dirpath, fn)
|
|
if os.path.abspath(full) == os.path.abspath(OUT):
|
|
continue # do not include the artifact being built
|
|
rel = os.path.relpath(full, REPO_ROOT)
|
|
rows.append((rel, str(os.path.getsize(full)), sha256_of(full)))
|
|
rows.sort(key=lambda r: r[0])
|
|
|
|
os.makedirs(os.path.dirname(OUT), exist_ok=True)
|
|
with open(OUT, "w", newline="", encoding="utf-8") as f:
|
|
w = csv.writer(f)
|
|
w.writerow(["rel_path", "size_bytes", "sha256"])
|
|
w.writerows(rows)
|
|
|
|
print(f"wrote {len(rows)} rows -> {OUT}")
|