"""고친 파일을 언급하는 시험 찾기 — 작업 끝 자체검증용(전체 시험 대신). python tools/related_tests.py # 고친 파일 = 작업 트리 + 메인에 없는 내 커밋 python tools/related_tests.py a.py b.ts # 고친 파일을 직접 줌 python tools/related_tests.py --run # 찾아서 바로 돌림 찾는 법: 고친 파일 이름(확장자 뺌)이 글 안에 든 `resources/tester/test_*.py` + 고친 시험 파일 자신. """ import pathlib import subprocess import sys ROOT = pathlib.Path(__file__).resolve().parent.parent TESTS = ROOT / "resources" / "tester" def _git(*args: str) -> list[str]: out = subprocess.run(["git", "-C", str(ROOT), *args], capture_output=True) return [x for x in out.stdout.decode("utf-8", "replace").splitlines() if x.strip()] def changed() -> list[str]: """작업 트리 고침 + 추적 안 된 새 파일 + 메인(origin/main_laptop_1)에 없는 내 커밋""" got = _git("diff", "--name-only", "HEAD") + _git("ls-files", "--others", "--exclude-standard") got += _git("diff", "--name-only", "origin/main_laptop_1...HEAD") return sorted(set(got)) def related(files: list[str]) -> list[str]: stems, own = set(), set() for f in files: p = pathlib.PurePosixPath(f.replace("\\", "/")) if p.name.startswith("test_") and p.suffix == ".py": own.add(p.name) elif len(p.stem) >= 6: # 짧은 이름(main · index)은 어디에나 나와 뺌 stems.add(p.stem) hit = set(own) for t in sorted(TESTS.glob("test_*.py")): if t.name in hit: continue text = t.read_text(encoding="utf-8", errors="replace") if any(s in text for s in stems): hit.add(t.name) return [f"resources/tester/{n}" for n in sorted(hit) if (TESTS / n).exists()] def main() -> int: args = [a for a in sys.argv[1:] if a != "--run"] tests = related(args or changed()) if "--run" not in sys.argv: print(" ".join(tests)) return 0 if not tests: print("관련 시험 없음") return 0 cmd = [sys.executable, "-m", "pytest", *tests, "-q", "-p", "no:cacheprovider"] return subprocess.run(cmd, cwd=ROOT).returncode if __name__ == "__main__": raise SystemExit(main())