#!/usr/bin/env python3 """Run clangd diagnostics on every C++ source file in the project. Scans known source directories for .cpp and .h files, then runs clangd-query.py diagnostics on each one, reporting any errors or warnings. """ import subprocess import sys import os from pathlib import Path # Directories to scan (relative to project root). SOURCE_DIRS = [ "Source/Integration", "luprex/cpp/core", "luprex/cpp/drv", "luprex/cpp/wrap", "Plugins/UEWingman/Source/UEWingman/Public", "Plugins/UEWingman/Source/UEWingman/Private", "Plugins/UEWingman/Source/UEWingman/Handlers", "Plugins/UEWingman/Source/UEWingman/HalfBaked", ] # Files to skip (relative to project root). SKIP_FILES = set() EXTENSIONS = {".cpp", ".hpp", ".h", ".c"} def find_project_root(): """Walk up from this script's directory to find the project root.""" d = Path(__file__).resolve().parent.parent if (d / "build.py").exists(): return d # Fallback: assume cwd. return Path.cwd() def find_source_files(root): """Collect all source files from the known directories.""" files = [] for rel_dir in SOURCE_DIRS: d = root / rel_dir if not d.is_dir(): print(f"WARNING: directory not found: {rel_dir}", file=sys.stderr) continue for f in sorted(d.iterdir()): if f.is_file() and f.suffix in EXTENSIONS: rel = f.relative_to(root) if str(rel) not in SKIP_FILES: files.append(rel) return files def run_diagnostics(root, rel_path): """Run clangd-query.py diagnostics on a single file. Returns output lines.""" result = subprocess.run( [sys.executable, "tools/clangd-query.py", "diagnostics", str(rel_path)], cwd=root, capture_output=True, text=True, timeout=120, ) output = result.stdout.strip() if result.returncode != 0 and result.stderr.strip(): output += "\n" + result.stderr.strip() return output def main(): root = find_project_root() files = find_source_files(root) print(f"Found {len(files)} source files across {len(SOURCE_DIRS)} directories.\n") total_issues = 0 files_with_issues = 0 for i, rel_path in enumerate(files): label = f"[{i+1}/{len(files)}] {rel_path}" print(f"{label} ... ", end="", flush=True) try: output = run_diagnostics(root, rel_path) except subprocess.TimeoutExpired: print("TIMEOUT") continue if not output or "No problems found" in output or output.strip() == "No diagnostics.": print("ok") else: lines = [l for l in output.splitlines() if l.strip()] count = len(lines) total_issues += count files_with_issues += 1 print(f"{count} issue(s)") for line in lines: print(f" {line}") print(f"\nDone. {total_issues} issue(s) in {files_with_issues} file(s) out of {len(files)} checked.") if __name__ == "__main__": main()