fix: read a past pin only for its own repository

A source_commit string from before the field was keyed by mode pinned
the standalone repository, yet was read as a writing pin for every mode.
xenia-edge then saw its libretro pin move under unchanged prose, and
the recale and bump were refused.
This commit is contained in:
Abdessamad Derraz committed 2026-10-21 05:17:01 +02:00
1 parent 64b2967ffb
commit 31566ce618
2 files changed
+60 -6

No files matched your search

+38 -6
View File
@@ -2877,12 +2877,41 @@ def _scalar_values(document: dict) -> dict[str, str]:
}
def _pin_of(document: dict, field: str, mode: str = "") -> str | None:
"""A pin as the profile records it, read for one build mode when keyed."""
def _pin_of(
document: dict, field: str, mode: str = "",
repo: upstream.Repo | None = None,
) -> str | None:
"""A pin as the profile records it, read for one build mode when keyed.
With `repo`, a pin the document declares for another repository under
the field and mode does not count. A past revision can pin another
repository under the same field: xenia-edge's source_commit named the
has207/xenia-edge sha until the field became a dict keyed by mode, and
read for the libretro mode that old string passed for a pin of the
GitLab port that moved under unchanged prose.
"""
value = document.get(field)
if isinstance(value, dict):
value = value.get(mode) if mode else None
return value if isinstance(value, str) and value else None
if not (isinstance(value, str) and value):
return None
if repo is not None:
url_field = field.removesuffix("_commit")
declared = {
(mode_key, url)
for name, mode_key, url in declared_repositories(document)
if name == url_field
}
url = next(
(u for m, u in declared if m == mode),
next((u for m, u in declared if not m), None),
)
owner = upstream.parse_repo(url) if url else None
if owner is not None and (owner.host, owner.slug.lower()) != (
repo.host, repo.slug.lower()
):
return None
return value
_CITATION_RUN_RE = re.compile(
@@ -2906,7 +2935,8 @@ def _scalar_citations(text: str | None) -> tuple[str, ...] | None:
def _writing_pins(
revisions: list[tuple[str, dict]], intro_sha: str, field: str, mode: str = ""
revisions: list[tuple[str, dict]], intro_sha: str, field: str, mode: str = "",
repo: upstream.Repo | None = None,
) -> list[str]:
"""Distinct pins committed while the scalar held its current text.
@@ -2925,7 +2955,7 @@ def _writing_pins(
return []
pins: list[str] = []
for position in range(index, -1, -1):
value = _pin_of(revisions[position][1], field, mode)
value = _pin_of(revisions[position][1], field, mode, repo)
if value and value not in pins:
pins.append(value)
return pins
@@ -3038,7 +3068,9 @@ def _writing_pairs(
current = _pin_of(document, f"{pin_field}_commit", mode)
if not current:
continue
written = _writing_pins(revisions, intro_sha, f"{pin_field}_commit", mode)
written = _writing_pins(
revisions, intro_sha, f"{pin_field}_commit", mode, repo
)
if attested in written:
written = [attested]
if len(written) > 1:
+22
View File
@@ -2473,6 +2473,28 @@ class TestWriteDryRun(unittest.TestCase):
)
self.assertIn([(repo, "old", "new")], readings)
def test_a_pin_of_another_repository_is_no_writing_pin(self):
"""xenia-edge: source_commit named the has207/xenia-edge sha until it
became a dict whose libretro key pins a GitLab port. Read for that
mode, the old string passed for a pin of the port that moved under
unchanged prose, and the bump stayed refused for good."""
edge = "https://github.com/has207/xenia-edge"
port = "https://gitlab.com/x/xenia-libretro"
modes = {"standalone": edge, "libretro": port}
revisions = [
("c2", {"source": modes, "notes": "x",
"source_commit": {"standalone": "e1", "libretro": "p1"}}),
("c1", {"source": edge, "notes": "x", "source_commit": "e1"}),
]
document = dict(revisions[0][1])
repos = [("source", mode, profile_sync.upstream.parse_repo(url))
for mode, url in modes.items()]
readings, ambiguous = profile_sync._writing_pairs(
document, repos, revisions, "c1"
)
self.assertEqual(readings, [[]])
self.assertEqual(ambiguous, [])
def test_stale_prose_holds_the_pin(self):
"""boom3: a note written at an older pin is not anchored from this one."""
before = self.path.read_text()