Files
wehub-resource-sync b4fbd6fe9f
Deploy Site / deploy-vercel (push) Has been skipped
Deploy Site / deploy-docs (push) Has been skipped
Build Skills Index / build-index (push) Has been skipped
Build Skills Index / trigger-deploy (push) Waiting to run
CI / Deny unrelated histories (push) Has been skipped
CI / CI timing report (push) Blocked by required conditions
CI / Detect affected areas (push) Successful in 27m35s
CI / OSV scan (push) Failing after 4s
CI / Build&Test Docker image (push) Successful in 9s
CI / Supply-chain scan (push) Has been skipped
CI / Lint Docker scripts (push) Failing after 5m13s
CI / Check contributors (push) Failing after 12m8s
CI / Docs Site (push) Failing after 12m8s
CI / TypeScript (push) Failing after 12m8s
CI / Python lints (push) Failing after 12m9s
CI / Python tests (push) Failing after 12m9s
CI / Check uv.lock (push) Failing after 23m22s
CI / All required checks pass (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 11:56:03 +08:00

103 lines
3.1 KiB
Python
Executable File

#!/usr/bin/env python3
"""Install psutil on Termux/Android by patching upstream platform detection.
psutil's setup currently gates Linux sources behind
``sys.platform.startswith('linux')``. On Termux, Python reports
``sys.platform == 'android'``, so ``pip install psutil`` aborts with
"platform android is not supported" — even though psutil compiles fine
when the Linux source path is reused.
This script downloads the official psutil sdist, applies a one-line
patch (``LINUX = sys.platform.startswith(("linux", "android"))``), and
installs the patched tree with ``pip install --no-build-isolation``.
Usage:
python scripts/install_psutil_android.py [--pip "/path/to/pip"] [--uv]
When neither flag is given, the script auto-detects ``uv`` on PATH and
falls back to ``<sys.executable> -m pip``.
This is a stopgap. Remove once psutil upstream merges
https://github.com/giampaolo/psutil/pull/2762 and ships a release.
"""
from __future__ import annotations
import argparse
import shutil
import subprocess
import sys
import tempfile
import urllib.request
from pathlib import Path
# Keep sibling imports working when invoked as
# ``python scripts/install_psutil_android.py`` from the repo checkout.
REPO_ROOT = Path(__file__).resolve().parents[1]
if str(REPO_ROOT) not in sys.path:
sys.path.insert(0, str(REPO_ROOT))
from hermes_cli.psutil_android import (
PSUTIL_URL,
PsutilAndroidInstallError,
prepare_patched_psutil_sdist,
)
def _resolve_install_cmd(pip_arg: str | None, prefer_uv: bool) -> list[str]:
if pip_arg:
return pip_arg.split()
if prefer_uv:
uv = shutil.which("uv")
if not uv:
sys.exit("--uv requested but no uv on PATH")
return [uv, "pip"]
auto_uv = shutil.which("uv")
if auto_uv:
return [auto_uv, "pip"]
return [sys.executable, "-m", "pip"]
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--pip",
help="Explicit installer command (e.g. '/usr/bin/uv pip' or 'python -m pip')",
)
parser.add_argument(
"--uv",
action="store_true",
help="Force using uv (errors out if uv is not on PATH)",
)
args = parser.parse_args()
install_cmd_prefix = _resolve_install_cmd(args.pip, args.uv)
print(
"→ Termux/Android: prebuilding psutil with Linux source path "
"compatibility shim (see psutil#2762)..."
)
with tempfile.TemporaryDirectory() as tmp:
tmp_path = Path(tmp)
archive = tmp_path / "psutil.tar.gz"
urllib.request.urlretrieve(PSUTIL_URL, archive)
try:
src_root = prepare_patched_psutil_sdist(archive, tmp_path)
except PsutilAndroidInstallError as exc:
sys.exit(str(exc))
cmd = install_cmd_prefix + ["install", "--no-build-isolation", str(src_root)]
print(f" $ {' '.join(cmd)}")
result = subprocess.run(cmd)
if result.returncode != 0:
return result.returncode
print("✓ psutil installed via Android compatibility shim")
return 0
if __name__ == "__main__":
raise SystemExit(main())