gabriel / muse public

test_tag_reflog.py file-level

at main · View file ↗ · Intel ↗

History
1 files
1 commits
0 hotspots
0 🧊 dead
0 💥 blast risk
sha256:e fix: get_signing_identity's MUSE_AGENT_KEY_FD path derived with entity_… · gabriel · Oct 22, 2026
1 """muse#54 item 5 -- reflog entries for `muse tag add` / `muse release add`.
2
3 `muse tag add` and `muse release add` move refs/tags/*-equivalent pointers
4 with no reflog trace at all before this change. Each gets its own reflog
5 namespace under .muse/logs/refs/tags/ (separate from branches), viewable
6 via `muse reflog --tag <name>`.
7 """
8 from __future__ import annotations
9
10 import datetime
11 import json
12 import pathlib
13
14 from tests.cli_test_helper import CliRunner
15 from muse.core.types import fake_id, Manifest
16 from muse.core.paths import ref_path, muse_dir
17
18 cli = None
19 runner = CliRunner()
20
21
22 def _env(root: pathlib.Path) -> Manifest:
23 return {"MUSE_REPO_ROOT": str(root)}
24
25
26 def _run(root: pathlib.Path, *args: str):
27 return runner.invoke(cli, list(args), env=_env(root))
28
29
30 def _init_repo(tmp_path: pathlib.Path) -> tuple[pathlib.Path, str]:
31 dot_muse = muse_dir(tmp_path)
32 dot_muse.mkdir()
33 repo_id = fake_id("repo")
34 (dot_muse / "repo.json").write_text(json.dumps({
35 "repo_id": repo_id, "domain": "code", "default_branch": "main",
36 "created_at": "2025-01-01T00:00:00+00:00",
37 }), encoding="utf-8")
38 (dot_muse / "HEAD").write_text("ref: refs/heads/main\n", encoding="utf-8")
39 (dot_muse / "refs" / "heads").mkdir(parents=True)
40 (dot_muse / "snapshots").mkdir()
41 (dot_muse / "commits").mkdir()
42 (dot_muse / "objects").mkdir()
43 return tmp_path, repo_id
44
45
46 def _make_commit(root: pathlib.Path, message: str = "feat: add") -> str:
47 from muse.core.ids import hash_snapshot, hash_commit
48 from muse.core.commits import CommitRecord, write_commit
49 from muse.core.snapshots import SnapshotRecord, write_snapshot
50
51 ref_file = ref_path(root, "main")
52 raw_parent = ref_file.read_text().strip() if ref_file.exists() else ""
53 parent_id: str | None = raw_parent if raw_parent else None
54 manifest: Manifest = {}
55 snap_id = hash_snapshot(manifest)
56 write_snapshot(root, SnapshotRecord(snapshot_id=snap_id, manifest=manifest))
57 now = datetime.datetime.now(datetime.timezone.utc)
58 parent_ids: list[str] = [parent_id] if parent_id else []
59 commit_id = hash_commit(
60 parent_ids=parent_ids, snapshot_id=snap_id, message=message,
61 committed_at_iso=now.isoformat(), author="gabriel",
62 )
63 write_commit(root, CommitRecord(
64 commit_id=commit_id, branch="main", snapshot_id=snap_id,
65 message=message, committed_at=now, parent_commit_id=parent_id,
66 author="gabriel",
67 ))
68 ref_file.write_text(commit_id, encoding="utf-8")
69 return commit_id
70
71
72 class TestTagAddReflog:
73 def test_new_tag_logs_creation_entry(self, tmp_path: pathlib.Path) -> None:
74 root, repo_id = _init_repo(tmp_path)
75 commit_id = _make_commit(root)
76
77 result = _run(root, "tag", "add", "v1.0.0")
78 assert result.exit_code == 0, result.output
79
80 from muse.core.reflog import read_tag_reflog
81 entries = read_tag_reflog(root, "v1.0.0")
82 assert len(entries) == 1
83 assert entries[0].new_id == commit_id
84 assert entries[0].old_id == "0" * 64
85 assert "tag: tagged v1.0.0" in entries[0].operation
86
87 def test_repointed_tag_logs_old_and_new_commit(self, tmp_path: pathlib.Path) -> None:
88 root, repo_id = _init_repo(tmp_path)
89 first_commit = _make_commit(root, message="first")
90 _run(root, "tag", "add", "v1.0.0")
91 second_commit = _make_commit(root, message="second")
92
93 result = _run(root, "tag", "add", "v1.0.0", "--json")
94 assert result.exit_code == 0, result.output
95
96 from muse.core.reflog import read_tag_reflog
97 entries = read_tag_reflog(root, "v1.0.0")
98 assert len(entries) == 2
99 assert entries[0].old_id == first_commit
100 assert entries[0].new_id == second_commit
101
102 def test_does_not_appear_in_head_reflog(self, tmp_path: pathlib.Path) -> None:
103 """Tagging doesn't move HEAD -- it must not pollute the HEAD/branch
104 reflog that `muse reflog` shows by default."""
105 root, repo_id = _init_repo(tmp_path)
106 _make_commit(root)
107
108 from muse.core.reflog import read_reflog
109 before = len(read_reflog(root))
110 _run(root, "tag", "add", "v1.0.0")
111 after = len(read_reflog(root))
112 assert after == before
113
114
115 class TestReleaseAddReflog:
116 def test_new_release_logs_creation_entry(self, tmp_path: pathlib.Path) -> None:
117 root, repo_id = _init_repo(tmp_path)
118 commit_id = _make_commit(root)
119
120 result = _run(root, "release", "add", "v1.0.0")
121 assert result.exit_code == 0, result.output
122
123 from muse.core.reflog import read_tag_reflog
124 entries = read_tag_reflog(root, "v1.0.0")
125 assert len(entries) == 1
126 assert entries[0].new_id == commit_id
127 assert "release: created v1.0.0" in entries[0].operation
128
129 def test_draft_release_notes_draft_in_operation(self, tmp_path: pathlib.Path) -> None:
130 root, repo_id = _init_repo(tmp_path)
131 _make_commit(root)
132 _run(root, "release", "add", "v1.0.0-beta", "--draft")
133
134 from muse.core.reflog import read_tag_reflog
135 entries = read_tag_reflog(root, "v1.0.0-beta")
136 assert "(draft)" in entries[0].operation
137
138
139 class TestReflogTagFlag:
140 def test_reflog_tag_shows_tag_history(self, tmp_path: pathlib.Path) -> None:
141 root, repo_id = _init_repo(tmp_path)
142 commit_id = _make_commit(root)
143 _run(root, "tag", "add", "v1.0.0")
144
145 result = _run(root, "reflog", "--tag", "v1.0.0", "--json")
146 assert result.exit_code == 0, result.output
147 data = json.loads(result.output)
148 assert data["ref"] == "refs/tags/v1.0.0"
149 assert data["total"] == 1
150 assert data["entries"][0]["new_id"] == commit_id
151
152 def test_reflog_tag_and_branch_mutually_exclusive(self, tmp_path: pathlib.Path) -> None:
153 root, repo_id = _init_repo(tmp_path)
154 _make_commit(root)
155 result = _run(root, "reflog", "--tag", "v1.0.0", "--branch", "main", "--json")
156 assert result.exit_code == 1
157
158 def test_reflog_tag_empty_when_tag_never_created(self, tmp_path: pathlib.Path) -> None:
159 root, repo_id = _init_repo(tmp_path)
160 _make_commit(root)
161 result = _run(root, "reflog", "--tag", "v9.9.9", "--json")
162 assert result.exit_code == 0, result.output
163 data = json.loads(result.output)
164 assert data["total"] == 0