-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathvalidate_codebase.py
More file actions
152 lines (120 loc) · 4.59 KB
/
Copy pathvalidate_codebase.py
File metadata and controls
152 lines (120 loc) · 4.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env python3
"""
Validation script for the sample codebase directory before indexing.
Performs pre-flight checks to detect common issues early.
"""
import os
import sys
from config import SUPPORTED_EXTENSIONS, MAX_FILE_SIZE_BYTES, MAX_FILE_SIZE_MB
IGNORED_DIRS = {"__pycache__", ".git", ".mypy_cache", ".pytest_cache", ".venv", "venv", "node_modules"}
def should_ignore_dir(dir_name):
"""Check if a directory should be ignored."""
return dir_name in IGNORED_DIRS or dir_name.startswith(".")
def validate_codebase(directory):
"""
Validate a codebase directory for indexing.
Returns:
tuple: (valid_files, skipped_files, warnings, errors)
"""
valid_files = []
skipped_files = []
warnings = []
errors = []
# Check if directory exists
if not os.path.exists(directory):
errors.append(f"Directory does not exist: {directory}")
return valid_files, skipped_files, warnings, errors
if not os.path.isdir(directory):
errors.append(f"Path is not a directory: {directory}")
return valid_files, skipped_files, warnings, errors
# Walk the directory and collect all files
found_files = []
unsupported_files = []
for root, dirs, files in os.walk(directory):
# Filter out directories we want to skip
dirs[:] = [d for d in dirs if not should_ignore_dir(d)]
for file in files:
# Skip hidden files
if file.startswith("."):
continue
path = os.path.join(root, file)
ext = os.path.splitext(file)[1].lower()
if ext in SUPPORTED_EXTENSIONS:
found_files.append(path)
else:
unsupported_files.append(path)
# Check if directory is empty
if not found_files and not unsupported_files:
errors.append("Directory is empty")
return valid_files, skipped_files, warnings, errors
# Report unsupported files
if unsupported_files:
warnings.append("Skipped:")
for path in unsupported_files:
warnings.append(f" {path}")
# Check that supported source files are present
if not found_files:
errors.append(f"No supported source files found (supported: {', '.join(sorted(SUPPORTED_EXTENSIONS))})")
return valid_files, skipped_files, warnings, errors
# Validate each supported file
for filepath in found_files:
try:
# Check if file is empty
size = os.path.getsize(filepath)
if size == 0:
skipped_files.append((filepath, "File is empty"))
continue
# Check if file exceeds size limit
if size > MAX_FILE_SIZE_BYTES:
skipped_files.append(
(filepath, f"Exceeds {MAX_FILE_SIZE_MB} MB size limit ({size / (1024 * 1024):.2f} MB)")
)
continue
# Try to read the file to check if it's readable
with open(filepath, "r", encoding="utf-8") as f:
f.read()
# If we got here, the file is valid
valid_files.append(filepath)
except PermissionError:
skipped_files.append((filepath, "Permission denied"))
except UnicodeDecodeError:
skipped_files.append((filepath, "Invalid text encoding"))
except OSError as e:
errors.append(f"Error reading file {filepath}: {e}")
except Exception as e:
errors.append(f"Unexpected error with file {filepath}: {e}")
return valid_files, skipped_files, warnings, errors
def main():
target = sys.argv[1] if len(sys.argv) > 1 else "./sample_codebase"
print(f"Validating codebase: {target}\n")
valid_files, skipped_files, warnings, errors = validate_codebase(target)
# Print errors
if errors:
print("[ERROR] Errors:")
for error in errors:
print(f" [ERROR] {error}")
# Print skipped files
if skipped_files:
print(f"\n[WARNING] Skipped files: {len(skipped_files)}")
for filepath, reason in skipped_files:
print(f" [WARNING] {filepath} ({reason})")
# Print warnings
if warnings:
for warning in warnings:
print(f"\n[WARNING] {warning}")
# Summary
print("\nValidation Summary")
print("-" * 20)
print(f"Valid: {len(valid_files)}")
print(f"Skipped: {len(skipped_files)}")
print(f"Errors: {len(errors)}")
# Determine exit code
if errors:
sys.exit(1)
elif not valid_files:
# Nothing valid to index
sys.exit(1)
else:
sys.exit(0)
if __name__ == "__main__":
main()