mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-14 15:33:23 -05:00
fix: propose retropie names per core, never into or-lists
This commit is contained in:
1 parent
623b0a6d47
commit
2cdb98239e
3 files changed
+52
-4
No files matched your search
@@ -142,12 +142,23 @@ class Exporter(BaseExporter):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _insertion_point(cls, help_text: str) -> int | None:
|
def _insertion_point(cls, help_text: str) -> int | None:
|
||||||
"""Where a name joins the list, or None when there is no list."""
|
"""Where a name joins the list, or None when there is no list.
|
||||||
|
|
||||||
|
A list of alternatives ("a or b", "a/b") is not an enumeration: an
|
||||||
|
appended ", c" reads as one more required file and the plural turns
|
||||||
|
"one of these" into "all of these". Such a list is left alone.
|
||||||
|
"""
|
||||||
clause = _BIOS_CLAUSE.search(help_text)
|
clause = _BIOS_CLAUSE.search(help_text)
|
||||||
if clause is None:
|
if clause is None:
|
||||||
return None
|
return None
|
||||||
names = cls._names_in(clause.group(0))
|
text = clause.group(0)
|
||||||
return clause.start() + names[-1].end() if names else None
|
names = cls._names_in(text)
|
||||||
|
if not names:
|
||||||
|
return None
|
||||||
|
between = text[names[0].start():names[-1].end()]
|
||||||
|
if re.search(r"\bor\b|/", between):
|
||||||
|
return None
|
||||||
|
return clause.start() + names[-1].end()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _in_search_order(candidates: list[NativeFile]) -> list[str]:
|
def _in_search_order(candidates: list[NativeFile]) -> list[str]:
|
||||||
@@ -164,6 +175,19 @@ class Exporter(BaseExporter):
|
|||||||
names.append(fe.name)
|
names.append(fe.name)
|
||||||
return names
|
return names
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _required_for(fe: NativeFile, core: str) -> bool:
|
||||||
|
"""Whether the package's own core needs the file.
|
||||||
|
|
||||||
|
The merged `required` is true when any core needs it: pcsx_rearmed
|
||||||
|
runs in HLE without a BIOS, yet four were proposed as required for
|
||||||
|
its package because other PSX cores require them.
|
||||||
|
"""
|
||||||
|
required_by = (fe.truth or {}).get("_required_by")
|
||||||
|
if required_by is None:
|
||||||
|
return fe.required
|
||||||
|
return core in required_by
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _join(names: list[str]) -> str:
|
def _join(names: list[str]) -> str:
|
||||||
"""RetroPie's own idiom: a, b and c."""
|
"""RetroPie's own idiom: a, b and c."""
|
||||||
@@ -235,7 +259,7 @@ class Exporter(BaseExporter):
|
|||||||
candidates = [
|
candidates = [
|
||||||
fe
|
fe
|
||||||
for fe in files
|
for fe in files
|
||||||
if fe.required
|
if self._required_for(fe, core or "")
|
||||||
and not (
|
and not (
|
||||||
{fe.name.lower()}
|
{fe.name.lower()}
|
||||||
| {str(a).lower() for a in (fe.native("aliases", []) or [])}
|
| {str(a).lower() for a in (fe.native("aliases", []) or [])}
|
||||||
|
|||||||
@@ -123,6 +123,10 @@ def _merge_file_into_system(
|
|||||||
existing.setdefault("_source_refs", set())
|
existing.setdefault("_source_refs", set())
|
||||||
if file_entry.get("required") and not existing.get("required"):
|
if file_entry.get("required") and not existing.get("required"):
|
||||||
existing["required"] = True
|
existing["required"] = True
|
||||||
|
if file_entry.get("required"):
|
||||||
|
# Which cores need it: `required` above is the union, true when
|
||||||
|
# any core needs it, and a package of one core must not read it.
|
||||||
|
existing["_required_by"] = existing.get("_required_by", set()) | {emu_name}
|
||||||
for h in ("sha1", "md5", "sha256", "crc32"):
|
for h in ("sha1", "md5", "sha256", "crc32"):
|
||||||
theirs = file_entry.get(h, "")
|
theirs = file_entry.get(h, "")
|
||||||
ours = existing.get(h, "")
|
ours = existing.get(h, "")
|
||||||
@@ -214,6 +218,7 @@ def _merge_file_into_system(
|
|||||||
elif isinstance(crc, str) and crc != crc.lower():
|
elif isinstance(crc, str) and crc != crc.lower():
|
||||||
entry["crc32"] = crc.lower()
|
entry["crc32"] = crc.lower()
|
||||||
entry["_cores"] = {emu_name}
|
entry["_cores"] = {emu_name}
|
||||||
|
entry["_required_by"] = {emu_name} if file_entry.get("required") else set()
|
||||||
sr = file_entry.get("source_ref")
|
sr = file_entry.get("source_ref")
|
||||||
if sr is not None:
|
if sr is not None:
|
||||||
sr_key = _serialize_source_ref(sr)
|
sr_key = _serialize_source_ref(sr)
|
||||||
@@ -387,6 +392,7 @@ def generate_platform_truth(
|
|||||||
for sys_id, sys_data in systems.items():
|
for sys_id, sys_data in systems.items():
|
||||||
for fe in sys_data.get("files", []):
|
for fe in sys_data.get("files", []):
|
||||||
fe["_cores"] = sorted(fe.get("_cores", set()))
|
fe["_cores"] = sorted(fe.get("_cores", set()))
|
||||||
|
fe["_required_by"] = sorted(fe.get("_required_by", set()))
|
||||||
fe["_source_refs"] = sorted(fe.get("_source_refs", set()))
|
fe["_source_refs"] = sorted(fe.get("_source_refs", set()))
|
||||||
# Add per-system coverage
|
# Add per-system coverage
|
||||||
cov = system_cores.get(sys_id, {})
|
cov = system_cores.get(sys_id, {})
|
||||||
|
|||||||
@@ -177,5 +177,23 @@ class RecalboxKeepsItsOwnNotes(unittest.TestCase):
|
|||||||
truth={"md5": A, "note": "Loaded at libretro.c:120"})
|
truth={"md5": A, "note": "Loaded at libretro.c:120"})
|
||||||
self.assertNotIn("note=", Recalbox()._bios_element(fe, "psx"))
|
self.assertNotIn("note=", Recalbox()._bios_element(fe, "psx"))
|
||||||
|
|
||||||
|
class RetroPieProposals(unittest.TestCase):
|
||||||
|
def test_required_is_read_for_the_package_core(self):
|
||||||
|
from exporter.retropie_exporter import Exporter as RetroPie
|
||||||
|
|
||||||
|
fe = NativeFile("scph5501.bin", "scph5501.bin", "psx",
|
||||||
|
truth={"required": True, "_required_by": ["beetle_psx"],
|
||||||
|
"_cores": ["beetle_psx", "pcsx_rearmed"]})
|
||||||
|
self.assertTrue(RetroPie._required_for(fe, "beetle_psx"))
|
||||||
|
self.assertFalse(RetroPie._required_for(fe, "pcsx_rearmed"))
|
||||||
|
|
||||||
|
def test_a_list_of_alternatives_is_not_extended(self):
|
||||||
|
from exporter.retropie_exporter import Exporter as RetroPie
|
||||||
|
|
||||||
|
alternatives = "Copy the required BIOS file a.rom or b.rom to $biosdir"
|
||||||
|
enumeration = "Copy the required BIOS files a.rom and b.rom to $biosdir"
|
||||||
|
self.assertIsNone(RetroPie._insertion_point(alternatives))
|
||||||
|
self.assertIsNotNone(RetroPie._insertion_point(enumeration))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
Reference in new issue
Block a user