Targeted unity build check for a single file. Used in single-file linting mode (agent hook on save). Only checks the immediate directory — does not walk the full project tree. Rules: - If file is _build.cpp.hpp: all *.cpp.hpp files in the same directory must be listed in
(file_path: Path)
| 1086 | |
| 1087 | |
| 1088 | def check_single_file(file_path: Path) -> CheckResult: |
| 1089 | """ |
| 1090 | Targeted unity build check for a single file. |
| 1091 | |
| 1092 | Used in single-file linting mode (agent hook on save). Only checks the |
| 1093 | immediate directory — does not walk the full project tree. |
| 1094 | |
| 1095 | Rules: |
| 1096 | - If file is _build.cpp.hpp: all *.cpp.hpp files in the same directory |
| 1097 | must be listed in it. |
| 1098 | - If file is any other *.cpp.hpp: the _build.cpp.hpp in the same directory |
| 1099 | must include it. |
| 1100 | - If file is in src/fl/build/: validate preheaders and content. |
| 1101 | |
| 1102 | Returns: |
| 1103 | CheckResult with success flag and list of violations |
| 1104 | """ |
| 1105 | if not file_path.name.endswith((".cpp.hpp", ".cpp")): |
| 1106 | return CheckResult(success=True, violations=[]) |
| 1107 | |
| 1108 | src_dir = PROJECT_ROOT / SRC_DIR_NAME |
| 1109 | build_dir = src_dir / "fl" / "build" |
| 1110 | |
| 1111 | # Handle build files in src/fl/build/ |
| 1112 | try: |
| 1113 | file_path.relative_to(build_dir) |
| 1114 | # This is a build file — validate it |
| 1115 | cpp_hpp_by_dir: CppHppByDir = defaultdict(list) |
| 1116 | for cpp_hpp in src_dir.rglob(CPP_HPP_PATTERN): |
| 1117 | cpp_hpp_by_dir[cpp_hpp.parent].append(cpp_hpp) |
| 1118 | violations: list[str] = [] |
| 1119 | violations.extend(_check_build_file_preheaders(src_dir)) |
| 1120 | violations.extend(_check_build_file_content(src_dir, cpp_hpp_by_dir)) |
| 1121 | return CheckResult(success=len(violations) == 0, violations=violations) |
| 1122 | except ValueError: |
| 1123 | pass # Not in build dir |
| 1124 | |
| 1125 | if not file_path.name.endswith(".cpp.hpp"): |
| 1126 | return CheckResult(success=True, violations=[]) |
| 1127 | |
| 1128 | dir_path = file_path.parent |
| 1129 | |
| 1130 | if file_path.name == BUILD_CPP_HPP: |
| 1131 | # Editing a _build.cpp.hpp: check all sibling .cpp.hpp files are listed. |
| 1132 | cpp_hpp_by_dir = {dir_path: list(dir_path.glob(CPP_HPP_PATTERN))} |
| 1133 | violations = _check_cpp_hpp_files(src_dir, cpp_hpp_by_dir) |
| 1134 | else: |
| 1135 | # Editing a regular .cpp.hpp: check its parent _build.cpp.hpp includes it. |
| 1136 | build_hpp = dir_path / BUILD_CPP_HPP |
| 1137 | |
| 1138 | if not build_hpp.exists(): |
| 1139 | try: |
| 1140 | rel_dir = dir_path.relative_to(PROJECT_ROOT) |
| 1141 | except ValueError: |
| 1142 | return CheckResult(success=True, violations=[]) |
| 1143 | violations = [f"Missing {BUILD_CPP_HPP} in {rel_dir.as_posix()}/"] |
| 1144 | else: |
| 1145 | try: |
nothing calls this directly
no test coverage detected