Validate the content of each build file in src/fl/build/: - Flat files (no +): include ALL .cpp.hpp from mapped dir, no _build.cpp.hpp - Recursive files (+): include exactly one _build.cpp.hpp from mapped dir Returns: list of violation strings
(src_dir: Path, cpp_hpp_by_dir: CppHppByDir)
| 756 | |
| 757 | |
| 758 | def _check_build_file_content(src_dir: Path, cpp_hpp_by_dir: CppHppByDir) -> list[str]: |
| 759 | """ |
| 760 | Validate the content of each build file in src/fl/build/: |
| 761 | - Flat files (no +): include ALL .cpp.hpp from mapped dir, no _build.cpp.hpp |
| 762 | - Recursive files (+): include exactly one _build.cpp.hpp from mapped dir |
| 763 | |
| 764 | Returns: |
| 765 | list of violation strings |
| 766 | """ |
| 767 | violations: list[str] = [] |
| 768 | build_dir = src_dir / "fl" / "build" |
| 769 | if not build_dir.exists(): |
| 770 | return violations |
| 771 | |
| 772 | include_pattern = re.compile(r'^\s*#include\s+"([^"]+\.cpp\.hpp)"', re.MULTILINE) |
| 773 | |
| 774 | for build_file in sorted(build_dir.glob("*.cpp")): |
| 775 | content = build_file.read_text(encoding="utf-8") |
| 776 | rel_file = build_file.relative_to(PROJECT_ROOT).as_posix() |
| 777 | |
| 778 | dir_path, is_recursive = _parse_build_filename(build_file.name) |
| 779 | |
| 780 | # Get all .cpp.hpp includes from this build file |
| 781 | impl_includes: list[str] = [] |
| 782 | for match in include_pattern.finditer(content): |
| 783 | impl_includes.append(match.group(1)) |
| 784 | |
| 785 | if is_recursive: |
| 786 | # Must include exactly one _build.cpp.hpp from the mapped directory |
| 787 | expected_build_hpp = (dir_path + "/" + BUILD_HPP) if dir_path else BUILD_HPP |
| 788 | build_hpp_includes = [i for i in impl_includes if i.endswith(BUILD_HPP)] |
| 789 | non_build_includes = [i for i in impl_includes if not i.endswith(BUILD_HPP)] |
| 790 | |
| 791 | if len(build_hpp_includes) == 0: |
| 792 | violations.append( |
| 793 | f"{rel_file}: Recursive build file must include '{expected_build_hpp}'." |
| 794 | ) |
| 795 | elif len(build_hpp_includes) > 1: |
| 796 | violations.append( |
| 797 | f"{rel_file}: Recursive build file must include exactly one _build.cpp.hpp, " |
| 798 | f"found {len(build_hpp_includes)}: {build_hpp_includes}" |
| 799 | ) |
| 800 | elif build_hpp_includes[0] != expected_build_hpp: |
| 801 | violations.append( |
| 802 | f"{rel_file}: Expected include '{expected_build_hpp}', " |
| 803 | f"found '{build_hpp_includes[0]}'." |
| 804 | ) |
| 805 | |
| 806 | if non_build_includes: |
| 807 | violations.append( |
| 808 | f"{rel_file}: Recursive build file should only include one _build.cpp.hpp, " |
| 809 | f"found extra .cpp.hpp includes: {non_build_includes}" |
| 810 | ) |
| 811 | else: |
| 812 | # Flat: must include ALL .cpp.hpp from mapped dir (excluding _build.cpp.hpp) |
| 813 | # Must NOT include any _build.cpp.hpp |
| 814 | mapped_dir = src_dir / dir_path if dir_path else src_dir |
| 815 | if not mapped_dir.exists(): |