hermes_cli.runtime_paths (venv generations, selection, activation) moves to pm.environments, and gains venv_bin_dir / venv_python / project_python. Every in-tree caller asks pm for an interpreter now; pm no longer reaches back into hermes_cli for its own environment layout (pm.packages, pm.extras, pm.ensure, pm.paths imported hermes_cli.runtime_paths). The three open-coded "Scripts/python.exe or bin/python" ladders in pm collapse onto venv_python. hermes_constants.venv_python_path / venv_bin_dir and hermes_cli.runtime_paths stay as frozen-updater-surface shims only (tests/compat/old_updater_surface.json). To keep the boot path light, pm/__init__ resolves its facade lazily (PEP 562) and pm.registry loads the built-in package definitions on first read instead of at import: `import hermes_bootstrap` now loads pm + pm.environments only (25ms, was 37ms with the eager facade dragging in the downloader). The stripped-payload fixtures that ship only pre-import files keep working for the same reason. Also restores two frozen-surface re-exports the F401 sweep dropped (banner._github_compare_behind, cua_backend.resolve_cua_driver_cmd).
25 lines
1.1 KiB
Python
25 lines
1.1 KiB
Python
"""Recovery does not overwrite a config edited after interrupted publication."""
|
|
import pytest
|
|
|
|
|
|
def test_recovery_refuses_to_replace_newer_config(tmp_path, monkeypatch):
|
|
from hermes_cli.runtime_state import recover_publication, runtime_lock
|
|
from pm.publication import PluginSelection
|
|
import pm.paths as paths
|
|
from pm.environments import install_state_dir
|
|
|
|
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
|
repo = tmp_path / "repo"
|
|
repo.mkdir()
|
|
monkeypatch.setattr(paths, "repo_root", lambda: repo)
|
|
config = tmp_path / "config.yaml"
|
|
config.write_bytes(b"plugins:\n enabled: [old]\n")
|
|
with runtime_lock(repo):
|
|
PluginSelection({"home": str(config.parent), "enabled": ["new"], "disabled": []}).publish(repo)
|
|
config.write_bytes(config.read_bytes() + b"model: user-choice\n")
|
|
changed = config.read_bytes()
|
|
with pytest.raises(RuntimeError, match="config changed"):
|
|
recover_publication(repo)
|
|
assert config.read_bytes() == changed
|
|
assert (install_state_dir(repo) / "publication.json").is_file()
|