Gary Talent 05f42150a1
All checks were successful
Build / build (push) Successful in 1m19s
[olympic] Add new loc command to Makefile
2025-06-09 21:29:27 -05:00

60 lines
1.8 KiB
Python
Executable File

#! /usr/bin/env python3
from pathlib import Path
import argparse
def parse_args():
parser = argparse.ArgumentParser(description="Count and sort lines of code in selected files.")
parser.add_argument(
"--search-dirs", nargs="+", required=True,
help="List of directories to search (recursively)."
)
parser.add_argument(
"--include-exts", nargs="+", required=True,
help="List of file extensions to include (e.g. .cpp .hpp .py)"
)
parser.add_argument(
"--exclude-paths", nargs="*", default=[],
help="Full file paths to exclude from counting."
)
return parser.parse_args()
def main():
args = parse_args()
include_exts = tuple(args.include_exts)
exclude_paths = {Path(p).resolve() for p in args.exclude_paths}
files = []
for base in args.search_dirs:
path = Path(base)
if path.is_dir():
for file in path.rglob("*"):
try:
resolved_file = file.resolve()
if (
file.is_file()
and file.name.endswith(include_exts)
and resolved_file not in exclude_paths
):
files.append(str(resolved_file))
except FileNotFoundError:
continue
line_counts = []
total_lines = 0
for f in files:
try:
with open(f, "r", encoding="utf-8", errors="ignore") as file:
lines = sum(1 for _ in file)
line_counts.append((lines, f))
total_lines += lines
except Exception as e:
print(f"Failed to read {f}: {e}")
line_counts.sort()
for count, filename in line_counts:
print(f"{count:>7} {filename}")
print(f"{total_lines:>7} total")
if __name__ == "__main__":
main()