Competing installers and checkout-local venv assumptions bypassed PM selection, install consent, and generation lifetimes. Route consumers through PM and installation-bound launchers. Refresh source launchers before obsolete Python entries can be collected. Remove Node, browser, and CUA acquisition engines, obsolete venv-holder handling, detached sync, and unused PM APIs. Keep historical updater exports inert and preserve external tool ownership and native integration. Share product freshness and prepared inputs across builders. Align plugin admission, Docker provisioning, setup instructions, and behavioral tests. Verified targeted Python and JavaScript tests, desktop and web typechecks, scoped lint, real product builds, and the Docker frontend smoke test. The missed post-setup test cleanup is included and verified. Native Windows/macOS execution, full Rust compilation, and the complete repository suite remain unverified. Historical compatibility requirements were preserved and extended, not fully rescanned.
62 lines
2.4 KiB
Python
62 lines
2.4 KiB
Python
"""Packaging guards not yet covered by the image-runtime suite.
|
|
|
|
Write permissions and lazy-install policy are exercised by tests/docker.
|
|
Keep stamp placement and Photon preparation until those image checks exist.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
DOCKERFILE = REPO_ROOT / "Dockerfile"
|
|
|
|
|
|
def _dockerfile_text() -> str:
|
|
return DOCKERFILE.read_text()
|
|
|
|
|
|
def test_dockerfile_bakes_code_scoped_install_method_stamp() -> None:
|
|
"""The 'docker' install-method stamp is baked next to the code.
|
|
|
|
detect_install_method() reads the code-scoped stamp
|
|
(/opt/hermes/.install_method) first; baking it at build time keeps the
|
|
published image self-identifying as 'docker' WITHOUT writing into the
|
|
shared $HERMES_HOME data volume (which a host install may also use).
|
|
The stamp is created by root in the shim-wiring RUN block; the hermes
|
|
user can't modify it (go-w from the --chmod on the source COPY).
|
|
"""
|
|
text = _dockerfile_text()
|
|
assert "printf 'docker\\n' > /opt/hermes/.install_method" in text
|
|
|
|
# The stamp must be in the RUN block that wires the exec shim.
|
|
shim_block = re.search(
|
|
r"RUN mkdir -p /opt/hermes/bin && \\\n"
|
|
r"(?:.*\\\n)+?"
|
|
r"\s+printf 'docker\\n' > /opt/hermes/\.install_method",
|
|
text,
|
|
)
|
|
assert shim_block, "install-method stamp must be in the shim-wiring RUN block"
|
|
|
|
|
|
def test_dockerfile_bakes_photon_sidecar_deps() -> None:
|
|
"""The Photon sidecar's node_modules must be baked at build time (NS-606).
|
|
|
|
The install tree is immutable at runtime, so a lazy `npm ci` on first
|
|
connect would hit EROFS. Baking the deps (from the committed lockfile,
|
|
which also runs the spectrum-ts postinstall patch) makes the hosted
|
|
happy path install-free. Guards the contract between the Dockerfile
|
|
and plugins/platforms/photon/sidecar_paths.resolve_sidecar_dir, which
|
|
runs in place only when the baked deps exist and match the lockfile.
|
|
"""
|
|
text = _dockerfile_text()
|
|
|
|
assert "plugins/platforms/photon/sidecar/package-lock.json" in text
|
|
assert re.search(
|
|
r"RUN cd plugins/platforms/photon/sidecar && \\\n\s+npm ci", text
|
|
), "sidecar deps must be installed with `npm ci` (deterministic, runs postinstall patch)"
|
|
# Immutability contract: never chown the sidecar tree to the runtime user.
|
|
assert not re.search(
|
|
r"chown\s+-R\s+hermes:hermes\s+/opt/hermes/plugins", text
|
|
)
|