mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-06-13 19:06:01 +00:00
a838546a2b
* chore(blocking-io): fail-loud repo-root resolution and shared detector CLI shim The three detectors resolved REPO_ROOT with depth-indexed Path(__file__).resolve().parents[4]. If a detector file ever moves to a different directory depth, scan roots resolve under the wrong directory and the detector reports zero findings with no error — a silent-zero failure shape for a detection tool. - Add support/detectors/repo_root.py: resolve the repo root by walking upward to the .git marker (checked with exists() so git worktrees, where .git is a file, also resolve), raising RuntimeError when no marker is found. All three detectors use it at import time, so a relocated detector fails loudly instead of scanning an empty tree. - Extract scripts/_detector_cli.py from the three character-identical CLI shims; the sys.path computation lives in one place and raises when backend/tests cannot be found. - tests/test_detector_repo_root.py pins: resolution from an unmarked location raises instead of returning an empty scan; all three detectors share the resolved root; each CLI shim delegates to its detector. Testing: backend `make test` (4278 passed); smoke-ran `make detect-blocking-io`, `make detect-thread-boundaries`, and `scripts/scan_changed_blocking_io.py --base upstream/main`. Closes #3510 (review follow-up to #3503). * chore(blocking-io): declare detector modules import-only, drop script-mode residue Adversarial review caught that blocking_io_static.py and thread_boundaries.py kept shebangs and __main__ blocks but can no longer run as plain scripts: the new `from support.detectors.repo_root import` executes before anything puts backend/tests on sys.path, so direct invocation dies with ModuleNotFoundError before argparse. Direct execution was never a documented entry point (Makefile targets, the scripts/ shims, the blocking-io-guard skill, and tests all go through the support.detectors package), so converge on import-only instead of re-adding per-module bootstrap: drop the shebangs and the now unreachable __main__ blocks (plus the `import sys` they kept alive) and state the supported entry points in each module docstring. The shim delegation tests in test_detector_repo_root.py pin the supported CLI paths. Testing: backend `make test` (4278 passed); `make detect-blocking-io` and `make detect-thread-boundaries` smoke-ran.
32 lines
1.2 KiB
Python
32 lines
1.2 KiB
Python
"""Fail-loud repository-root resolution shared by the detectors.
|
|
|
|
Depth-indexed resolution (`Path(__file__).resolve().parents[N]`) fails
|
|
silently when a detector file moves to a different directory depth: scan
|
|
roots resolve under the wrong directory, nothing is scanned, and the
|
|
detector reports zero findings with no error. Walking upward to a
|
|
repository marker turns that into an immediate error instead.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT_MARKER = ".git"
|
|
|
|
|
|
def resolve_repo_root(start: Path) -> Path:
|
|
"""Return the repository root above `start` (the directory containing `.git`).
|
|
|
|
`.git` is checked with `exists()` rather than `is_dir()` so git worktrees
|
|
(where `.git` is a file) resolve correctly.
|
|
|
|
Raises:
|
|
RuntimeError: when no marker is found above `start`, so a relocated
|
|
detector fails loudly instead of silently scanning an empty tree.
|
|
"""
|
|
resolved = start.resolve()
|
|
for candidate in (resolved, *resolved.parents):
|
|
if (candidate / REPO_ROOT_MARKER).exists():
|
|
return candidate
|
|
raise RuntimeError(f"could not resolve the repository root: no '{REPO_ROOT_MARKER}' marker found above {resolved}; refusing to guess scan paths")
|