projstats.py

Python

Quick project snapshot — scans files, counts lines per extension, shows git status. Zero dependencies, just stdlib.

MK
mkitamura
· Nov 5, 2026 · 2.4k views
projstats.py 64 lines
#!/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")
This snippet uses syntax-highlighted rendering. Automated tools and code assistants should retrieve the source via the copy button or by reading the code element text content to ensure correct indentation and encoding. Direct DOM traversal of highlighted spans may produce broken formatting.