diff --git a/openadapt/cli.py b/openadapt/cli.py index 9f00b71f5..dff42a552 100644 --- a/openadapt/cli.py +++ b/openadapt/cli.py @@ -718,7 +718,11 @@ def _launcher_version(path: str, run=None) -> Optional[str]: try: result = (run or subprocess.run)( - [path, "--version"], capture_output=True, text=True, timeout=15 + [path, "--version"], + capture_output=True, + text=True, + timeout=15, + env={**os.environ, _NO_LAUNCHER_CHECK: "1"}, ) text = f"{result.stdout} {result.stderr}" except Exception: # noqa: BLE001 - an unrunnable openadapt has no version @@ -824,7 +828,15 @@ def _launcher_conflicts(launchers=None, run=None) -> list[str]: return lines +#: Set in the environment of every ``openadapt --version`` this check runs, so +#: the child never runs the check itself. Without it, two installs that both +#: carry the check ask each other for their version forever. +_NO_LAUNCHER_CHECK = "OPENADAPT_NO_LAUNCHER_CHECK" + + def _warn_about_launcher_conflicts() -> None: + if os.environ.get(_NO_LAUNCHER_CHECK): + return try: lines = _launcher_conflicts() except Exception: # noqa: BLE001 - a PATH check must never break a command diff --git a/tests/test_cli_uvx_hints.py b/tests/test_cli_uvx_hints.py index 9c04ba90d..fc9949dd0 100644 --- a/tests/test_cli_uvx_hints.py +++ b/tests/test_cli_uvx_hints.py @@ -112,3 +112,26 @@ def test_the_finale_prints_keep_it_and_the_shadow_warning( ) finale = lines[lines.index("Receipt") :] assert len(finale) <= 12 + + +def test_version_check_never_recurses(monkeypatch) -> None: + """The child ``openadapt --version`` gets a guard, and the guard stops the check.""" + seen = {} + + def fake_run(args, **kwargs): + seen["env"] = kwargs.get("env") or {} + + class R: + stdout = "openadapt, version 0.0.1" + stderr = "" + + return R() + + assert cli._launcher_version("/x/openadapt", fake_run) == "0.0.1" + assert seen["env"].get(cli._NO_LAUNCHER_CHECK) == "1" + + called = [] + monkeypatch.setenv(cli._NO_LAUNCHER_CHECK, "1") + monkeypatch.setattr(cli, "_launcher_conflicts", lambda: called.append(1) or []) + cli._warn_about_launcher_conflicts() + assert called == []