mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-10 13:33:24 -05:00
fix: arbitrate slots on the strongest profile proof
This commit is contained in:
1 parent
a8415c33c3
commit
16f4c071fe
2 files changed
+46
-4
No files matched your search
+26
-4
@@ -319,6 +319,15 @@ def pack_overrides(
|
|||||||
return overrides
|
return overrides
|
||||||
|
|
||||||
|
|
||||||
|
def _strongest(claims: list[Claim]) -> Claim:
|
||||||
|
"""The profile claim with the strongest proof; the first emulator breaks ties.
|
||||||
|
|
||||||
|
yaps2 pins its GameIndex.yaml by sha1 while armsx2 and lrps2 only match a
|
||||||
|
path: alphabetical order served armsx2's copy to all three.
|
||||||
|
"""
|
||||||
|
return max(claims, key=lambda claim: (_claim_rank(claim), -claims.index(claim)))
|
||||||
|
|
||||||
|
|
||||||
def arbitrate(conflict: Conflict, mode: str, addressee: str = "platform") -> Decision:
|
def arbitrate(conflict: Conflict, mode: str, addressee: str = "platform") -> Decision:
|
||||||
"""Decide a contested destination for the pack being built.
|
"""Decide a contested destination for the pack being built.
|
||||||
|
|
||||||
@@ -333,7 +342,7 @@ def arbitrate(conflict: Conflict, mode: str, addressee: str = "platform") -> Dec
|
|||||||
addressee decides; the loss is reported rather than absorbed, because the
|
addressee decides; the loss is reported rather than absorbed, because the
|
||||||
cause is an upstream declaration that needs fixing at its source.
|
cause is an upstream declaration that needs fixing at its source.
|
||||||
"""
|
"""
|
||||||
profile = conflict.profile_claims[0]
|
profile = _strongest(conflict.profile_claims)
|
||||||
if addressee == "emulator":
|
if addressee == "emulator":
|
||||||
return Decision(conflict, profile, ADDRESSEE)
|
return Decision(conflict, profile, ADDRESSEE)
|
||||||
if not nativemode.reads_file_contents(mode):
|
if not nativemode.reads_file_contents(mode):
|
||||||
@@ -345,11 +354,24 @@ def format_decision(decision: Decision) -> str:
|
|||||||
"""One line naming the contested slot, the winner and the ground for it."""
|
"""One line naming the contested slot, the winner and the ground for it."""
|
||||||
conflict = decision.conflict
|
conflict = decision.conflict
|
||||||
if decision.serves_both:
|
if decision.serves_both:
|
||||||
return (
|
winner = decision.winner.local_path
|
||||||
f"{conflict.destination}: serve {decision.winner.local_path} "
|
served = sorted({
|
||||||
f"({', '.join(conflict.emulators) or 'profile'}); the frontend only "
|
c.emulator for c in conflict.profile_claims
|
||||||
|
if c.emulator and c.local_path == winner
|
||||||
|
})
|
||||||
|
others = sorted({
|
||||||
|
c.emulator for c in conflict.profile_claims
|
||||||
|
if c.emulator and c.local_path != winner
|
||||||
|
})
|
||||||
|
line = (
|
||||||
|
f"{conflict.destination}: serve {winner} "
|
||||||
|
f"({', '.join(served) or 'profile'}); the frontend only "
|
||||||
"checks the path, so both are satisfied"
|
"checks the path, so both are satisfied"
|
||||||
)
|
)
|
||||||
|
if others:
|
||||||
|
# One path holds one file: an emulator pinning another is not served.
|
||||||
|
line += f"; {', '.join(others)} expected another file"
|
||||||
|
return line
|
||||||
if decision.reason == ADDRESSEE:
|
if decision.reason == ADDRESSEE:
|
||||||
return (
|
return (
|
||||||
f"{conflict.destination}: serve {decision.winner.local_path}, "
|
f"{conflict.destination}: serve {decision.winner.local_path}, "
|
||||||
|
|||||||
@@ -555,5 +555,25 @@ class ManifestFollowsTheArbitration(unittest.TestCase):
|
|||||||
self.assertEqual(by_dest[dest]["repo_path"], path)
|
self.assertEqual(by_dest[dest]["repo_path"], path)
|
||||||
|
|
||||||
|
|
||||||
|
class StrongestProfileClaimWins(unittest.TestCase):
|
||||||
|
"""yaps2 pins GameIndex.yaml by sha1; armsx2 matched a path only."""
|
||||||
|
|
||||||
|
def test_hash_proof_beats_path_proof(self):
|
||||||
|
from slots import Claim, Conflict, arbitrate, format_decision
|
||||||
|
|
||||||
|
def claim(emu, path, status):
|
||||||
|
return Claim("profile", "pcsx2/resources/GameIndex.yaml", "GameIndex.yaml",
|
||||||
|
emulator=emu, local_path=path, status=status)
|
||||||
|
|
||||||
|
conflict = Conflict(
|
||||||
|
"pcsx2/resources/GameIndex.yaml",
|
||||||
|
Claim("platform", "pcsx2/resources/GameIndex.yaml", "GameIndex.yaml",
|
||||||
|
local_path="p", status="path_exact"),
|
||||||
|
[claim("armsx2", "a", "path_exact"), claim("yaps2", "y", "sha1_exact")],
|
||||||
|
)
|
||||||
|
decision = arbitrate(conflict, "existence")
|
||||||
|
self.assertEqual(decision.winner.emulator, "yaps2")
|
||||||
|
self.assertIn("armsx2 expected another file", format_decision(decision))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
Reference in new issue
Block a user