fix: compute verify's gap report once

This commit is contained in:
Abdessamad Derraz committed 2026-10-18 16:06:35 +02:00
1 parent 32d415eda5
commit 8001b9d86d
3 files changed
+48 -7

No files matched your search

+11 -5
View File
@@ -155,6 +155,7 @@ def hidden_extras(
target_cores: set[str] | None = None,
region_drops: set[str] | None = None,
placed: set[str] | None = None,
report: list[dict] | None = None,
) -> dict[tuple[str, str, str], str]:
"""Report entries the builder holds and still leaves out, with the reason.
@@ -189,7 +190,7 @@ def hidden_extras(
hidden: dict[tuple[str, str, str], str] = {}
for fe in _collect_emulator_extras(
config, emulators_dir, db, set(shipped), base_dest, profiles,
target_cores=target_cores,
target_cores=target_cores, undeclared=report,
):
dest = sanitize_pack_path(fe.get("destination", fe.get("name", "")))
if not dest or (region_drops and dest in region_drops):
@@ -603,9 +604,13 @@ def _collect_emulator_extras(
unplaceable: list[dict] | None = None,
baseline_claims: dict[str, dict] | None = None,
absent: list[dict] | None = None,
undeclared: list[dict] | None = None,
) -> list[dict]:
"""Collect core requirement files from emulator profiles not in the platform pack.
``undeclared`` is the gap report when the caller already holds it,
computed with the same arguments (verify's own pass).
``absent`` receives, placed like the others, the entries the collection
does not hold: the region pass groups them as it groups the platform's
own missing files, so the report withdraws the ones a request excludes.
@@ -650,10 +655,11 @@ def _collect_emulator_extras(
# under an alias still get packed at the emulator's expected path.
yaml_names = platform_declarations(config, db, enrich=False)
undeclared = find_undeclared_files(
config, emulators_dir, db, emu_profiles, target_cores=target_cores,
include_all=include_all, declared_names=yaml_names,
)
if undeclared is None:
undeclared = find_undeclared_files(
config, emulators_dir, db, emu_profiles, target_cores=target_cores,
include_all=include_all, declared_names=yaml_names,
)
# A destination two cores claim goes to the one that names its content:
# hypseus-singe asks for gamecontrollerdb.txt by name alone and took the
# BIOS root before Solarus, which pins its own by sha1. Profile order
+8 -2
View File
@@ -787,10 +787,13 @@ def _mark_hidden(
shipped: dict[str, str],
target_cores: set[str] | None,
region_drops: set[str] | None = None,
report: list[dict] | None = None,
) -> set[str]:
"""What the builder holds but cannot place beside the files it packed.
Returns the full destinations the builder fills with a core's file.
``report`` is the gap report the caller already computed with the
builder's arguments; without it the builder's pass computes its own.
"""
from packextras import hidden_extras
@@ -799,7 +802,7 @@ def _mark_hidden(
config, emulators_dir, db,
emu_profiles if emu_profiles is not None
else load_emulator_profiles(emulators_dir),
shipped, target_cores, region_drops, placed,
shipped, target_cores, region_drops, placed, report,
)
for u in undeclared:
reason = hidden.get(
@@ -1128,6 +1131,9 @@ def verify_platform(
target_cores=target_cores,
declared_names=platform_declarations(config, db, enrich=False),
)
# The builder's own pass reads the same report: computed once here and
# handed over as it stands now, before the markings below.
report_for_builder = [dict(u) for u in undeclared]
if region_drops:
undeclared = [
u
@@ -1140,7 +1146,7 @@ def verify_platform(
_mark_unplaced(config, undeclared, profiles)
placed = _mark_hidden(
config, undeclared, emulators_dir, db, emu_profiles, shipped, target_cores,
region_drops,
region_drops, report_for_builder,
)
if not reads_file_contents(mode):
# An existence frontend is satisfied by any file at the path, and the
+29
View File
@@ -110,5 +110,34 @@ class TheReportSaysSo(unittest.TestCase):
self.assertIs(entry.get("in_pack"), False)
class TheGapReportIsComputedOnce(unittest.TestCase):
"""verify_platform ran find_undeclared_files twice with the same
arguments, once itself and once through hidden_extras: every
resolution twice, 8% of verify --all."""
def test_one_call_per_platform(self):
if not (REPO_ROOT / "database.json").exists():
self.skipTest("database.json is not built")
from unittest import mock
previous = os.getcwd()
os.chdir(REPO_ROOT)
try:
import verify
from common import load_database, load_emulator_profiles, load_platform_config
db = load_database("database.json")
profiles = load_emulator_profiles("emulators")
config = load_platform_config("emudeck", "platforms")
with mock.patch.object(
verify, "find_undeclared_files", wraps=verify.find_undeclared_files
) as counted:
verify.verify_platform(config, db, "emulators", profiles)
finally:
os.chdir(previous)
self.assertEqual(counted.call_count, 1)
if __name__ == "__main__":
unittest.main()