Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions scripts/check_readme_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,12 @@ def main(argv: list[str] | None = None) -> int:
parser.add_argument(
"--check",
action="store_true",
help="Audit only and exit non-zero on drift (the CI-gate mode).",
help=(
"Exit non-zero on drift (the CI-gate mode). Without it, drift is "
"reported but the exit code stays 0 for informational, non-gating runs."
),
)
parser.parse_args(argv)
args = parser.parse_args(argv)

root = _repo_root()
drift = audit(root / "pyproject.toml", root / "README.md")
Expand All @@ -84,7 +87,7 @@ def main(argv: list[str] | None = None) -> int:
"the README sample to match. See ADR 0013.",
file=sys.stderr,
)
return 1
return 1 if args.check else 0
print("README sample-output version is in sync with the pyproject.toml anchor.")
return 0

Expand Down
59 changes: 59 additions & 0 deletions test/unit/test_check_readme_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""Regression tests for ``scripts/check_readme_version.py``.

AAASM-4942: the ``--check`` flag used to be a no-op β€” its parsed value was
discarded and drift always forced a non-zero exit. These tests pin the two
distinct modes so the flag can't silently regress back to a single mode:
``--check`` gates (exit 1 on drift) while the default reports drift but exits 0.
"""

from __future__ import annotations

import importlib.util
from pathlib import Path
from types import ModuleType

import pytest

_SCRIPT = Path(__file__).resolve().parents[2] / "scripts" / "check_readme_version.py"


def _load_module() -> ModuleType:
spec = importlib.util.spec_from_file_location("check_readme_version", _SCRIPT)
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module


def _write_tree(root: Path, *, anchor: str, sample: str) -> None:
(root / "pyproject.toml").write_text(f'[project]\nversion = "{anchor}"\n', encoding="utf-8")
(root / "README.md").write_text(f"aasm --version # e.g. aasm {sample}\n", encoding="utf-8")


@pytest.fixture
def script(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> tuple[ModuleType, Path]:
module = _load_module()
monkeypatch.setattr(module, "_repo_root", lambda: tmp_path)
return module, tmp_path


def test_check_exits_nonzero_on_drift(script: tuple[ModuleType, Path]) -> None:
module, root = script
_write_tree(root, anchor="0.0.1rc6", sample="9.9.9-STALE")

assert module.main(["--check"]) == 1


def test_default_reports_drift_but_exits_zero(script: tuple[ModuleType, Path]) -> None:
module, root = script
_write_tree(root, anchor="0.0.1rc6", sample="9.9.9-STALE")

assert module.main([]) == 0


def test_both_modes_pass_when_in_sync(script: tuple[ModuleType, Path]) -> None:
module, root = script
_write_tree(root, anchor="0.0.1rc6", sample="0.0.1rc6")

assert module.main(["--check"]) == 0
assert module.main([]) == 0