Verified with the coordinated workspace changes by devkit full run 2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed). This shared UI pass does not mark the individual module reviews complete.
159 lines
4.8 KiB
Python
Executable File
159 lines
4.8 KiB
Python
Executable File
"""Public CLI contracts and an executable portable-project smoke fixture."""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "tools/devkit"))
|
|
from govoplan_devkit import cli, doctor, runner
|
|
from govoplan_devkit.common import META_ROOT
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"arguments",
|
|
[["--json", "commands"], ["commands", "--json"], ["commands", "--format", "json"]],
|
|
)
|
|
def test_global_output_flags_work_on_either_side_of_command(arguments, capsys):
|
|
assert cli.main(arguments) == 0
|
|
output = json.loads(capsys.readouterr().out)
|
|
names = {item["command"] for item in output["commands"]}
|
|
assert {"context", "check", "doctor", "docs", "issues", "release", "git"} <= names
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"command",
|
|
[
|
|
"context",
|
|
"doctor",
|
|
"check",
|
|
"resume",
|
|
"recover",
|
|
"docs",
|
|
"review",
|
|
"issues",
|
|
"release",
|
|
"git",
|
|
],
|
|
)
|
|
def test_command_help_does_not_require_live_services(command, capsys):
|
|
with pytest.raises(SystemExit) as stopped:
|
|
cli.main([command, "--help"])
|
|
assert stopped.value.code == 0
|
|
assert "usage:" in capsys.readouterr().out
|
|
|
|
|
|
def test_portable_project_executes_registered_commands_and_reads_receipt(
|
|
tmp_path, capsys, monkeypatch
|
|
):
|
|
monkeypatch.setenv("XDG_STATE_HOME", str(tmp_path / "state"))
|
|
repo = tmp_path / "example"
|
|
repo.mkdir()
|
|
subprocess.run(["git", "init", "-q", str(repo)], check=True)
|
|
subprocess.run(
|
|
[
|
|
"git",
|
|
"-C",
|
|
str(repo),
|
|
"-c",
|
|
"user.name=Fixture",
|
|
"-c",
|
|
"user.email=fixture@example.invalid",
|
|
"commit",
|
|
"--allow-empty",
|
|
"-qm",
|
|
"fixture",
|
|
],
|
|
check=True,
|
|
)
|
|
project = tmp_path / "project.json"
|
|
project.write_text(
|
|
json.dumps(
|
|
{
|
|
"schema_version": 1,
|
|
"name": "Portable",
|
|
"repositories": [{"name": "example", "path": "example"}],
|
|
"checks": [
|
|
{
|
|
"id": "test",
|
|
"argv": ["{python}", "-c", "print('portable ok')"],
|
|
"cwd": "example",
|
|
}
|
|
],
|
|
"profiles": {"quick": ["test"]},
|
|
}
|
|
)
|
|
)
|
|
common = ["--workspace-root", str(tmp_path), "--project", str(project), "--json"]
|
|
with patch.object(runner, "environment_fingerprint", return_value="fixture"):
|
|
assert cli.main(common + ["check", "--profile", "quick"]) == 0
|
|
result = json.loads(capsys.readouterr().out)
|
|
assert result["status"] == "passed"
|
|
assert cli.main(["status", result["run_id"], *common]) == 0
|
|
status = json.loads(capsys.readouterr().out)
|
|
assert status["snapshot_verified"] is True
|
|
assert cli.main(["logs", result["run_id"], "--stage", "test", *common]) == 0
|
|
assert "portable ok" in capsys.readouterr().out
|
|
|
|
|
|
def test_portable_example_matches_published_schema():
|
|
import jsonschema
|
|
|
|
jsonschema.validate(
|
|
json.loads((META_ROOT / "tools/devkit/examples/project.json").read_text()),
|
|
json.loads((META_ROOT / "tools/devkit/project.schema.json").read_text()),
|
|
)
|
|
|
|
|
|
def test_malformed_project_is_a_controlled_json_error(tmp_path, capsys):
|
|
project = tmp_path / "bad.json"
|
|
project.write_text('{"schema_version":true,"repositories":[]}')
|
|
assert (
|
|
cli.main(
|
|
[
|
|
"context",
|
|
"--workspace-root",
|
|
str(tmp_path),
|
|
"--project",
|
|
str(project),
|
|
"--json",
|
|
]
|
|
)
|
|
== 2
|
|
)
|
|
assert json.loads(capsys.readouterr().out)["status"] == "error"
|
|
|
|
|
|
def test_doctor_is_read_only_and_preserves_dependency_warnings(tmp_path, capsys):
|
|
project = tmp_path / "project.json"
|
|
project.write_text(
|
|
json.dumps(
|
|
{"schema_version": 1, "repositories": [{"name": "example", "path": "."}]}
|
|
)
|
|
)
|
|
(tmp_path / "package.json").write_text("{}")
|
|
before = set(tmp_path.iterdir())
|
|
with (
|
|
patch.object(doctor, "tool_version", return_value="fixture"),
|
|
patch.object(doctor, "inspect_repository", return_value={"errors": []}),
|
|
):
|
|
assert (
|
|
cli.main(
|
|
[
|
|
"doctor",
|
|
"--workspace-root",
|
|
str(tmp_path),
|
|
"--project",
|
|
str(project),
|
|
"--json",
|
|
]
|
|
)
|
|
== 0
|
|
)
|
|
output = json.loads(capsys.readouterr().out)
|
|
assert any(item["status"] == "warning" for item in output["checks"])
|
|
assert set(tmp_path.iterdir()) == before
|