mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-28 18:05:08 +00:00
install.ps1 wrote the marker on Windows and the Rust installer now writes it, but install.sh -- the path every Mac and Linux CLI install takes -- never did. A machine set up with install.sh therefore looked uninstalled to the desktop app, which re-ran first-run bootstrap on every launch. Stamp the same schema-v1 payload install.ps1 writes, from both the staged `complete` stage and monolithic main(). An unresolvable HEAD skips the marker rather than writing one the desktop validator rejects: absent reads as a clean "bootstrap needed", malformed reads as a confusing half-state.
109 lines
3.6 KiB
Python
109 lines
3.6 KiB
Python
"""install.sh must stamp the desktop bootstrap-complete marker.
|
|
|
|
The marker at ``$INSTALL_DIR/.hermes-bootstrap-complete`` is what the desktop
|
|
app (apps/desktop/electron/main.ts) and the macOS launcher fast path
|
|
(apps/bootstrap-installer) use to decide "a real install finished here."
|
|
install.sh never wrote it, so a CLI-installed Mac/Linux box re-ran first-run
|
|
bootstrap on every desktop launch (#60721).
|
|
|
|
These exercise the real shell function against a temp checkout rather than
|
|
asserting on the text of install.sh.
|
|
"""
|
|
|
|
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
INSTALL_SH = REPO_ROOT / "scripts" / "install.sh"
|
|
|
|
|
|
def run_write_marker(install_dir, *, commit="", branch="main"):
|
|
"""Source install.sh and invoke write_bootstrap_marker in isolation.
|
|
|
|
install.sh guards its own entrypoint behind MANIFEST_MODE/STAGE_NAME/main,
|
|
so sourcing it with --help-less argv defines the functions without running
|
|
an install.
|
|
"""
|
|
script = f"""
|
|
set -e
|
|
INSTALL_DIR={install_dir!s}
|
|
INSTALL_COMMIT={commit!r}
|
|
BRANCH={branch!r}
|
|
# Pull in the function definitions without triggering an install.
|
|
eval "$(sed -n '/^write_bootstrap_marker()/,/^}}/p' {INSTALL_SH!s})"
|
|
log_warn() {{ echo "WARN: $*" >&2; }}
|
|
write_bootstrap_marker
|
|
"""
|
|
return subprocess.run(
|
|
["bash", "-c", script], capture_output=True, text=True, timeout=30
|
|
)
|
|
|
|
|
|
def make_checkout(tmp_path):
|
|
install_dir = tmp_path / "hermes-agent"
|
|
install_dir.mkdir()
|
|
subprocess.run(["git", "init", "-q"], cwd=install_dir, check=True)
|
|
subprocess.run(
|
|
["git", "-c", "user.email=t@t", "-c", "user.name=t", "commit", "-q",
|
|
"--allow-empty", "-m", "init"],
|
|
cwd=install_dir,
|
|
check=True,
|
|
)
|
|
return install_dir
|
|
|
|
|
|
def test_marker_matches_the_schema_the_desktop_validates(tmp_path):
|
|
"""Desktop's isBootstrapComplete() needs schemaVersion 1 + a >=7 char commit."""
|
|
install_dir = make_checkout(tmp_path)
|
|
|
|
result = run_write_marker(install_dir)
|
|
assert result.returncode == 0, result.stderr
|
|
|
|
marker = install_dir / ".hermes-bootstrap-complete"
|
|
assert marker.is_file(), "install.sh must stamp the bootstrap marker"
|
|
|
|
payload = json.loads(marker.read_text())
|
|
assert payload["schemaVersion"] == 1
|
|
assert len(payload["pinnedCommit"]) >= 7
|
|
assert payload["pinnedBranch"] == "main"
|
|
assert payload["completedAt"].endswith("Z")
|
|
|
|
|
|
def test_marker_publish_leaves_no_temp_sibling(tmp_path):
|
|
"""The launcher predicate is existence-only, so the write must be atomic."""
|
|
install_dir = make_checkout(tmp_path)
|
|
|
|
run_write_marker(install_dir)
|
|
|
|
assert (install_dir / ".hermes-bootstrap-complete").is_file()
|
|
assert not (install_dir / ".hermes-bootstrap-complete.tmp").exists()
|
|
|
|
|
|
def test_explicit_commit_pin_wins_over_head(tmp_path):
|
|
install_dir = make_checkout(tmp_path)
|
|
pinned = "abcdef1234567890abcdef1234567890abcdef12"
|
|
|
|
run_write_marker(install_dir, commit=pinned)
|
|
|
|
payload = json.loads((install_dir / ".hermes-bootstrap-complete").read_text())
|
|
assert payload["pinnedCommit"] == pinned
|
|
|
|
|
|
def test_no_marker_written_when_head_cannot_be_resolved(tmp_path):
|
|
"""A malformed marker is worse than none: absent means a clean re-bootstrap."""
|
|
install_dir = tmp_path / "not-a-checkout"
|
|
install_dir.mkdir()
|
|
|
|
result = run_write_marker(install_dir)
|
|
|
|
assert result.returncode == 0, "an unresolvable HEAD must not fail the install"
|
|
assert not (install_dir / ".hermes-bootstrap-complete").exists()
|
|
|
|
|
|
def test_missing_install_dir_is_not_fatal(tmp_path):
|
|
result = run_write_marker(tmp_path / "does-not-exist")
|
|
|
|
assert result.returncode == 0
|