#!/usr/bin/env python3
"""projstats.py — Quick project snapshot for your README."""
import os
import json
import subprocess
from pathlib import Path
from datetime import datetime
def run(cmd):
try:
r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=10)
return r.stdout.strip()
except Exception:
return ""
def scan(root="."):
root = Path(root).resolve()
exts = {}
total_files = 0
total_lines = 0
for f in root.rglob("*"):
if f.is_file() and ".git" not in f.parts:
ext = f.suffix if f.suffix else "(none)"
exts[ext] = exts.get(ext, 0) + 1
total_files += 1
try:
total_lines += sum(1 for _ in f.open(errors="ignore"))
except (OSError, PermissionError):
pass
top = dict(sorted(exts.items(), key=lambda x: -x[1])[:12])
return {
"generated": datetime.utcnow().strftime("%Y-%m-%d %H:%M UTC"),
"directory": str(root),
"total_files": total_files,
"total_lines": total_lines,
"extensions": top,
"git": {
"branch": run("git rev-parse --abbrev-ref HEAD 2>/dev/null") or "n/a",
"commit": run("git log -1 --format='%h %s' 2>/dev/null") or "n/a",
"dirty": len(run("git status --porcelain 2>/dev/null").splitlines()),
},
}
def show(stats):
print()
print("=" * 50)
print(" Project Snapshot")
print("=" * 50)
print(f" Directory : {stats['directory']}")
print(f" Generated : {stats['generated']}")
print(f" Files : {stats['total_files']}")
print(f" Lines : {stats['total_lines']:,}")
print()
for ext, n in stats["extensions"].items():
bar = "#" * min(n, 30)
print(f" {ext:10s} {n:>5} {bar}")
g = stats["git"]
print(f"\n Branch : {g['branch']}")
print(f" Commit : {g['commit']}")
print(f" Dirty : {g['dirty']} file(s)")
print("=" * 50)
if __name__ == "__main__":
stats = scan()
show(stats)
out = "project-snapshot.json"
with open(out, "w") as f:
json.dump(stats, f, indent=2)
print(f"\n Saved -> {out}\n")