- Docker: Delete 23 deprecated Dockerfiles, fix CI/CD to use Dockerfile.foxhunt-build - Config: Remove 36 .env files, keep 4 essential, delete config/environments/ - Docs: Archive 614 Wave D files to docs/archive/wave_d/, 95% reduction in root - Scripts: Delete 56 deprecated scripts, keep 58 production-critical (49% reduction) - Python: Organize 37 scripts into scripts/python/ subdirectories, delete ml/python/ - Build: Remove 1GB artifacts, delete old venvs, clean Python cache from git - Migrations: Delete deprecated directory (4,432 lines), remove duplicate database/migrations/ - Infrastructure: Delete deployment/ (61 files), docs/scripts/ (8 files) Total impact: ~2,500 files cleaned, 750MB+ space freed, zero production impact All deleted scripts backed up to archives. runpod/ and tests/runpod/ preserved. data_acquisition_service retained per user request.
146 lines
4.8 KiB
Python
146 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Analyze clippy warnings from output file."""
|
|
|
|
import re
|
|
from collections import defaultdict
|
|
from pathlib import Path
|
|
|
|
def analyze_clippy_output(filepath):
|
|
"""Analyze clippy output and categorize warnings."""
|
|
|
|
warning_types = defaultdict(list)
|
|
warning_counts = defaultdict(int)
|
|
file_warnings = defaultdict(list)
|
|
|
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
lines = f.readlines()
|
|
|
|
current_warning = None
|
|
current_file = None
|
|
|
|
for i, line in enumerate(lines):
|
|
# Extract warning type and location
|
|
if line.strip().startswith('warning:') and '-->' in (lines[i+1] if i+1 < len(lines) else ''):
|
|
warning_text = line.strip()
|
|
location = lines[i+1].strip()
|
|
|
|
# Extract file path
|
|
match = re.search(r'--> (.+):(\d+):(\d+)', location)
|
|
if match:
|
|
file_path = match.group(1)
|
|
line_num = match.group(2)
|
|
|
|
# Extract warning type from help text or note
|
|
warning_type = "unknown"
|
|
for j in range(i+1, min(i+10, len(lines))):
|
|
if 'clippy::' in lines[j]:
|
|
clippy_match = re.search(r'clippy::(\w+)', lines[j])
|
|
if clippy_match:
|
|
warning_type = clippy_match.group(1)
|
|
break
|
|
|
|
warning_counts[warning_type] += 1
|
|
file_warnings[file_path].append({
|
|
'type': warning_type,
|
|
'line': line_num,
|
|
'text': warning_text.replace('warning: ', '')
|
|
})
|
|
|
|
return warning_counts, file_warnings
|
|
|
|
def categorize_severity(warning_type):
|
|
"""Categorize warning by severity."""
|
|
|
|
critical = {
|
|
'correctness', 'suspicious', 'panic', 'unwrap_used',
|
|
'expect_used', 'indexing_slicing', 'panic_in_result_fn'
|
|
}
|
|
|
|
high = {
|
|
'perf', 'performance', 'nursery', 'cargo',
|
|
'missing_errors_doc', 'missing_panics_doc', 'must_use_candidate'
|
|
}
|
|
|
|
medium = {
|
|
'complexity', 'style', 'pedantic', 'redundant_clone',
|
|
'needless_pass_by_value', 'unnecessary_wraps'
|
|
}
|
|
|
|
low = {
|
|
'restriction', 'needless_raw_string_hashes', 'doc_markdown',
|
|
'missing_const_for_fn', 'default_numeric_fallback'
|
|
}
|
|
|
|
if warning_type in critical:
|
|
return 'CRITICAL'
|
|
elif warning_type in high:
|
|
return 'HIGH'
|
|
elif warning_type in medium:
|
|
return 'MEDIUM'
|
|
elif warning_type in low:
|
|
return 'LOW'
|
|
else:
|
|
return 'UNKNOWN'
|
|
|
|
def main():
|
|
filepath = Path('/home/jgrusewski/Work/foxhunt/clippy_full_output.txt')
|
|
|
|
warning_counts, file_warnings = analyze_clippy_output(filepath)
|
|
|
|
# Categorize by severity
|
|
severity_counts = defaultdict(int)
|
|
severity_types = defaultdict(list)
|
|
|
|
for warning_type, count in warning_counts.items():
|
|
severity = categorize_severity(warning_type)
|
|
severity_counts[severity] += count
|
|
severity_types[severity].append((warning_type, count))
|
|
|
|
print("=" * 80)
|
|
print("CLIPPY WARNING ANALYSIS")
|
|
print("=" * 80)
|
|
print()
|
|
|
|
# Summary by severity
|
|
print("SEVERITY SUMMARY:")
|
|
print("-" * 80)
|
|
for severity in ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'UNKNOWN']:
|
|
if severity in severity_counts:
|
|
print(f"{severity:10s}: {severity_counts[severity]:5d} warnings")
|
|
print()
|
|
|
|
# Top warnings by type
|
|
print("TOP WARNING TYPES:")
|
|
print("-" * 80)
|
|
sorted_warnings = sorted(warning_counts.items(), key=lambda x: x[1], reverse=True)
|
|
for warning_type, count in sorted_warnings[:20]:
|
|
severity = categorize_severity(warning_type)
|
|
print(f" [{severity:8s}] {warning_type:40s}: {count:5d}")
|
|
print()
|
|
|
|
# Files with most warnings
|
|
print("FILES WITH MOST WARNINGS:")
|
|
print("-" * 80)
|
|
sorted_files = sorted(file_warnings.items(), key=lambda x: len(x[1]), reverse=True)
|
|
for filepath, warnings in sorted_files[:15]:
|
|
print(f" {filepath:60s}: {len(warnings):5d} warnings")
|
|
print()
|
|
|
|
# Critical warnings detail
|
|
print("CRITICAL WARNINGS DETAIL:")
|
|
print("-" * 80)
|
|
for warning_type, count in sorted_warnings:
|
|
if categorize_severity(warning_type) == 'CRITICAL':
|
|
print(f"\n{warning_type.upper()} ({count} occurrences):")
|
|
# Find examples
|
|
examples = []
|
|
for filepath, warnings in file_warnings.items():
|
|
for w in warnings:
|
|
if w['type'] == warning_type and len(examples) < 3:
|
|
examples.append(f" - {filepath}:{w['line']} - {w['text']}")
|
|
for ex in examples:
|
|
print(ex)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|