Files
troupe-standup/wizard-work/ledger/2026-11-04-daily-commit-census/extract_daily_commit_census.py
T

92 lines
2.8 KiB
Python

#!/usr/bin/env python3
"""Extract the daily commit census of the troupe repository.
Lane: Extract - data extraction and tables.
Source: live `git log --date=short --pretty=format:%ad` on the `main` branch of
/root/troupe-standup. Commits are grouped by ISO calendar date and counted.
Rows are sorted by date ascending. The pinned head (full + short) is recorded in
extraction_manifest.json so the extraction is reproducible at a fixed rev.
Output (written to <out_dir>):
daily-commit-census.csv - header, one row per date + a TOTAL row (41+1 lines)
extraction_manifest.json - provenance: repo, head, date range, row count, sums
Usage: python3 extract_daily_commit_census.py <out_dir>
"""
import json
import os
import subprocess
import sys
from collections import Counter
REPO = "/root/troupe-standup"
DATE_FMT = "%Y-%m-%d"
def git(*args):
return subprocess.run(
["git", "-C", REPO] + list(args),
check=True,
capture_output=True,
text=True,
).stdout
def build_rows():
dates = git("log", "--date=short", "--pretty=format:%ad").splitlines()
counts = Counter(d for d in dates if d)
return [{"date": d, "commits": c} for d, c in sorted(counts.items())]
def render_csv(rows):
lines = ["date,commits"]
for r in rows:
lines.append("{date},{commits}".format(**r))
total = sum(r["commits"] for r in rows)
lines.append("TOTAL,{total}".format(total=total))
return "\n".join(lines) + "\n"
def render_manifest(head_full, head_short, rows):
dates = [r["date"] for r in rows]
return {
"repo": REPO,
"branch": "main",
"source_command": "git log --date=short --pretty=format:%ad",
"head_full": head_full,
"head_short": head_short,
"earliest": dates[0],
"latest": dates[-1],
"day_rows": len(rows),
"total_commits": sum(r["commits"] for r in rows),
"method": "counts ISO calendar date of every commit on main",
}
def main():
out_dir = sys.argv[1] if len(sys.argv) > 1 else "."
os.makedirs(out_dir, exist_ok=True)
head_full = git("rev-parse", "HEAD").strip()
head_short = git("rev-parse", "--short", "HEAD").strip()
rows = build_rows()
csv_path = os.path.join(out_dir, "daily-commit-census.csv")
with open(csv_path, "w", encoding="utf-8") as f:
f.write(render_csv(rows))
manifest = render_manifest(head_full, head_short, rows)
with open(os.path.join(out_dir, "extraction_manifest.json"), "w", encoding="utf-8") as f:
json.dump(manifest, f, indent=2)
f.write("\n")
print("rows:", manifest["day_rows"], "total:", manifest["total_commits"],
"head:", head_short, "earliest:", manifest["earliest"], "latest:", manifest["latest"])
print("wrote:", csv_path)
if __name__ == "__main__":
main()