All checks were successful
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Successful in 13m43s
wai-key-proxy's [[bin]] path = "src/alias.rs" (8da651a54) is built by cargo as the binary
wai-key-proxy, but the check knew only src/bin/ and the fixed entry names, so it reported the
file as never compiled and repo-checks went red on main. The check now reads each crate's
Cargo.toml target tables ([lib], [[bin]], [[example]], [[test]], [[bench]]) and counts their
path as an entry point. A path under [dependencies.x] or in an inline dependency table names
another crate and still counts for nothing: a scratch tree with a stray file, a dependency-table
path and an inline dependency path flagged all three, and a [[bin]] path flagged none.
Changelog: none
Co-Authored-By: Claude Opus 5.5 <[email protected]>
196 lines
8.1 KiB
Python
Executable file
196 lines
8.1 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""No library source file is unreachable from its crate root.
|
|
|
|
An orphan `.rs` file — one no `mod` declaration, `#[path]` attribute or
|
|
`include!` ever names — is not merely untested. It is **never compiled**, so it
|
|
is invisible to every check in this repository at once: not `cargo check`, not
|
|
`cargo test`, not clippy, not the conformance suites. It cannot fail, because
|
|
nothing ever asks it anything.
|
|
|
|
That makes it the strongest member of a family this repo keeps finding: a
|
|
feature-gated test run without `--features`, a platform-gated meter on a
|
|
single-platform runner, a conformance suite living in `main()` that
|
|
`cargo test` compiles and never runs. In each the code looks present and
|
|
reports nothing. An orphan file does not even type-check.
|
|
|
|
The hazard is not the dead code itself, it is the next reader. A file that
|
|
documents itself as doing something real, sitting in the tree beside files that
|
|
do, will eventually be wired in by someone who trusts its header — and it has
|
|
never been compiled, let alone verified.
|
|
|
|
What is NOT an orphan, and why the exclusions matter:
|
|
|
|
src/bin/*.rs cargo auto-discovers these as binaries
|
|
examples/, tests/, benches/ likewise auto-discovered
|
|
lib.rs, main.rs, mod.rs, build.rs entry points
|
|
a file Cargo.toml names as a target's `path` ([lib], [[bin]], [[example]],
|
|
[[test]], [[bench]]) an entry point too, compiled as that target
|
|
(2026-11-10: wai-key-proxy's
|
|
`[[bin]] path = "src/alias.rs"` was
|
|
reported though cargo builds it)
|
|
foo.rs beside a foo/ directory a directory module of the same name
|
|
|
|
A first pass at this check counted 77 orphans by missing the `src/bin`
|
|
exclusion. The real figure is a quarter of that and sits in one crate. A
|
|
detector that over-reports is as useless as one that under-reports, so the
|
|
exclusions are part of the check, not a convenience.
|
|
|
|
Usage:
|
|
scripts/check-orphan-sources.py # fail on anything not in BASELINE
|
|
scripts/check-orphan-sources.py --list # print every orphan found
|
|
|
|
The baseline pins what exists today so CI does not go red on a pre-existing
|
|
condition, and so the number can only go **down**. Removing a file from the
|
|
baseline is the point; adding one is a regression and should be argued for in a
|
|
commit message, not slipped in.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
# Pre-existing orphans, pinned 2026-10-02. All 25 are in jouleclaw-omni, which
|
|
# also holds `runtime/energy.rs` — a file documenting itself as measuring
|
|
# "actual GPU, CPU, ANE and DRAM energy consumption using Apple's IOReport
|
|
# framework" while in fact multiplying `getrusage` CPU seconds by a fixed 15 W
|
|
# and apportioning the result 60/20/20 across subsystems. It has never been
|
|
# compiled. That is precisely the trap this check exists to stop growing:
|
|
# a real meter with a per-rail liveness gate lives in `jouleclaw-energy`, and a
|
|
# reader who wires this one in instead gets a fabricated figure.
|
|
BASELINE = {
|
|
# Wants an `ffmpeg_next` dependency it does not have
|
|
# (`extern crate ffmpeg_next` -> E0463): a system library and a licensing
|
|
# choice, so it stays undeclared until that is decided. Every other file
|
|
# that was here on 2026-10-17 is now declared and type-checked.
|
|
"jouleclaw/jouleclaw-rs/crates/jouleclaw-omni/src/inference/video_decode.rs",
|
|
}
|
|
|
|
ENTRY = {"lib", "main", "mod", "build"}
|
|
|
|
DECL = re.compile(r"(?m)^\s*(?:pub(?:\([^)]*\))?\s+)?mod\s+([A-Za-z_]\w*)\s*;")
|
|
PATH_ATTR = re.compile(r'#\[path\s*=\s*"([^"]+)"\]')
|
|
INCLUDE = re.compile(r'include!\s*\(\s*"([^"]+)"')
|
|
|
|
|
|
def declared_names(src_root: str) -> set[str]:
|
|
"""Every module name the crate's own sources name, by any mechanism."""
|
|
names: set[str] = set()
|
|
for dirpath, dirs, files in os.walk(src_root):
|
|
dirs[:] = [d for d in dirs if d != "target"]
|
|
for f in files:
|
|
if not f.endswith(".rs"):
|
|
continue
|
|
try:
|
|
text = open(os.path.join(dirpath, f), encoding="utf-8", errors="ignore").read()
|
|
except OSError:
|
|
continue
|
|
names.update(DECL.findall(text))
|
|
for pat in (PATH_ATTR, INCLUDE):
|
|
for hit in pat.findall(text):
|
|
names.add(os.path.basename(hit).removesuffix(".rs"))
|
|
return names
|
|
|
|
|
|
TARGET_TABLE = re.compile(r"^\s*\[\[?\s*(lib|bin|example|test|bench)\s*\]\]?\s*(?:#.*)?$")
|
|
TABLE = re.compile(r"^\s*\[")
|
|
TARGET_PATH = re.compile(r'^\s*path\s*=\s*"([^"]+)"')
|
|
|
|
|
|
def target_paths(crate_dir: str) -> set[str]:
|
|
"""The files a crate's Cargo.toml names as a target's `path`, as absolute paths.
|
|
|
|
Only the target tables count. A `path` under [dependencies.x] or in an inline
|
|
dependency table names another crate, not a source of this one."""
|
|
paths: set[str] = set()
|
|
try:
|
|
lines = open(os.path.join(crate_dir, "Cargo.toml"), encoding="utf-8", errors="ignore").read().splitlines()
|
|
except OSError:
|
|
return paths
|
|
in_target = False
|
|
for line in lines:
|
|
if TABLE.match(line):
|
|
in_target = bool(TARGET_TABLE.match(line))
|
|
continue
|
|
if in_target:
|
|
m = TARGET_PATH.match(line)
|
|
if m:
|
|
paths.add(os.path.normpath(os.path.join(crate_dir, m.group(1))))
|
|
return paths
|
|
|
|
|
|
def find_orphans(repo: str) -> list[str]:
|
|
orphans: list[str] = []
|
|
seen_roots: dict[str, set[str]] = {}
|
|
seen_targets: dict[str, set[str]] = {}
|
|
for dirpath, dirs, files in os.walk(repo):
|
|
dirs[:] = [d for d in dirs if d not in ("target", ".git", "node_modules")]
|
|
rel = os.path.relpath(dirpath, repo)
|
|
if "/src" not in "/" + rel + "/":
|
|
continue
|
|
# cargo auto-discovers these; they are reachable without a `mod`.
|
|
if "/src/bin" in "/" + rel or rel.endswith("/src/bin"):
|
|
continue
|
|
rs = [f for f in files if f.endswith(".rs")]
|
|
if not rs:
|
|
continue
|
|
src_root = os.path.join(repo, rel.split("/src")[0], "src")
|
|
if src_root not in seen_roots:
|
|
seen_roots[src_root] = declared_names(src_root)
|
|
declared = seen_roots[src_root]
|
|
crate_dir = os.path.dirname(src_root)
|
|
if crate_dir not in seen_targets:
|
|
seen_targets[crate_dir] = target_paths(crate_dir)
|
|
targets = seen_targets[crate_dir]
|
|
for f in rs:
|
|
stem = f[:-3]
|
|
if stem in ENTRY:
|
|
continue
|
|
if os.path.normpath(os.path.join(repo, rel, f)) in targets:
|
|
continue # Cargo.toml builds it as a target
|
|
|
|
if stem in declared:
|
|
continue
|
|
if os.path.isdir(os.path.join(dirpath, stem)):
|
|
continue # a directory module of the same name
|
|
orphans.append(os.path.normpath(os.path.join(rel, f)))
|
|
return sorted(orphans)
|
|
|
|
|
|
def main() -> int:
|
|
repo = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
orphans = find_orphans(repo)
|
|
|
|
if "--list" in sys.argv:
|
|
for o in orphans:
|
|
mark = " (baseline)" if o in BASELINE else " NEW"
|
|
print(f"{o}{mark}")
|
|
print(f"\n{len(orphans)} orphan(s); {len(BASELINE)} pinned in the baseline")
|
|
return 0
|
|
|
|
new = [o for o in orphans if o not in BASELINE]
|
|
gone = sorted(BASELINE - set(orphans))
|
|
|
|
if gone:
|
|
print("These baseline orphans are reachable again, or were removed — good.")
|
|
print("Drop them from BASELINE in this script so the floor ratchets down:")
|
|
for g in gone:
|
|
print(f" {g}")
|
|
print()
|
|
|
|
if new:
|
|
print("New orphan source file(s): never compiled, so invisible to every")
|
|
print("check in this repo — cargo check, cargo test, clippy, conformance.")
|
|
print("Declare it with `mod`, move it under src/bin/, name it as a target's path in")
|
|
print("Cargo.toml, or delete it.\n")
|
|
for n in new:
|
|
print(f" {n}")
|
|
return 1
|
|
|
|
print(f"No new orphan sources ({len(orphans)} pinned, {len(BASELINE)} expected).")
|
|
return 1 if gone else 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|