Files
troupe-standup/wizard-work/spark/code_stats.py
T

80 lines
2.2 KiB
Python

#!/usr/bin/env python3
"""Code statistics analyzer for Python files."""
import ast
import os
import sys
def analyze_file(filepath: str) -> dict:
"""Analyze a single Python file and return stats."""
stats = {
'lines': 0,
'functions': 0,
'classes': 0,
'imports': 0
}
try:
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
stats['lines'] = content.count('\n')
tree = ast.parse(content)
for node in ast.walk(tree):
if isinstance(node, ast.FunctionDef):
stats['functions'] += 1
elif isinstance(node, ast.ClassDef):
stats['classes'] += 1
elif isinstance(node, (ast.Import, ast.ImportFrom)):
stats['imports'] += 1
except SyntaxError:
pass
return stats
def analyze_directory(directory: str) -> dict:
"""Analyze all Python files in a directory recursively."""
total = {
'files': 0,
'lines': 0,
'functions': 0,
'classes': 0,
'imports': 0
}
for root, _, files in os.walk(directory):
for filename in files:
if filename.endswith('.py'):
filepath = os.path.join(root, filename)
stats = analyze_file(filepath)
total['files'] += 1
total['lines'] += stats['lines']
total['functions'] += stats['functions']
total['classes'] += stats['classes']
total['imports'] += stats['imports']
return total
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Usage: python code_stats.py <directory_or_file>")
sys.exit(1)
target = sys.argv[1]
if os.path.isfile(target):
stats = analyze_file(target)
stats['files'] = 1
print(f"File: {target}")
else:
stats = analyze_directory(target)
print(f"Directory: {target}")
print(f"Files: {stats['files']}")
print(f"Lines: {stats['lines']}")
print(f"Functions: {stats['functions']}")
print(f"Classes: {stats['classes']}")
print(f"Imports: {stats['imports']}")