101 lines
2.5 KiB
Python
101 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Подсчёт строк кода WESP (см. docs/README.full.md)."""
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
EXCLUDE_DIRS = {
|
|
".venv",
|
|
"vendor",
|
|
"data",
|
|
".git",
|
|
"legacy",
|
|
"__pycache__",
|
|
"node_modules",
|
|
".pytest_cache",
|
|
"htmlcov",
|
|
"dist",
|
|
"backups",
|
|
".cursor",
|
|
"test", # Windows venv test/Lib/site-packages
|
|
}
|
|
|
|
EXTS = {
|
|
".py": "Python",
|
|
".js": "JavaScript",
|
|
".css": "CSS",
|
|
".html": "HTML",
|
|
".sh": "Shell",
|
|
}
|
|
|
|
|
|
def should_skip(path: Path) -> bool:
|
|
try:
|
|
rel = path.relative_to(ROOT)
|
|
except ValueError:
|
|
return True
|
|
return any(part in EXCLUDE_DIRS for part in rel.parts)
|
|
|
|
|
|
def count_file(path: Path) -> tuple[int, int]:
|
|
text = path.read_text(encoding="utf-8", errors="ignore")
|
|
code = blank = 0
|
|
for line in text.splitlines():
|
|
if line.strip():
|
|
code += 1
|
|
else:
|
|
blank += 1
|
|
return code, blank
|
|
|
|
|
|
def main() -> None:
|
|
stats: dict[str, dict[str, int]] = {
|
|
ext: {"files": 0, "code": 0, "blank": 0} for ext in EXTS
|
|
}
|
|
|
|
for path in sorted(ROOT.rglob("*")):
|
|
if not path.is_file() or should_skip(path):
|
|
continue
|
|
ext = path.suffix.lower()
|
|
if ext not in EXTS:
|
|
continue
|
|
code, blank = count_file(path)
|
|
stats[ext]["files"] += 1
|
|
stats[ext]["code"] += code
|
|
stats[ext]["blank"] += blank
|
|
|
|
print(f"WESP LOC — {ROOT}")
|
|
print(f"{'Language':<12} {'files':>6} {'code':>8} {'blank':>8}")
|
|
print("-" * 38)
|
|
total = {"files": 0, "code": 0, "blank": 0}
|
|
for ext in sorted(EXTS, key=lambda e: -stats[e]["code"]):
|
|
s = stats[ext]
|
|
if not s["files"]:
|
|
continue
|
|
print(
|
|
f"{EXTS[ext]:<12} {s['files']:>6} {s['code']:>8} {s['blank']:>8}"
|
|
)
|
|
for k in total:
|
|
total[k] += s[k]
|
|
print("-" * 38)
|
|
print(f"{'SUM':<12} {total['files']:>6} {total['code']:>8} {total['blank']:>8}")
|
|
|
|
py_by_dir: dict[str, int] = {}
|
|
for path in sorted(ROOT.rglob("*.py")):
|
|
if should_skip(path):
|
|
continue
|
|
rel = path.relative_to(ROOT)
|
|
top = rel.parts[0] if len(rel.parts) > 1 else "."
|
|
code, _ = count_file(path)
|
|
py_by_dir[top] = py_by_dir.get(top, 0) + code
|
|
|
|
print("\nPython by top-level dir:")
|
|
for name, lines in sorted(py_by_dir.items(), key=lambda x: -x[1]):
|
|
print(f" {name:20} {lines:>6}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|