fix: count one export line per addition path

This commit is contained in:
Abdessamad Derraz committed 2026-11-06 14:55:23 +01:00
1 parent 651c64c763
commit 144cd46df1
4 files changed
+113 -14

No files matched your search

+21 -8
View File
@@ -221,12 +221,19 @@ class Exporter(BaseExporter):
ours = str(entry.get("path") or entry.get("name", "")).split("/")[:-1]
return not {d.casefold() for d in theirs} & {d.casefold() for d in ours}
def _bios_element(self, fe: NativeFile, native_id: str) -> str:
def _bios_element(
self, fe: NativeFile, native_id: str, also: tuple[NativeFile, ...] = ()
) -> str:
"""``also`` are further additions at fe's path: Bios.cpp reads one
element per path, and its md5 and core lists take every one of them."""
group = (fe, *also)
md5 = dict.fromkeys(h for f in group for h in f.hashes("md5"))
cores = dict.fromkeys(c for f in group for c in f.cores())
attrs = [f"path={quoteattr(self._path(fe))}"]
attrs.append(f'md5={quoteattr(",".join(fe.hashes("md5")))}')
attrs.append(f'core={quoteattr(",".join(fe.cores()))}')
attrs.append(f'md5={quoteattr(",".join(md5))}')
attrs.append(f'core={quoteattr(",".join(cores))}')
if not self.required_value(fe):
if not any(self.required_value(f) for f in group):
attrs.append('mandatory="false"')
elif fe.native("mandatory_declared", None) is True:
attrs.append('mandatory="true"')
@@ -343,11 +350,17 @@ class Exporter(BaseExporter):
}
ours: dict[str, tuple[NativeSystem, dict[str, tuple[NativeFile, str]]]] = {}
for system in systems.values():
writable = [fe for fe in system.files if self.writable(fe)]
if writable:
# Two additions at one path (two cores, two dumps) are one
# element: keyed by path, the second replaced the first and its
# md5 left the file while both were counted added.
at_path: dict[str, list[NativeFile]] = {}
for fe in system.files:
if self.writable(fe):
at_path.setdefault(self._path(fe), []).append(fe)
if at_path:
ours[system.native_id] = (system, {
self._path(fe): (fe, self._bios_element(fe, system.native_id))
for fe in writable
path: (group[0], self._bios_element(group[0], system.native_id, tuple(group[1:])))
for path, group in at_path.items()
})
def element(attrs: dict[str, str]) -> str:
+15 -4
View File
@@ -215,6 +215,7 @@ class Exporter(BaseExporter):
ours: list[OrderedDict],
additions: list[OrderedDict] | None = None,
appended: set[tuple[str, str]] | None = None,
held_back: list[int] | None = None,
) -> list[OrderedDict]:
"""Correct the component's own list, never replace it.
@@ -301,13 +302,19 @@ class Exporter(BaseExporter):
for e in merged
for system in (_systems_of(e) or [""])
}
for entry in additions or []:
for index, entry in enumerate(additions or []):
key = (str(entry.get("filename", "")), str(entry.get("system", "")), _paths_key(entry))
if key[0] and key not in held:
held.add(key)
merged.append(entry)
elif held_back is not None:
held_back.append(index)
return merged
def lands(self, fe: NativeFile) -> bool:
"""An addition the list already held is not written a second time."""
return self.writable(fe) and id(fe) not in getattr(self, "_held_back", set())
def render(
self,
systems: dict[str, NativeSystem],
@@ -317,6 +324,7 @@ class Exporter(BaseExporter):
) -> dict[str, str]:
self._place_additions(systems)
self._appended: set[int] = set()
self._held_back: set[int] = set()
grouped = self._by_component(systems)
produced: dict[str, str] = {}
@@ -331,25 +339,28 @@ class Exporter(BaseExporter):
continue
entries = [self._entry(fe) for fe in files if fe.platform is not None]
additions = [self._entry(fe) for fe in files if fe.platform is None]
added = [fe for fe in files if fe.platform is None]
additions = [self._entry(fe) for fe in added]
appended: set[tuple[str, str]] = set()
held_back: list[int] = []
for component_value in manifest.values():
if not isinstance(component_value, dict):
continue
holder = self._bios_holder(component_value)
if holder is None:
component_value["bios"] = self._merge(
None, entries, additions, appended
None, entries, additions, appended, held_back
)
else:
container, key = holder
written = container.get(key)
merged = self._merge(written, entries, additions, appended)
merged = self._merge(written, entries, additions, appended, held_back)
# A single object stays one while nothing is added to it.
container[key] = (
merged[0] if isinstance(written, dict) and len(merged) == 1 else merged
)
break
self._held_back.update(id(added[index]) for index in held_back)
# A declared entry whose revision the platform does not hold is
# written beside theirs: a new line, not a corrected value.
self._appended.update(
+13 -2
View File
@@ -175,6 +175,9 @@ class Exporter(BaseExporter):
ours: dict[str, dict[str, str]] = {}
added: dict[str, set[str]] = {}
# A rom name is one line: an addition whose name an earlier entry
# took is not written, and was counted added.
self._shadowed: set[int] = set()
for system, files in self.exportable(systems):
rendered: dict[str, str] = {}
for fe in files:
@@ -194,7 +197,11 @@ class Exporter(BaseExporter):
sha1 = fe.record_hash("sha1")
if sha1:
parts.append(f"sha1 {sha1}")
rendered.setdefault(name, f"\trom ( {' '.join(parts)} )")
if name in rendered:
if fe.platform is None:
self._shadowed.add(id(fe))
continue
rendered[name] = f"\trom ( {' '.join(parts)} )"
if fe.platform is None:
added.setdefault(system.native_id, set()).add(name)
if rendered:
@@ -241,7 +248,11 @@ class Exporter(BaseExporter):
return {self.native_filename(): "\n".join(lines)}
def lands(self, fe: NativeFile) -> bool:
return self.writable(fe) and id(fe) not in getattr(self, "_untitled", set())
return (
self.writable(fe)
and id(fe) not in getattr(self, "_untitled", set())
and id(fe) not in getattr(self, "_shadowed", set())
)
def validate(
self,