Files
hermes-agent/apps/desktop/electron/fixtures/source-backend.py

100 lines
4.6 KiB
Python

"""PM publication plus the real backend, using prepared dependencies offline.
Only acquisition is substituted: real uv/Python come from the test host.
A local wheel exposes its prepared dependency closure through a load-bearing
.pth. PM's worker creates and selects the generation and the real publisher
writes the launcher. No production dependency install or fake server is used.
"""
from __future__ import annotations
import importlib
import json
import os
from pathlib import Path
import shutil
import subprocess
import sys
import zipfile
def main() -> None:
repository = Path(__file__).resolve().parents[4]
temp = Path(sys.argv[1])
root = Path(os.environ["HERMES_HOME"]) / "hermes-agent"
root.mkdir(parents=True)
for name in (
"hermes_cli", "hermes_platform", "pm", "agent", "tools", "gateway", "tui_gateway", "cron", "plugins",
):
shutil.copytree(repository / name, root / name,
ignore=shutil.ignore_patterns("__pycache__", "*.pyc"))
for source in repository.glob("*.py"):
shutil.copy2(source, root / source.name)
sys.path.insert(0, str(root))
uv = shutil.which("uv")
assert uv, "real uv must be prepared on PATH"
sites = [p for p in sys.path if p.endswith("site-packages")]
assert sites, "run with the prepared Hermes Python dependency environment"
wheels = temp / "wheels"
wheels.mkdir()
dist = "desktop_backend_deps-1.dist-info"
entries = {
"desktop_backend_deps.pth": "\n".join(sites) + "\n",
"desktop_backend_proof.py": "VALUE = 'selected by PM'\n",
f"{dist}/METADATA": "Metadata-Version: 2.1\nName: desktop-backend-deps\nVersion: 1\n",
f"{dist}/WHEEL": "Wheel-Version: 1.0\nRoot-Is-Purelib: true\nTag: py3-none-any\n",
}
entries[f"{dist}/RECORD"] = "".join(f"{name},,\n" for name in entries)
with zipfile.ZipFile(wheels / "desktop_backend_deps-1-py3-none-any.whl", "w") as wheel:
for name, content in entries.items():
wheel.writestr(name, content)
(root / "pyproject.toml").write_text(
'[project]\nname="desktop-startup-proof"\nversion="1"\nrequires-python=">=3.11"\n'
'dependencies=["desktop-backend-deps==1"]\n'
'[project.optional-dependencies]\nall=[]\n'
'[tool.uv]\npackage=false\nno-index=true\n'
f'find-links=[{json.dumps(wheels.as_posix())}]\n', encoding="utf-8")
subprocess.run([uv, "lock", "--project", str(root), "--python", sys.executable],
check=True, stdout=sys.stderr, timeout=30)
import pm
from pm import paths
from pm.lock import Facts
from pm.store import current_target, tree_digest
from pm.environments import selected_venv
from hermes_cli._launchers import ensure_install_launchers
# PM's worker runs on PM's own staged runtime (truststore, ruamel), never on
# the application interpreter; only the tool acquisition is substituted.
from pm.runtime_stage import stage_runtime
worker = root / "pm" / "worker.py"
worker_python = stage_runtime(Path(uv), Path(sys.executable), temp / "pm-runtime")
worker_code = (
"import runpy, sys; from pathlib import Path; "
f"sys.path.insert(0, {str(root)!r}); import pm._uv; "
f"pm._uv._toolchain = lambda **kwargs: (Path({uv!r}), Path({sys.executable!r})); "
f"runpy.run_path({str(worker)!r}, run_name='__main__')"
)
client = importlib.import_module("pm.client")
setattr(client, "runtime_command", lambda *args, **kwargs: [str(worker_python), "-I", "-c", worker_code])
pm.sync_venv(explicit=True, project_root=root)
selected = selected_venv(root)
assert selected and selected.is_relative_to(Path(os.environ["HERMES_HOME"]))
store = paths.store_root()
entry = store / "python-fixture"
python = entry / "bin" / "python3"
python.parent.mkdir(parents=True)
python.symlink_to(getattr(sys, "_base_executable", sys.executable))
Facts(paths.facts_path()).record("python", "fixture", entry.name, {"PATH": [str(python.parent)]},
store, target=current_target(), digest=tree_digest(entry))
launchers = ensure_install_launchers(root, root / ".hermes" / "bin")
assert launchers
(root / "desktop_launch_probe.py").write_text(
"import desktop_backend_proof, json, sys\n"
"print(json.dumps({'python': sys.executable, 'module': desktop_backend_proof.__file__, "
"'value': desktop_backend_proof.VALUE}))\n", encoding="utf-8")
print(json.dumps({"root": str(root), "launcher": str(root / ".hermes/bin/hermes"),
"python": str(python), "selected": str(selected)}))
if __name__ == "__main__":
main()