mirror of
https://github.com/razzant/ouroboros.git
synced 2026-08-04 08:09:48 +00:00
161 lines
5.2 KiB
Python
161 lines
5.2 KiB
Python
from __future__ import annotations
|
|
|
|
import pathlib
|
|
import subprocess
|
|
|
|
|
|
def _git(repo: pathlib.Path, *args: str) -> str:
|
|
result = subprocess.run(
|
|
["git", *args],
|
|
cwd=str(repo),
|
|
check=True,
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
return result.stdout.strip()
|
|
|
|
|
|
def _repo(tmp_path: pathlib.Path) -> pathlib.Path:
|
|
repo = tmp_path / "repo"
|
|
repo.mkdir()
|
|
_git(repo, "init")
|
|
_git(repo, "config", "user.name", "Binding Test")
|
|
_git(repo, "config", "user.email", "binding@example.test")
|
|
(repo / "VERSION").write_text("1.0.0\n", encoding="utf-8")
|
|
(repo / "app.txt").write_text("base\n", encoding="utf-8")
|
|
_git(repo, "add", "-A")
|
|
_git(repo, "commit", "-m", "base")
|
|
return repo
|
|
|
|
|
|
def test_staged_fingerprint_binds_tree_parent_version_and_expected_tag(tmp_path):
|
|
from ouroboros.tools.git import _fingerprint_staged_diff
|
|
|
|
repo = _repo(tmp_path)
|
|
parent = _git(repo, "rev-parse", "HEAD")
|
|
(repo / "VERSION").write_text("1.1.0\n", encoding="utf-8")
|
|
(repo / "app.txt").write_text("release\n", encoding="utf-8")
|
|
_git(repo, "add", "-A")
|
|
|
|
result = _fingerprint_staged_diff(repo)
|
|
binding = result["binding"]
|
|
|
|
assert result["ok"] is True
|
|
assert binding["tree_sha"] == _git(repo, "write-tree")
|
|
assert binding["parents"] == [parent]
|
|
assert binding["staged_version"] == "1.1.0"
|
|
assert binding["version_staged"] is True
|
|
assert binding["expected_tag"] == "v1.1.0"
|
|
assert binding["existing_tag_target"] == ""
|
|
assert len(binding["diff_sha256"]) == 64
|
|
|
|
|
|
def test_staged_fingerprint_binds_all_merge_parents(tmp_path):
|
|
from ouroboros.tools.git import (
|
|
_fingerprint_staged_diff,
|
|
_verify_reviewed_commit_binding,
|
|
)
|
|
|
|
repo = _repo(tmp_path)
|
|
base_branch = _git(repo, "branch", "--show-current")
|
|
_git(repo, "checkout", "-b", "side")
|
|
(repo / "side.txt").write_text("side\n", encoding="utf-8")
|
|
_git(repo, "add", "-A")
|
|
_git(repo, "commit", "-m", "side")
|
|
side_sha = _git(repo, "rev-parse", "HEAD")
|
|
_git(repo, "checkout", base_branch)
|
|
(repo / "main.txt").write_text("main\n", encoding="utf-8")
|
|
_git(repo, "add", "-A")
|
|
_git(repo, "commit", "-m", "main")
|
|
first_parent = _git(repo, "rev-parse", "HEAD")
|
|
_git(repo, "merge", "--no-ff", "--no-commit", "side")
|
|
|
|
fingerprint = _fingerprint_staged_diff(repo)
|
|
|
|
assert fingerprint["binding"]["parents"] == [first_parent, side_sha]
|
|
_git(repo, "commit", "-m", "merge")
|
|
commit_sha = _git(repo, "rev-parse", "HEAD")
|
|
ok, detail = _verify_reviewed_commit_binding(
|
|
repo, commit_sha, fingerprint, verify_expected_tag=False
|
|
)
|
|
assert ok is True, detail
|
|
|
|
|
|
def test_existing_expected_tag_is_a_pre_review_collision(tmp_path):
|
|
from ouroboros.tools.git import (
|
|
_fingerprint_staged_diff,
|
|
_review_binding_precondition_error,
|
|
)
|
|
|
|
repo = _repo(tmp_path)
|
|
old_target = _git(repo, "rev-parse", "HEAD")
|
|
_git(repo, "tag", "v1.1.0", old_target)
|
|
(repo / "VERSION").write_text("1.1.0\n", encoding="utf-8")
|
|
_git(repo, "add", "VERSION")
|
|
|
|
fingerprint = _fingerprint_staged_diff(repo)
|
|
message = _review_binding_precondition_error(fingerprint)
|
|
|
|
assert fingerprint["binding"]["existing_tag_target"] == old_target
|
|
assert "already targets" in message
|
|
assert "immutable" in message
|
|
|
|
|
|
def test_commit_and_release_tag_must_match_reviewed_binding(tmp_path):
|
|
from ouroboros.tools.git import (
|
|
_auto_tag_on_version_bump,
|
|
_fingerprint_staged_diff,
|
|
_verify_reviewed_commit_binding,
|
|
)
|
|
|
|
repo = _repo(tmp_path)
|
|
(repo / "VERSION").write_text("1.1.0\n", encoding="utf-8")
|
|
(repo / "app.txt").write_text("release\n", encoding="utf-8")
|
|
_git(repo, "add", "-A")
|
|
fingerprint = _fingerprint_staged_diff(repo)
|
|
_git(repo, "commit", "-m", "release")
|
|
commit_sha = _git(repo, "rev-parse", "HEAD")
|
|
|
|
ok, detail = _verify_reviewed_commit_binding(
|
|
repo, commit_sha, fingerprint, verify_expected_tag=False
|
|
)
|
|
assert ok is True, detail
|
|
ok, detail = _verify_reviewed_commit_binding(
|
|
repo, commit_sha, fingerprint, verify_expected_tag=True
|
|
)
|
|
assert ok is False
|
|
assert "expected tag" in detail
|
|
|
|
tag_info = _auto_tag_on_version_bump(
|
|
repo,
|
|
"release",
|
|
expected_commit_sha=commit_sha,
|
|
expected_tag="v1.1.0",
|
|
)
|
|
assert "tagged: v1.1.0" in tag_info
|
|
ok, detail = _verify_reviewed_commit_binding(
|
|
repo, commit_sha, fingerprint, verify_expected_tag=True
|
|
)
|
|
assert ok is True, detail
|
|
|
|
|
|
def test_auto_tag_refuses_to_accept_existing_tag_on_other_commit(tmp_path):
|
|
from ouroboros.tools.git import _auto_tag_on_version_bump
|
|
|
|
repo = _repo(tmp_path)
|
|
old_target = _git(repo, "rev-parse", "HEAD")
|
|
(repo / "VERSION").write_text("1.1.0\n", encoding="utf-8")
|
|
_git(repo, "add", "VERSION")
|
|
_git(repo, "commit", "-m", "release")
|
|
commit_sha = _git(repo, "rev-parse", "HEAD")
|
|
_git(repo, "tag", "v1.1.0", old_target)
|
|
|
|
result = _auto_tag_on_version_bump(
|
|
repo,
|
|
"release",
|
|
expected_commit_sha=commit_sha,
|
|
expected_tag="v1.1.0",
|
|
)
|
|
|
|
assert "tag target mismatch" in result
|
|
assert _git(repo, "rev-parse", "v1.1.0^{commit}") == old_target
|