3"""Which files ``check_doc_attachment.py`` reads.
5Split out of the checker (#359) so the scope is one small, readable thing
6rather than five constants scattered above 1600 lines of rules. A scope that
7is hard to find is a scope nobody re-reads, and a checker whose roots quietly
8stopped describing the tree is the defect this repository has now hit five
9times -- see the ``check_lint_coverage.py`` docstring for the tally.
12from __future__
import annotations
15from pathlib
import Path
17REPO_ROOT = Path(__file__).resolve().parents[2]
22SCAN_ROOTS = (
"libs",
"port",
"examples",
"tools",
"apps",
"tests")
25EXCLUDED_PARTS = frozenset(
40SOURCE_SUFFIXES = (
".c",
".h")
43def iter_sources(targets: list[Path]) -> list[Path]:
44 """Every in-scope source file under ``targets``."""
46 for target
in targets:
48 if target.suffix
in SOURCE_SUFFIXES:
51 for dirpath, dirnames, filenames
in os.walk(target):
52 dirnames[:] = [d
for d
in dirnames
if d
not in EXCLUDED_PARTS]
54 if not fn.endswith(SOURCE_SUFFIXES):
56 p = Path(dirpath) / fn
57 if EXCLUDED_PARTS & set(p.relative_to(REPO_ROOT).parts):
60 return sorted(set(out))
63def default_targets() -> list[Path]:
64 """Every first-party root that exists in this checkout."""
65 return [REPO_ROOT / r
for r
in SCAN_ROOTS
if (REPO_ROOT / r).is_dir()]