mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-10 21:43:23 -05:00
fix: exporters keep what the maintainer wrote
This commit is contained in:
1 parent
3baec1794b
commit
8fb65b8e97
4 files changed
+133
-20
No files matched your search
@@ -62,10 +62,29 @@ class Exporter(BaseExporter):
|
||||
# The data block is a fraction of the file; the rest is the checker.
|
||||
return True
|
||||
|
||||
def _bios_files(self, files: list[NativeFile]) -> str:
|
||||
return ", ".join(self._bios_items(files))
|
||||
def _bios_files(self, files: list[NativeFile], before: dict | None = None) -> str:
|
||||
return ", ".join(self._bios_items(files, before))
|
||||
|
||||
def _bios_items(self, files: list[NativeFile]) -> list[str]:
|
||||
@staticmethod
|
||||
def _runner_keys(item: dict | None) -> list[str]:
|
||||
"""The emulator and core checkBios reads through coreExists().
|
||||
|
||||
Not in our model, so they travel from the maintainer's own entry: a
|
||||
rewritten item without them made the checker treat the BIOS as
|
||||
wanted by every build (vectrex, tvc, macintosh, bk).
|
||||
"""
|
||||
return [
|
||||
f'"{key}": "{item[key]}"'
|
||||
for key in ("emulator", "core")
|
||||
if item and isinstance(item.get(key), str)
|
||||
]
|
||||
|
||||
def _bios_items(self, files: list[NativeFile], before: dict | None = None) -> list[str]:
|
||||
originals = {
|
||||
str(item.get("file", "")): item
|
||||
for item in (before or {}).get("biosFiles", [])
|
||||
if isinstance(item, dict)
|
||||
}
|
||||
parts: list[str] = []
|
||||
for fe in files:
|
||||
# The platform states an unhashed file as an empty md5 rather
|
||||
@@ -80,14 +99,25 @@ class Exporter(BaseExporter):
|
||||
zipped = fe.native("zipped_file", "")
|
||||
if zipped:
|
||||
item.append(f'"zippedFile": "{zipped}"')
|
||||
item.extend(self._runner_keys(originals.get(path)))
|
||||
parts.append("{ " + ", ".join(item) + " }")
|
||||
return parts
|
||||
|
||||
def _entry_line(self, system: NativeSystem, files: list[NativeFile]) -> str:
|
||||
@staticmethod
|
||||
def _own_entry(system: NativeSystem, before: dict | None) -> dict:
|
||||
"""The maintainer's entry for this system, out of the parsed pair."""
|
||||
inner = (before or {}).get(system.native_id)
|
||||
return inner if isinstance(inner, dict) else {}
|
||||
|
||||
def _entry_line(
|
||||
self, system: NativeSystem, files: list[NativeFile], before: dict | None = None
|
||||
) -> str:
|
||||
own = self._own_entry(system, before)
|
||||
runner = "".join(f"{key}, " for key in self._runner_keys(own))
|
||||
return (
|
||||
f'{_INDENT}"{system.native_id}": '
|
||||
f'{{ "name": "{self.display_name(system)}", '
|
||||
f'"biosFiles": [ {self._bios_files(files)} ] }},'
|
||||
f'{{ "name": "{self.display_name(system)}", {runner}'
|
||||
f'"biosFiles": [ {self._bios_files(files, own)} ] }},'
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@@ -127,14 +157,17 @@ class Exporter(BaseExporter):
|
||||
) -> list[str]:
|
||||
"""One entry, keeping the layout and the notes it was written with."""
|
||||
trailing, leading = self._item_notes(original)
|
||||
items = self._bios_items(files)
|
||||
before = self._parse_entry(original)
|
||||
own = self._own_entry(system, before)
|
||||
items = self._bios_items(files, own)
|
||||
one_line = len(original) == 1 and not trailing and not leading
|
||||
if one_line:
|
||||
return [self._entry_line(system, files)]
|
||||
return [self._entry_line(system, files, before)]
|
||||
|
||||
runner = "".join(f"{key}, " for key in self._runner_keys(own))
|
||||
head = (
|
||||
f'{_INDENT}"{system.native_id}": '
|
||||
f'{{ "name": "{self.display_name(system)}", "biosFiles": ['
|
||||
f'{{ "name": "{self.display_name(system)}", {runner}"biosFiles": ['
|
||||
)
|
||||
pad = " " * (len(_INDENT) + 4)
|
||||
lines = [head]
|
||||
@@ -244,8 +277,8 @@ class Exporter(BaseExporter):
|
||||
continue
|
||||
written.add(key)
|
||||
original_lines = body[start:end + 1]
|
||||
replacement = self._entry_line(*pair)
|
||||
before = self._parse_entry(original_lines)
|
||||
replacement = self._entry_line(*pair, before)
|
||||
after = self._parse_entry([replacement])
|
||||
if before is not None and before == after:
|
||||
# Nothing changed: keep the maintainer's own lines, comments
|
||||
|
||||
@@ -82,8 +82,15 @@ class Exporter(BaseExporter):
|
||||
for fe in system.files:
|
||||
# A SHA1 BizHawk declares is BizHawk's own code, the authority
|
||||
# for its cores: the truth's MSX.rom came from FBNeo and would
|
||||
# have made MSXHawk refuse the dump it accepts.
|
||||
if fe.hash("sha1") and not _hash_values(fe.platform or {}, "sha1"):
|
||||
# have made MSXHawk refuse the dump it accepts. An entry the
|
||||
# database never declared (can_add refuses it) names no call
|
||||
# of its own either: by name it would rewrite the homonym of
|
||||
# another system.
|
||||
if (
|
||||
fe.platform is not None
|
||||
and fe.hash("sha1")
|
||||
and not _hash_values(fe.platform, "sha1")
|
||||
):
|
||||
seen.setdefault(fe.name.casefold(), []).append(fe)
|
||||
resolved: dict[str, NativeFile] = {}
|
||||
for name, entries in seen.items():
|
||||
|
||||
@@ -176,8 +176,8 @@ class Exporter(BaseExporter):
|
||||
return nested, "bios"
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _merge(existing: object, ours: list[OrderedDict]) -> list[OrderedDict]:
|
||||
@classmethod
|
||||
def _merge(cls, existing: object, ours: list[OrderedDict]) -> list[OrderedDict]:
|
||||
"""Correct the component's own list; never replace it.
|
||||
|
||||
Assigning our entries wholesale dropped every file RetroDECK declares
|
||||
@@ -206,6 +206,9 @@ class Exporter(BaseExporter):
|
||||
for system in _systems_of(entry):
|
||||
key = (str(entry.get("filename", "")), system)
|
||||
seen_keys[key] = seen_keys.get(key, 0) + 1
|
||||
# A hash no revision shares is a revision the platform does not
|
||||
# know: appended, not counted corrected against entries kept as
|
||||
# they were (the 64DD IPL declared twice, both contradicted).
|
||||
for entry in entries:
|
||||
keys = _matching_keys(entry, by_key)
|
||||
other_revision = (
|
||||
@@ -213,18 +216,17 @@ class Exporter(BaseExporter):
|
||||
and seen_keys.get(keys[0], 0) > 1
|
||||
and not _md5_set(entry.get("md5")) & _md5_set(by_key[keys[0]].get("md5"))
|
||||
)
|
||||
if other_revision:
|
||||
merged.append(OrderedDict(entry))
|
||||
corrected.update(keys)
|
||||
continue
|
||||
if not keys:
|
||||
if other_revision or not keys:
|
||||
merged.append(OrderedDict(entry))
|
||||
continue
|
||||
declared = entry.get("system")
|
||||
combined = OrderedDict(entry)
|
||||
# Only what the format says it corrects: the maintainer's
|
||||
# description and search paths are theirs (neogeo.zip lost its
|
||||
# four roms directories to a path that does not exist).
|
||||
combined.update(
|
||||
(field, value) for field, value in by_key[keys[0]].items()
|
||||
if not (field == "system" and declared)
|
||||
if field in cls.carries() and not (field == "system" and declared)
|
||||
)
|
||||
merged.append(combined)
|
||||
corrected.update(keys)
|
||||
|
||||
Reference in new issue
Block a user