Check that _build.cpp.hpp files have correct include ordering and section comments. Required structure (when both same-level AND subdir includes exist): // begin current directory includes #include "fl/channels/channel.cpp.hpp" ... // begin sub directory i
(src_dir: Path)
| 352 | |
| 353 | |
| 354 | def _check_build_include_order(src_dir: Path) -> list[str]: |
| 355 | """ |
| 356 | Check that _build.cpp.hpp files have correct include ordering and section comments. |
| 357 | |
| 358 | Required structure (when both same-level AND subdir includes exist): |
| 359 | |
| 360 | // begin current directory includes |
| 361 | #include "fl/channels/channel.cpp.hpp" |
| 362 | ... |
| 363 | |
| 364 | // begin sub directory includes |
| 365 | #include "fl/channels/detail/_build.cpp.hpp" |
| 366 | ... |
| 367 | |
| 368 | Rules: |
| 369 | 1. Same-level *.cpp.hpp includes BEFORE subdirectory _build.cpp.hpp includes. |
| 370 | 2. When both sections exist, require section comment markers with a blank line before each. |
| 371 | 3. Files with only one kind of include do NOT need section comments. |
| 372 | |
| 373 | Returns: |
| 374 | list of violation strings |
| 375 | """ |
| 376 | violations: list[str] = [] |
| 377 | |
| 378 | include_pattern = re.compile(r'^\s*#include\s+"([^"]+\.cpp\.hpp)"', re.MULTILINE) |
| 379 | |
| 380 | for build_hpp in src_dir.rglob(BUILD_HPP): |
| 381 | content = build_hpp.read_text(encoding="utf-8") |
| 382 | lines = content.splitlines() |
| 383 | namespace_path = _get_namespace_path(build_hpp, src_dir) |
| 384 | if namespace_path is None: |
| 385 | continue |
| 386 | |
| 387 | includes = list(include_pattern.finditer(content)) |
| 388 | if not includes: |
| 389 | continue |
| 390 | |
| 391 | rel_file = build_hpp.relative_to(PROJECT_ROOT).as_posix() |
| 392 | |
| 393 | # Classify includes |
| 394 | same_level_lines: list[int] = [] |
| 395 | subdir_lines: list[int] = [] |
| 396 | |
| 397 | for match in includes: |
| 398 | included_path = match.group(1) |
| 399 | line_num = _get_line_number(content, match.start()) |
| 400 | |
| 401 | if included_path.endswith(BUILD_HPP): |
| 402 | subdir_lines.append(line_num) |
| 403 | else: |
| 404 | same_level_lines.append(line_num) |
| 405 | |
| 406 | has_both = bool(same_level_lines) and bool(subdir_lines) |
| 407 | |
| 408 | # Check ordering: all same-level must come before all subdir |
| 409 | if has_both: |
| 410 | last_same = max(same_level_lines) |
| 411 | first_subdir = min(subdir_lines) |
no test coverage detected