fix: keep the claims of every core on a file

The first profile reading a requirement hosts the others' claims,
and two ways of dropping the host dropped them too. DraStic brings its
own usrcheat.dat, and DSPerate, which reads the same file, lost it
wherever DraStic runs. A missing file was recorded for its first
reader alone: NAPALM.GRP named Raze, Data.rsdk Sonic Mania. A list
built for a board without that reader carried what the full list
left out, and install.py --target disagreed with the builder on
ROCKNIX, KNULLI, Batocera and RetroPie boards.
This commit is contained in:
Abdessamad Derraz committed 2026-11-10 02:08:11 +01:00
1 parent 2a6b8b5943
commit 3d2629f652
4 files changed
+89 -8

No files matched your search

+10 -3
View File
@@ -4694,11 +4694,18 @@ def _record_absent(
):
continue
full_dest = extra_full_destination(fe, extras_pfx)
if not full_dest:
continue
if full_dest in seen_destinations or full_dest in omitted_by_destination:
if not full_dest or full_dest in seen_destinations:
continue
source_emu = fe.get("source_profile") or fe.get("source_emulator", "")
held = omitted_by_destination.get(full_dest)
if held is not None:
# Another core reads the same missing file there (Raze and
# EDuke32 both open NAPALM.GRP): one omission names them all.
claimed = held.get("cores")
if (held.get("reason") == "not_found" and claimed and source_emu
and source_emu not in claimed):
held["cores"] = sorted([*claimed, source_emu])
continue
systems = _extra_system_ids(fe)
record_omission(
full_dest, fe, systems[0] if systems else "", "not_found",
+7 -4
View File
@@ -1263,11 +1263,14 @@ def _collect_emulator_extras(
placements = placement.places(u, dest)
save_root = u.get("root") == "save"
if not u["in_repo"]:
# Each core reading it is named on the omission: a list built
# without the first reader still has to say the file is missing.
for placed in placements:
missing = _report_extra(u, name, placed[0])
if save_root:
_save_fields(missing, placed[1], placement)
absent.append(missing)
for claim in (u, *u.get("other_claims", [])):
missing = _report_extra(claim, name, placed[0])
if save_root:
_save_fields(missing, placed[1], placement)
absent.append(missing)
continue
if not placements:
if unplaceable is not None:
+30 -1
View File
@@ -824,7 +824,36 @@ def find_undeclared_files(
for entry in sorted(archive_entries.values(), key=lambda e: e["name"]):
undeclared.append(entry)
return _settle_core_sets(undeclared, set_records, settled, profiles)
return _split_bundled_claims(
_settle_core_sets(undeclared, set_records, settled, profiles)
)
def _split_bundled_claims(undeclared: list[dict]) -> list[dict]:
"""A file one emulator installs itself, another reads from the pack.
The first profile reading a requirement hosts the claims of the others,
and a host installed with its emulator is left out of the pack with all
of them: DraStic brings its own usrcheat.dat, and ROCKNIX's DSPerate,
which reads the same file, lost it wherever DraStic runs too. Built for
a board without DraStic, the pack carried it.
"""
out: list[dict] = []
for entry in undeclared:
claims = entry.get("other_claims") or []
rest = [c for c in claims if not c.get("bundled")]
if not entry.get("bundled") or not rest:
out.append(entry)
continue
own = [c for c in claims if c.get("bundled")]
kept = {k: v for k, v in entry.items() if k != "other_claims"}
if own:
kept["other_claims"] = own
promoted = dict(rest[0])
if rest[1:]:
promoted["other_claims"] = rest[1:]
out += [kept, promoted]
return out
def _settle_core_sets(