Skip to content

Commit 200be8b

Browse files
committed
ci: resolve Lychee directly from the hook environment
Use the running Python environment scripts directory instead of searching PATH. Fail explicitly when the native binary is absent, and cover Linux and Windows executable selection plus unrelated installations on PATH. Signed-off-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
1 parent 1e1d063 commit 200be8b

2 files changed

Lines changed: 36 additions & 11 deletions

File tree

‎ci/tools/run_lychee.py‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
from __future__ import annotations
77

8-
import shutil
98
import subprocess
109
import sys
10+
import sysconfig
1111
from pathlib import Path
1212

1313
ROOT = Path(__file__).resolve().parents[2]
@@ -23,12 +23,14 @@ def repo_link_remaps(root: Path = ROOT) -> list[str]:
2323

2424

2525
def main(arguments: list[str] | None = None) -> int:
26-
executable = shutil.which("lychee")
27-
if executable is None:
28-
raise SystemExit("lychee was not found; run this script through the configured pre-commit hook")
26+
# Use this Python environment's installation, independent of PATH and the working directory.
27+
executable = Path(sysconfig.get_path("scripts")) / ("lychee.exe" if sys.platform == "win32" else "lychee")
28+
if not executable.is_file():
29+
raise SystemExit(
30+
f"lychee was not found at {executable}; run this script through the configured pre-commit hook"
31+
)
2932
arguments = sys.argv[1:] if arguments is None else arguments
30-
# Let Python launch the native binary on every platform, including Windows.
31-
return subprocess.run([executable, *repo_link_remaps(), *arguments], check=False).returncode # noqa: S603
33+
return subprocess.run([str(executable), *repo_link_remaps(), *arguments], check=False).returncode # noqa: S603
3234

3335

3436
if __name__ == "__main__":

‎ci/tools/tests/test_run_lychee.py‎

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,41 @@ def test_remaps_leave_other_targets_and_nested_urls_unchanged(tmp_path, url):
5151
assert re.sub(pattern, replacement, url) == url
5252

5353

54+
@pytest.mark.parametrize("platform", ["linux", "win32"])
5455
@pytest.mark.agent_authored(model="gpt-6.1-sol")
55-
def test_main_passes_arguments_without_shell_and_preserves_failure_status():
56+
def test_main_uses_hook_environment_despite_other_binary_on_path(tmp_path, monkeypatch, platform):
57+
scripts = tmp_path / "hook environment" / ("Scripts" if platform == "win32" else "bin")
58+
scripts.mkdir(parents=True)
59+
name = "lychee.exe" if platform == "win32" else "lychee"
60+
executable = scripts / name
61+
executable.touch()
62+
other_directory = tmp_path / "other installation"
63+
other_directory.mkdir()
64+
(other_directory / name).touch(mode=0o755)
65+
monkeypatch.setenv("PATH", str(other_directory))
5666
arguments = ["--cache", "--max-concurrency=4", "guide with spaces.md"]
5767
with (
58-
patch("run_lychee.shutil.which", return_value="/hook environment/bin/lychee"),
68+
patch("run_lychee.sysconfig.get_path", return_value=str(scripts)),
69+
patch("run_lychee.sys.platform", platform),
5970
patch("run_lychee.subprocess.run", return_value=subprocess.CompletedProcess([], 2)) as run,
6071
):
6172
assert main(arguments) == 2
62-
run.assert_called_once_with(["/hook environment/bin/lychee", *repo_link_remaps(), *arguments], check=False)
73+
run.assert_called_once_with([str(executable), *repo_link_remaps(), *arguments], check=False)
6374

6475

6576
@pytest.mark.agent_authored(model="gpt-6.1-sol")
66-
def test_main_reports_missing_binary():
67-
with patch("run_lychee.shutil.which", return_value=None), pytest.raises(SystemExit, match="lychee was not found"):
77+
def test_main_reports_missing_hook_binary_without_falling_back_to_path(tmp_path, monkeypatch):
78+
scripts = tmp_path / "hook environment" / "bin"
79+
other_directory = tmp_path / "other installation"
80+
other_directory.mkdir()
81+
(other_directory / "lychee").touch(mode=0o755)
82+
monkeypatch.setenv("PATH", str(other_directory))
83+
with (
84+
patch("run_lychee.sysconfig.get_path", return_value=str(scripts)),
85+
patch("run_lychee.sys.platform", "linux"),
86+
patch("run_lychee.subprocess.run") as run,
87+
pytest.raises(SystemExit, match="lychee was not found") as error,
88+
):
6889
main(["guide.md"])
90+
assert str(scripts / "lychee") in str(error.value)
91+
run.assert_not_called()

0 commit comments

Comments
 (0)