Files
echoes-of-the-ash/count_sloc.py

89 lines
2.7 KiB
Python

import os
import subprocess
def count_lines():
try:
# Get list of tracked files
result = subprocess.run(['git', 'ls-files'], capture_output=True, text=True, check=True)
files = result.stdout.splitlines()
except subprocess.CalledProcessError:
print("Not a git repository or git error.")
return
stats = {}
total_effective = 0
total_files = 0
comments = {
'.py': '#',
'.js': '//',
'.jsx': '//',
'.ts': '//',
'.tsx': '//',
'.css': '/*', # Simple check, not perfect for block comments across lines or inline
'.html': '<!--',
'.json': None, # JSON doesn't standardized comments, but we count lines
'.yml': '#',
'.yaml': '#',
'.sh': '#',
'.md': None
}
ignored_dirs = ['old', 'migrations', 'images', 'claude_sonnet_logs', 'data', 'gamedata/items.json'] # items.json can be huge
for file_path in files:
if any(part in file_path.split('/') for part in ignored_dirs):
continue
# Determine extension
_, ext = os.path.splitext(file_path)
if ext not in comments and ext not in ['.json', '.md']:
# Skip unknown extensions or binary files if not handled
# But let's verify if text
continue
try:
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
lines = f.readlines()
except Exception:
continue
effective_lines = 0
file_total = 0
comment_char = comments.get(ext)
for line in lines:
line_strip = line.strip()
if not line_strip:
continue
file_total += 1
if comment_char:
if line_strip.startswith(comment_char):
continue
# Special handling for CSS/HTML block comments would be needed for perfect accuracy
# keeping it simple: if it starts with comment char, ignore.
effective_lines += 1
if ext not in stats:
stats[ext] = {'files': 0, 'lines': 0}
stats[ext]['files'] += 1
stats[ext]['lines'] += effective_lines
total_effective += effective_lines
total_files += 1
print(f"{'Language':<15} {'Files':<10} {'Effective Lines':<15}")
print("-" * 40)
for ext, data in sorted(stats.items(), key=lambda x: x[1]['lines'], reverse=True):
lang = ext if ext else "No Ext"
print(f"{lang:<15} {data['files']:<10} {data['lines']:<15}")
print("-" * 40)
print(f"{'Total':<15} {total_files:<10} {total_effective:<15}")
if __name__ == "__main__":
count_lines()