From 31566ce618b80f20650426d7bd6776d3d1cefb2b Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Wed, 21 Oct 2026 05:17:01 +0200 Subject: [PATCH] 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. --- scripts/profile_sync.py | 44 ++++++++++++++++++++++++++++++++------ tests/test_profile_sync.py | 22 +++++++++++++++++++ 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/scripts/profile_sync.py b/scripts/profile_sync.py index 378729c9..b7459194 100644 --- a/scripts/profile_sync.py +++ b/scripts/profile_sync.py @@ -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: diff --git a/tests/test_profile_sync.py b/tests/test_profile_sync.py index 1dbc8b29..ebfedead 100644 --- a/tests/test_profile_sync.py +++ b/tests/test_profile_sync.py @@ -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()