* fix(docker): install @mathew-cf/opencode-memory plugin in Dockerfile * test(docker): add Dockerfile npm install test * docs(handoff): set PR number 57 in handoff + ADR-024 --------- Co-authored-by: opencode-agent <agent@slaid098.dev>
118 lines
4.4 KiB
Python
118 lines
4.4 KiB
Python
"""Tests for Dockerfile npm install line.
|
|
|
|
Covers issue #56 acceptance criteria:
|
|
- ``Dockerfile`` installs ``@mathew-cf/opencode-memory`` alongside
|
|
``opencode-ai`` and ``repomix`` in the global npm install step, so the
|
|
memory plugin (``memory_save`` / ``memory_search`` / ``memory_list`` MCP
|
|
tools) is available inside the container.
|
|
- ``opencode-ai`` is still present (regression guard — must not be dropped
|
|
when editing the install line).
|
|
|
|
Checks are raw-text grep assertions (no Docker build needed), mirroring the
|
|
belt-and-suspenders style of ``test_docker_compose.py``.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
DOCKERFILE = REPO_ROOT / "Dockerfile"
|
|
|
|
REQUIRED_PACKAGES = ("opencode-ai", "repomix", "@mathew-cf/opencode-memory")
|
|
MEMORY_PLUGIN = "@mathew-cf/opencode-memory"
|
|
OPENCODE_AI = "opencode-ai"
|
|
|
|
|
|
def _dockerfile_text() -> str:
|
|
"""Read Dockerfile text (asserts the file exists)."""
|
|
assert DOCKERFILE.exists(), f"Dockerfile missing: {DOCKERFILE}"
|
|
return DOCKERFILE.read_text()
|
|
|
|
|
|
def _npm_install_lines(text: str) -> list[str]:
|
|
"""Return every ``npm install -g ...`` line from the Dockerfile."""
|
|
return [line for line in text.splitlines() if "npm install -g" in line]
|
|
|
|
|
|
# ── file exists ─────────────────────────────────────────────────────────────
|
|
|
|
|
|
def test_dockerfile_exists():
|
|
"""Dockerfile exists at repo root."""
|
|
assert DOCKERFILE.exists(), f"Dockerfile missing: {DOCKERFILE}"
|
|
|
|
|
|
# ── @mathew-cf/opencode-memory installed (issue #56 — the required plugin) ───
|
|
|
|
|
|
def test_memory_plugin_in_npm_install():
|
|
"""Dockerfile installs ``@mathew-cf/opencode-memory`` via ``npm install -g``.
|
|
|
|
Without the plugin the memory MCP tools (``memory_save`` /
|
|
``memory_search`` / ``memory_list``) are unavailable — opencode silently
|
|
skips the uninstalled plugin referenced in opencode.json.
|
|
"""
|
|
lines = _npm_install_lines(_dockerfile_text())
|
|
assert lines, "no `npm install -g` line found in Dockerfile"
|
|
assert any(MEMORY_PLUGIN in line for line in lines), (
|
|
f"Dockerfile must install {MEMORY_PLUGIN!r} via `npm install -g` — "
|
|
"memory plugin MCP tools depend on it"
|
|
)
|
|
|
|
|
|
def test_memory_plugin_in_npm_install_raw():
|
|
"""Raw text check: the Dockerfile contains ``@mathew-cf/opencode-memory``.
|
|
|
|
Belt-and-suspenders alongside the parsed check — catches edge cases where
|
|
the line collector might miss a multi-line or differently-formatted
|
|
install statement.
|
|
"""
|
|
assert MEMORY_PLUGIN in _dockerfile_text(), (
|
|
f"Dockerfile must contain {MEMORY_PLUGIN!r} so the memory plugin loads inside the container"
|
|
)
|
|
|
|
|
|
# ── opencode-ai still present (regression — must not drop the main package) ──
|
|
|
|
|
|
def test_opencode_ai_present():
|
|
"""Dockerfile still installs ``opencode-ai`` (regression guard).
|
|
|
|
Editing the npm install line to add the memory plugin must not
|
|
accidentally drop the primary ``opencode-ai`` package.
|
|
"""
|
|
lines = _npm_install_lines(_dockerfile_text())
|
|
assert lines, "no `npm install -g` line found in Dockerfile"
|
|
assert any(OPENCODE_AI in line for line in lines), (
|
|
f"Dockerfile must still install {OPENCODE_AI!r} — dropping it breaks "
|
|
"the container entrypoint"
|
|
)
|
|
|
|
|
|
def test_opencode_ai_present_raw():
|
|
"""Raw text check: the Dockerfile contains ``opencode-ai``."""
|
|
assert OPENCODE_AI in _dockerfile_text(), f"Dockerfile must still contain {OPENCODE_AI!r}"
|
|
|
|
|
|
# ── single npm install line holds all three packages ────────────────────────
|
|
|
|
|
|
def test_single_npm_install_line_has_all_packages():
|
|
"""One ``npm install -g`` line installs all three required packages.
|
|
|
|
Guards against splitting the install across multiple RUN layers (which
|
|
would waste image layers and obscure which package is missing).
|
|
"""
|
|
lines = _npm_install_lines(_dockerfile_text())
|
|
install_lines = [line for line in lines if OPENCODE_AI in line]
|
|
assert install_lines, f"no `npm install -g` line with {OPENCODE_AI!r}"
|
|
main_line = install_lines[0]
|
|
for pkg in REQUIRED_PACKAGES:
|
|
assert pkg in main_line, (
|
|
f"package {pkg!r} missing from the opencode-ai npm install line: {main_line!r}"
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import pytest
|
|
|
|
pytest.main([__file__, "-v"])
|