Coverage for src / renaissance / project / project_scanner.py: 100%
45 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-09-09 14:04 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-09-09 14:04 +0000
1import json
2from os import system
3from pathlib import Path
6class ProjectScanner:
7 def find_sources(self) -> list[str]:
8 raise NotImplementedError
11class CppScanner(ProjectScanner):
12 def __init__(self, compile_commands_path: str = "compile_commands.json"):
13 self.compile_commands_path = compile_commands_path
15 def find_sources(self) -> list[str]:
16 if not Path(self.compile_commands_path).exists():
17 raise FileNotFoundError("compile_commands.json not found")
18 with Path(self.compile_commands_path).open() as f:
19 commands = json.load(f)
20 return sorted(set(entry["file"] for entry in commands if "file" in entry))
23class JavaScanner(ProjectScanner):
24 def __init__(self, root_dir: str = "."):
25 self.root_dir = root_dir
27 def find_sources(self) -> list[str]:
28 java_files = Path(self.root_dir).rglob("*.java")
29 return sorted(str(f) for f in java_files)
32class PythonScanner(ProjectScanner):
33 def __init__(self, root_dir: str = ".", package_dirs: list[str] | None = None):
35 # return (file_path for file_path in current_dir.iterdir() if is_python_file)
37 self.root_dir = root_dir
38 self.package_dirs = package_dirs or ["src", "lib", "test"]
39 # TODO: Why this hardcoded default heuristic?
40 # Why not what Python by default enforces or what is derived from the project config?
42 def find_sources(self) -> list[str]:
43 files = []
45 for d in self.package_dirs:
46 file_path = Path(self.root_dir) / d
47 if file_path.exists():
48 files.extend(file_path.glob("**/*.py"))
49 return sorted(files)
52class BearCppScanner(CppScanner):
53 def __init__(self, build_dir: str = ".", compile_commands_path: str = "compile_commands.json"):
54 super().__init__(compile_commands_path)
55 self.build_dir = build_dir
57 def run_bear(self):
58 print("Running Bear to generate compile_commands.json...")
59 result = system(f"bear -- make -C {self.build_dir}")
60 if result != 0:
61 raise RuntimeError("Bear failed to run or make failed.")
63 def find_sources(self) -> list[str]:
64 if not Path(self.compile_commands_path).exists():
65 self.run_bear()
66 return super().find_sources()