更新counter.py适配项目结构

This commit is contained in:
2026-03-12 02:41:26 +08:00
parent c992e3da24
commit e98093da94

163
counter.py Normal file
View File

@@ -0,0 +1,163 @@
#!/usr/bin/env python3
import os
import sys
import argparse
from pathlib import Path
if sys.platform == "win32":
sys.stdout.reconfigure(encoding="utf-8")
sys.stderr.reconfigure(encoding="utf-8")
def count_lines(file_path: Path) -> int:
try:
with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
return sum(1 for _ in f)
except Exception:
return 0
def should_include(file_path: Path, extensions: list[str]) -> bool:
if not extensions:
return True
return file_path.suffix in extensions
def walk_dir(root_path: Path, extensions: list[str], exclude_dirs: set[str]):
results = []
total_lines = 0
for root, dirs, files in os.walk(root_path):
dirs[:] = [d for d in dirs if d not in exclude_dirs]
rel_root = Path(root).relative_to(root_path)
indent = len(rel_root.parts) if str(rel_root) != "." else 0
prefix = " " * indent
if indent > 0:
print(f"{prefix}└── {rel_root.name}/")
for i, file in enumerate(files):
file_path = Path(root) / file
if not should_include(file_path, extensions):
continue
lines = count_lines(file_path)
total_lines += lines
results.append((file_path, lines, indent + 1))
is_last = (i == len(files) - 1) and not any(
should_include(Path(root) / f, extensions) for f in dirs
)
connector = "└──" if is_last else "├──"
print(f"{' ' * (indent + 1)}{connector} {file} ({lines} lines)")
return total_lines
def main_all():
directories = {
".": [".cpp", ".h", ".hlsl"],
"docs": [".md"],
}
total_all = 0
results = []
for directory, extensions in directories.items():
root_path = Path(directory)
if not root_path.exists():
continue
exclude_dirs = {
".git",
"build",
"Release",
"bin",
"__pycache__",
".ruff_cache",
"stbi",
}
print(f"\n{'=' * 60}")
print(f"项目文件统计: {root_path}")
print(f"后缀过滤: {extensions}")
print(f"{'=' * 60}\n")
total = walk_dir(root_path, extensions, exclude_dirs)
results.append((directory, total))
total_all += total
# 单独统计 stbi
stbi_path = Path("stbi")
if stbi_path.exists():
exclude_dirs = {".git", "__pycache__"}
print(f"\n{'=' * 60}")
print(f"项目文件统计: stbi (第三方库)")
print(f"后缀过滤: ['.cpp', '.h']")
print(f"{'=' * 60}\n")
total = walk_dir(stbi_path, [".cpp", ".h"], exclude_dirs)
results.append(("stbi", total))
total_all += total
print(f"\n{'=' * 60}")
print("汇总统计")
print(f"{'=' * 60}")
for name, lines in results:
print(f"{name:15} {lines:>10,}")
print(f"{'=' * 60}")
print(f"{'总计':15} {total_all:>10,}")
print(f"{'=' * 60}\n")
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="统计项目文件行数")
parser.add_argument(
"-e", "--extension", action="append", help="指定后缀名,如: .py .ts .js"
)
parser.add_argument("-d", "--directory", default=".", help="指定子文件夹路径")
parser.add_argument(
"-x", "--exclude", action="append", default=[], help="排除的文件夹"
)
parser.add_argument(
"--all",
action="store_true",
help="统计所有源码目录 (./docs/stbi)",
)
args = parser.parse_args()
if args.all:
main_all()
else:
root_path = Path(args.directory).resolve()
extensions = args.extension
exclude_dirs = {
".git",
"build",
"Release",
"bin",
"__pycache__",
}
exclude_dirs.update(args.exclude)
if not root_path.exists():
print(f"错误: 目录 {root_path} 不存在")
sys.exit(1)
print(f"\n{'=' * 60}")
print(f"项目文件统计: {root_path}")
if extensions:
print(f"后缀过滤: {extensions}")
print(f"{'=' * 60}\n")
total = walk_dir(root_path, extensions, exclude_dirs)
print(f"\n{'=' * 60}")
print(f"总行数: {total}")
print(f"{'=' * 60}\n")