mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-27 11:22:03 +00:00
fix(update): reuse an existing PATH uv on Termux before pip
_ensure_uv_for_termux only checked resolve_uv() (the managed
$HERMES_HOME/bin/uv) before falling back to pip, so a uv installed via
`pkg install uv` lives on PATH but is invisible to the helper. Combined
with the cherry-picked wheel-only fallback, a Termux user with no managed
uv still hit `pip install uv`, which has no Android wheel and tried to
source-build the Rust crate, OOM-killing low-memory devices.
Probe shutil.which("uv") right after the Termux guard and reuse it before
pip. Add a regression test that keeps resolve_uv() returning None while a
uv exists on PATH and asserts pip is never invoked.
This commit is contained in:
parent
3e508363f7
commit
667a9f5139
2 changed files with 26 additions and 2 deletions
|
|
@ -7724,8 +7724,9 @@ def _ensure_uv_for_termux(pip_cmd: list[str]) -> str | None:
|
|||
|
||||
The normal path (``ensure_uv()`` in managed_uv) installs the managed
|
||||
standalone uv into ``$HERMES_HOME/bin/uv``, but on Termux the official
|
||||
installer may not work (glibc vs bionic). Fall back to ``pip install uv``
|
||||
which gets a Termux-compatible binary.
|
||||
installer may not work (glibc vs bionic). Prefer a uv already on PATH
|
||||
(e.g. ``pkg install uv``); only if there is none do we fall back to a
|
||||
wheel-only ``pip install uv`` so we never source-build the Rust crate.
|
||||
"""
|
||||
from hermes_cli.managed_uv import resolve_uv
|
||||
|
||||
|
|
@ -7734,6 +7735,12 @@ def _ensure_uv_for_termux(pip_cmd: list[str]) -> str | None:
|
|||
return existing
|
||||
if not _is_termux_env():
|
||||
return None
|
||||
# A Termux-packaged uv lands on PATH but not in the managed bin dir, so
|
||||
# resolve_uv() misses it. Use it before pip, which has no Android wheel and
|
||||
# would otherwise build uv from source on a low-memory device.
|
||||
system_uv = shutil.which("uv")
|
||||
if system_uv:
|
||||
return system_uv
|
||||
try:
|
||||
print(" → Termux detected: trying to install uv for faster dependency updates...")
|
||||
result = subprocess.run(
|
||||
|
|
|
|||
|
|
@ -138,6 +138,23 @@ class TestCmdUpdateTermuxUvBootstrap:
|
|||
assert mock_run.call_args.kwargs["cwd"] == PROJECT_ROOT
|
||||
assert mock_run.call_args.kwargs["check"] is False
|
||||
|
||||
@patch("subprocess.run")
|
||||
def test_termux_reuses_existing_path_uv_without_pip(self, mock_run, monkeypatch):
|
||||
"""A uv already on PATH (e.g. ``pkg install uv``) is reused before pip runs."""
|
||||
from hermes_cli import main as hm
|
||||
|
||||
pkg_uv = "/data/data/com.termux/files/usr/bin/uv"
|
||||
monkeypatch.setattr(hm, "_is_termux_env", lambda env=None: True)
|
||||
# Production resolve_uv only checks $HERMES_HOME/bin/uv; model an empty
|
||||
# managed dir so the PATH probe is what surfaces the packaged uv.
|
||||
monkeypatch.setattr("hermes_cli.managed_uv.resolve_uv", lambda: None)
|
||||
monkeypatch.setattr("shutil.which", lambda name: pkg_uv if name == "uv" else None)
|
||||
|
||||
uv_bin = hm._ensure_uv_for_termux(["/termux/python", "-m", "pip"])
|
||||
|
||||
assert uv_bin == pkg_uv
|
||||
mock_run.assert_not_called()
|
||||
|
||||
|
||||
class TestCmdUpdateBranchFallback:
|
||||
"""cmd_update falls back to main when current branch has no remote counterpart."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue