fix: propose retropie names per core, never into or-lists

This commit is contained in:
Abdessamad Derraz committed 2026-10-06 05:01:10 +02:00
1 parent 623b0a6d47
commit 2cdb98239e
3 files changed
+52 -4

No files matched your search

+28 -4
View File
@@ -142,12 +142,23 @@ class Exporter(BaseExporter):
@classmethod
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)
if clause is None:
return None
names = cls._names_in(clause.group(0))
return clause.start() + names[-1].end() if names else None
text = clause.group(0)
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
def _in_search_order(candidates: list[NativeFile]) -> list[str]:
@@ -164,6 +175,19 @@ class Exporter(BaseExporter):
names.append(fe.name)
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
def _join(names: list[str]) -> str:
"""RetroPie's own idiom: a, b and c."""
@@ -235,7 +259,7 @@ class Exporter(BaseExporter):
candidates = [
fe
for fe in files
if fe.required
if self._required_for(fe, core or "")
and not (
{fe.name.lower()}
| {str(a).lower() for a in (fe.native("aliases", []) or [])}
+6
View File
@@ -123,6 +123,10 @@ def _merge_file_into_system(
existing.setdefault("_source_refs", set())
if file_entry.get("required") and not existing.get("required"):
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"):
theirs = file_entry.get(h, "")
ours = existing.get(h, "")
@@ -214,6 +218,7 @@ def _merge_file_into_system(
elif isinstance(crc, str) and crc != crc.lower():
entry["crc32"] = crc.lower()
entry["_cores"] = {emu_name}
entry["_required_by"] = {emu_name} if file_entry.get("required") else set()
sr = file_entry.get("source_ref")
if sr is not None:
sr_key = _serialize_source_ref(sr)
@@ -387,6 +392,7 @@ def generate_platform_truth(
for sys_id, sys_data in systems.items():
for fe in sys_data.get("files", []):
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()))
# Add per-system coverage
cov = system_cores.get(sys_id, {})