@@ -0,0 +1,100 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user