mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-01 00:27:20 -05:00
fix: judge each build's refs in its own tree
A profile keyed by build mode compared a part in every repository and kept the best outcome: xenia-edge's libretro tree carries emulator.cc offset, and its lines vouched for standalone refs that had moved 4 lines. A part of an entry with a mode is read in that build's repository, and a part naming none in the first build declared, as _realign_part decides.
This commit is contained in:
1 parent
06492ec6b8
commit
68f42bf8e2
2 files changed
+82
-6
No files matched your search
+35
-6
@@ -131,6 +131,9 @@ class RepoView:
|
||||
head: str
|
||||
origin: str
|
||||
field: str
|
||||
# The build mode a keyed source names this repository under (ymir,
|
||||
# xenia-edge): `standalone` or `libretro`, empty for a plain URL.
|
||||
mode: str = ""
|
||||
|
||||
|
||||
HASH_FIELDS = ("sha1", "md5", "crc32", "sha256", "known_hash_adler32")
|
||||
@@ -1149,7 +1152,7 @@ def select_views(
|
||||
if relation and relation[0] == 0 and relation[1] > 0:
|
||||
head = upstream.resolve_head(repo, cache_dir, offline, branch, fresh=True) or head
|
||||
seen.add((repo.host, repo.slug))
|
||||
views.append(RepoView(repo, pin, head, origin, field))
|
||||
views.append(RepoView(repo, pin, head, origin, field, mode))
|
||||
if gone and not views:
|
||||
raise upstream.GoneError(f"{profile.get('emulator', '?')}: every declared repository is gone")
|
||||
views = _follow_fork_base(_follow_submodule(views, cache_dir, offline), cache_dir, offline)
|
||||
@@ -1528,6 +1531,7 @@ def build_report(
|
||||
for _, _, url in declared_repositories(profile)
|
||||
if (repo := upstream.parse_repo(url)) is not None
|
||||
)
|
||||
modes = {mode for _, mode, _ in declared_repositories(profile) if mode}
|
||||
refs = []
|
||||
for citation in collect_citations(profile, text):
|
||||
if citation.kind == "ref":
|
||||
@@ -1538,10 +1542,14 @@ def build_report(
|
||||
# The repository a part says its lines are in (`upstream
|
||||
# src/a.c:5`) stays on that part: the same path can be cited
|
||||
# under both roles in one profile.
|
||||
# An entry of one build mode reads that build's repository when
|
||||
# the profile keys its source by mode.
|
||||
mode = str(citation.label or entry.get("mode") or "")
|
||||
mode = mode if mode in modes else ""
|
||||
parts = [
|
||||
RefPart(
|
||||
strip_repo_word(p.path, known), p.start, p.end, p.raw,
|
||||
ref_role(p.path)[0],
|
||||
ref_role(p.path)[0] or mode,
|
||||
)
|
||||
for p in split_source_ref(citation.ref)
|
||||
]
|
||||
@@ -1773,8 +1781,14 @@ def build_report(
|
||||
return 2
|
||||
return 1 if line.strip() else 0
|
||||
|
||||
# A part that names its repository is looked up there first.
|
||||
ordered = sorted(views, key=lambda v: _view_role(v) != wanted) if wanted else views
|
||||
# A part that names its repository is looked up there first. In a
|
||||
# profile keyed by build mode, a part naming none belongs to the
|
||||
# first build declared, as _realign_part decides a shared path: the
|
||||
# libretro tree of xenia-edge carries emulator.cc offset, and its
|
||||
# better-scored line hid a standalone ref that had moved.
|
||||
if not wanted and primary.mode:
|
||||
wanted = primary.mode
|
||||
ordered = sorted(views, key=lambda v: not _answers(v, wanted)) if wanted else views
|
||||
best = None
|
||||
for candidate in candidates:
|
||||
for sha_of in (lambda v: v.pin, lambda v: v.head):
|
||||
@@ -1789,6 +1803,11 @@ def build_report(
|
||||
continue
|
||||
candidate = target
|
||||
rank = score(found)
|
||||
if rank and _answers(view, wanted) and view.mode:
|
||||
# An entry of one build mode is that build's code:
|
||||
# xenia-edge's standalone xbox.xex refs scored higher
|
||||
# in the libretro tree, whose same file is offset.
|
||||
return view, candidate
|
||||
if rank == 3 and not wanted and _view_role(view) == "source":
|
||||
# The port carries a copy of the emulator: when the
|
||||
# original holds the same value on the cited line,
|
||||
@@ -1964,8 +1983,12 @@ def build_report(
|
||||
view for view in views
|
||||
if fetch_from(view.repo, view.pin, part.path) is not None
|
||||
]
|
||||
named = [view for view in carrying if _view_role(view) == part.role]
|
||||
if part.role and named:
|
||||
# Judged in the build it belongs to: the best outcome across the
|
||||
# builds of a keyed profile let the libretro tree vouch for a
|
||||
# standalone ref that had moved (xenia-edge's emulator.cc).
|
||||
meant = part.role or primary.mode
|
||||
named = [view for view in carrying if _answers(view, meant)]
|
||||
if meant and named:
|
||||
carrying = named
|
||||
live = {
|
||||
id(view) for view in carrying
|
||||
@@ -3009,6 +3032,12 @@ def _view_role(view: RepoView) -> str:
|
||||
return "upstream" if view.field == "upstream" else "source"
|
||||
|
||||
|
||||
def _answers(view: RepoView, role: str) -> bool:
|
||||
"""Whether a part written under *role* means this repository: the field
|
||||
it comes from, or the build mode a keyed source declares it under."""
|
||||
return bool(role) and role in (_view_role(view), view.mode)
|
||||
|
||||
|
||||
ATTRIBUTED_STATUSES = ("ANCHORED", "SHIFTED", "RENAMED", "MOVED", "CHANGED")
|
||||
|
||||
|
||||
|
||||
@@ -2845,6 +2845,53 @@ class TestWriteDryRun(unittest.TestCase):
|
||||
self.assertEqual(self.path.read_text(), before)
|
||||
|
||||
|
||||
class AKeyedProfileJudgesEachBuildInItsOwnTree(TestBuildReport):
|
||||
"""xenia-edge's standalone emulator.cc block moved down 4 lines while
|
||||
the libretro tree, at HEAD, carried the same path offset: the best
|
||||
outcome across repositories reported ANCHORED and the move went unseen."""
|
||||
|
||||
def _keyed(self, mode=None):
|
||||
entry = {"name": "f.bin", "source_ref": "a.c:2"}
|
||||
if mode:
|
||||
entry["mode"] = mode
|
||||
return {
|
||||
"emulator": "Test",
|
||||
"source": {"standalone": "https://github.com/o/edge",
|
||||
"libretro": "https://github.com/o/port"},
|
||||
"upstream": "https://github.com/o/edge",
|
||||
"source_commit": {"standalone": "spin", "libretro": "lpin"},
|
||||
"files": [entry],
|
||||
}
|
||||
|
||||
def _two_builds(self):
|
||||
trees = {
|
||||
("o/edge", "spin", "a.c"): ["x", "f.bin cited"],
|
||||
("o/edge", "shead", "a.c"): ["pad", "pad", "x", "f.bin cited"],
|
||||
("o/port", "lpin", "a.c"): ["y", "f.bin cited"],
|
||||
}
|
||||
heads = {"o/edge": "shead", "o/port": "lpin"}
|
||||
profile_sync.upstream.fetch_file = (
|
||||
lambda repo, sha, path, cache_dir, offline=False:
|
||||
trees.get((repo.slug, sha, path))
|
||||
)
|
||||
profile_sync.upstream.resolve_head = (
|
||||
lambda repo, cache_dir, offline=False, branch=None, fresh=False:
|
||||
heads[repo.slug]
|
||||
)
|
||||
|
||||
def _status(self, profile):
|
||||
self._two_builds()
|
||||
report = build_report("test", profile, self.dir)
|
||||
return report.entries[0].parts[0].status
|
||||
|
||||
def test_a_part_naming_no_build_is_the_first_builds(self):
|
||||
self.assertEqual(self._status(self._keyed()), "SHIFTED")
|
||||
|
||||
def test_an_entry_of_one_mode_is_read_in_that_build(self):
|
||||
self.assertEqual(self._status(self._keyed("standalone")), "SHIFTED")
|
||||
self.assertNotEqual(self._status(self._keyed("libretro")), "SHIFTED")
|
||||
|
||||
|
||||
class TestDeliberatelyFrozenPin(TestBuildReport):
|
||||
"""A pin held on purpose is judged against itself, like a frozen tag.
|
||||
|
||||
|
||||
Reference in new issue
Block a user