mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-14 04:02:26 +00:00
fix: harden termux update path with uv bootstrap and env guard
This commit is contained in:
parent
6f7b698a08
commit
7c174e65f7
2 changed files with 41 additions and 3 deletions
|
|
@ -5923,16 +5923,19 @@ def _update_via_zip(args):
|
||||||
# individually so update does not silently strip working capabilities.
|
# individually so update does not silently strip working capabilities.
|
||||||
print("→ Updating Python dependencies...")
|
print("→ Updating Python dependencies...")
|
||||||
|
|
||||||
uv_bin = shutil.which("uv")
|
pip_cmd = [sys.executable, "-m", "pip"]
|
||||||
|
uv_bin = shutil.which("uv") or _ensure_uv_for_termux(pip_cmd)
|
||||||
if uv_bin:
|
if uv_bin:
|
||||||
uv_env = {**os.environ, "VIRTUAL_ENV": str(PROJECT_ROOT / "venv")}
|
uv_env = {**os.environ, "VIRTUAL_ENV": str(PROJECT_ROOT / "venv")}
|
||||||
|
if _is_termux_env(uv_env):
|
||||||
|
uv_env.pop("PYTHONPATH", None)
|
||||||
|
uv_env.pop("PYTHONHOME", None)
|
||||||
_install_python_dependencies_with_optional_fallback([uv_bin, "pip"], env=uv_env)
|
_install_python_dependencies_with_optional_fallback([uv_bin, "pip"], env=uv_env)
|
||||||
else:
|
else:
|
||||||
# Use sys.executable to explicitly call the venv's pip module,
|
# Use sys.executable to explicitly call the venv's pip module,
|
||||||
# avoiding PEP 668 'externally-managed-environment' errors on Debian/Ubuntu.
|
# avoiding PEP 668 'externally-managed-environment' errors on Debian/Ubuntu.
|
||||||
# Some environments lose pip inside the venv; bootstrap it back with
|
# Some environments lose pip inside the venv; bootstrap it back with
|
||||||
# ensurepip before trying the editable install.
|
# ensurepip before trying the editable install.
|
||||||
pip_cmd = [sys.executable, "-m", "pip"]
|
|
||||||
try:
|
try:
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
pip_cmd + ["--version"],
|
pip_cmd + ["--version"],
|
||||||
|
|
@ -6564,6 +6567,25 @@ def _install_python_dependencies_with_optional_fallback(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _is_termux_env(env: dict[str, str] | None = None) -> bool:
|
||||||
|
check = env or os.environ
|
||||||
|
prefix = str(check.get("PREFIX", ""))
|
||||||
|
return "com.termux" in prefix or prefix.startswith("/data/data/com.termux/")
|
||||||
|
|
||||||
|
|
||||||
|
def _ensure_uv_for_termux(pip_cmd: list[str]) -> str | None:
|
||||||
|
"""Best-effort uv bootstrap on Termux for faster update installs."""
|
||||||
|
uv_bin = shutil.which("uv")
|
||||||
|
if uv_bin or not _is_termux_env():
|
||||||
|
return uv_bin
|
||||||
|
try:
|
||||||
|
print(" → Termux detected: trying to install uv for faster dependency updates...")
|
||||||
|
subprocess.run(pip_cmd + ["install", "uv"], cwd=PROJECT_ROOT, check=False)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return shutil.which("uv")
|
||||||
|
|
||||||
|
|
||||||
def _update_node_dependencies() -> None:
|
def _update_node_dependencies() -> None:
|
||||||
npm = shutil.which("npm")
|
npm = shutil.which("npm")
|
||||||
if not npm:
|
if not npm:
|
||||||
|
|
@ -7304,9 +7326,13 @@ def _cmd_update_impl(args, gateway_mode: bool):
|
||||||
# breaks on this machine, keep base deps and reinstall the remaining extras
|
# breaks on this machine, keep base deps and reinstall the remaining extras
|
||||||
# individually so update does not silently strip working capabilities.
|
# individually so update does not silently strip working capabilities.
|
||||||
print("→ Updating Python dependencies...")
|
print("→ Updating Python dependencies...")
|
||||||
uv_bin = shutil.which("uv")
|
pip_cmd = [sys.executable, "-m", "pip"]
|
||||||
|
uv_bin = shutil.which("uv") or _ensure_uv_for_termux(pip_cmd)
|
||||||
if uv_bin:
|
if uv_bin:
|
||||||
uv_env = {**os.environ, "VIRTUAL_ENV": str(PROJECT_ROOT / "venv")}
|
uv_env = {**os.environ, "VIRTUAL_ENV": str(PROJECT_ROOT / "venv")}
|
||||||
|
if _is_termux_env(uv_env):
|
||||||
|
uv_env.pop("PYTHONPATH", None)
|
||||||
|
uv_env.pop("PYTHONHOME", None)
|
||||||
_install_python_dependencies_with_optional_fallback(
|
_install_python_dependencies_with_optional_fallback(
|
||||||
[uv_bin, "pip"], env=uv_env
|
[uv_bin, "pip"], env=uv_env
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -246,3 +246,15 @@ class TestCmdUpdateProfileSkillSync:
|
||||||
cmd_update(mock_args)
|
cmd_update(mock_args)
|
||||||
|
|
||||||
assert default_p.path in synced_paths
|
assert default_p.path in synced_paths
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_termux_env_true_for_termux_prefix():
|
||||||
|
from hermes_cli import main as hm
|
||||||
|
|
||||||
|
assert hm._is_termux_env({"PREFIX": "/data/data/com.termux/files/usr"}) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_termux_env_false_for_non_termux_prefix():
|
||||||
|
from hermes_cli import main as hm
|
||||||
|
|
||||||
|
assert hm._is_termux_env({"PREFIX": "/usr/local"}) is False
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue