fix(tools): include user local bin in POSIX PATH

This commit is contained in:
KoNit-K
2026-09-15 17:40:05 +08:00
committed by Teknium
parent b74f158b0d
commit c68e306ea4
2 changed files with 39 additions and 3 deletions
+22
View File
@@ -1594,6 +1594,28 @@ class TestSanePathIncludesHomebrew:
for entry in _SANE_PATH.split(os.pathsep):
assert entry in path_entries
def test_make_run_env_appends_existing_user_local_bin_on_posix(self, monkeypatch, tmp_path):
"""A thin remote SSH PATH can still resolve user-installed CLIs (#111778)."""
from tools.environments import local as local_mod
from tools.environments.local import _make_run_env
local_bin = tmp_path / ".local" / "bin"
local_bin.mkdir(parents=True)
executable = local_bin / "himalaya"
executable.touch()
executable.chmod(0o755)
monkeypatch.setattr(local_mod, "_git_bash_bin_dirs", lambda: [])
monkeypatch.setattr(local_mod.Path, "home", classmethod(lambda cls: tmp_path))
with patch.dict(os.environ, {"PATH": "/usr/bin:/bin"}, clear=True):
result = _make_run_env({})
if sys.platform == "win32":
assert str(local_bin) not in result["PATH"].split(os.pathsep)
else:
entries = result["PATH"].split(os.pathsep)
assert entries[:2] == ["/usr/bin", "/bin"]
assert str(local_bin) in entries
@pytest.mark.macos_only
def test_make_run_env_real_launchd_path_gains_homebrew(self):
+17 -3
View File
@@ -552,16 +552,30 @@ def _managed_runtime_path_entries() -> list[str]:
return []
def _existing_user_local_bin_dir() -> str | None:
"""Return the POSIX user's ``~/.local/bin`` only when it exists."""
if _IS_WINDOWS:
return None
candidate = Path.home() / ".local" / "bin"
return str(candidate) if candidate.is_dir() else None
def _append_missing_sane_path_entries(existing_path: str) -> str:
"""Normalised POSIX PATH with missing sane entries appended: empty entries
dropped (shells read them as cwd), duplicates collapsed (first wins), then
missing ``_SANE_PATH`` / managed-runtime dirs appended so user entries keep
precedence. Windows is a no-op passthrough (native ``;`` PATH untouched)."""
missing ``_SANE_PATH``, managed-runtime dirs, and an existing user-local bin
dir appended so inherited/login-shell entries keep precedence. Windows is a
no-op passthrough (native ``;`` PATH untouched)."""
if _IS_WINDOWS:
return existing_path
# dict preserves first-occurrence order; empty entries dropped.
ordered = dict.fromkeys(entry for entry in existing_path.split(":") if entry)
ordered.update(dict.fromkeys([*_SANE_PATH.split(":"), *_managed_runtime_path_entries()]))
user_local_bin = _existing_user_local_bin_dir()
ordered.update(dict.fromkeys([
*_SANE_PATH.split(":"),
*_managed_runtime_path_entries(),
*([user_local_bin] if user_local_bin else []),
]))
return ":".join(ordered)