fix: resolve declarations through one function

verify resolved platform entries with common.resolve_local_file and put
the slot override first, and the region pass added a destination hint.
packresolve.resolve_declaration now serves the builder, the manifest,
verify and the region pass: release assets cached for a file absent from
bios/ count as shipped in all four, and a release asset keeps its answer
over a slot override.
This commit is contained in:
Abdessamad Derraz committed 2026-10-21 09:56:07 +02:00
1 parent 3545c1b333
commit 2af9509ef4
7 files changed
+108 -37

No files matched your search

+8 -9
View File
@@ -936,19 +936,16 @@ def generate_pack(
total_files += 1
continue
local_path, status = resolve_file(
local_path, status = resolve_declaration(
file_entry,
db,
bios_dir,
zip_contents,
data_dir_registry=data_registry,
data_registry,
slot_overrides.get(full_dest),
offline=offline,
)
local_path, status = slots.apply_override(
slot_overrides.get(full_dest), local_path, status
)
if status == "external":
file_ext = os.path.splitext(file_entry["name"])[1] or ""
with tempfile.NamedTemporaryFile(
@@ -4243,14 +4240,15 @@ def generate_manifest(
file_entry: dict, sys_id: str, dest: str, override: str | None
) -> tuple[str | None, str]:
"""The file served once the slot is settled, or None and why not."""
local_path, status = slots.apply_override(override, *resolve_file(
local_path, status = resolve_declaration(
file_entry,
db,
bios_dir,
zip_contents,
data_dir_registry=data_registry,
data_registry,
override,
offline=offline,
))
)
if status == "not_found" and not reads_file_contents(verification_mode):
found = agnostic_substitute(file_entry, sys_id, db, manifest_profiles)
if found:
@@ -4914,6 +4912,7 @@ from packresolve import ( # noqa: E402,F401
parse_hash_input,
parse_hash_file,
lookup_hashes,
resolve_declaration,
resolve_file,
)
+7 -3
View File
@@ -1229,14 +1229,18 @@ def _kept(entries: list[dict], required_only: bool) -> list[dict]:
return [e for e in entries if e.get("required") is not False]
def _ships(config: dict, file_entry: dict, db: dict, dest: str) -> bool:
def _ships(config: dict, file_entry: dict, db: dict) -> bool:
"""Whether the builder packs this declaration: resolved, and not refused
by a hash frontend. A dump whose md5 Recalbox would reject is left out
of the pack, so it cannot win a regional slot over a file that ships.
"""
from packresolve import resolve_declaration
from validation import baseline_verdict
path, status = resolve_local_file(file_entry, db, dest_hint=dest)
# The builder's resolution: no destination hint, release assets included.
path, status = resolve_declaration(
file_entry, db, "bios", None, None, None, offline=True,
)
if not path:
return False
return baseline_verdict(
@@ -1288,7 +1292,7 @@ def platform_region_groups(
if dest:
members.append((dest, file_entry.get("name", "")))
if held_out is not None and db is not None and _ships(
config, file_entry, db, dest
config, file_entry, db
):
held_out.add(dest)
+40
View File
@@ -286,6 +286,46 @@ def resolve_file(
return None, "not_found"
def apply_override(
override: str | None, local_path: str | None, status: str
) -> tuple[str | None, str]:
"""The file a pack serves at a destination once its slot is settled.
An entry the platform stores outside the collection, or a release asset
fetched for its declared hash, keeps its own answer.
"""
if override and status not in ("external", "release_asset"):
return override, "slot_arbitrated"
return local_path, status
def resolve_declaration(
file_entry: dict,
db: dict,
bios_dir: str,
zip_contents: dict | None,
data_dir_registry: dict | None,
override: str | None,
*,
offline: bool | None = None,
) -> tuple[str | None, str]:
"""The file a platform pack serves for one of the platform's declarations.
Read by the builder, the install manifest, verify and the region pass.
verify resolved with common.resolve_local_file and put the slot override
first: without the release-asset tier a gitignored file absent from bios/
read as missing there while the pack shipped the cached asset.
"""
return apply_override(override, *resolve_file(
file_entry,
db,
bios_dir,
zip_contents,
data_dir_registry=data_dir_registry,
offline=offline,
))
def preferred_entries(
pack_systems: dict,
db: dict,
-14
View File
@@ -578,20 +578,6 @@ def slot_choices(
return choices
def apply_override(
override: str | None, local_path: str | None, status: str
) -> tuple[str | None, str]:
"""The file a pack serves at a destination once its slot is settled.
An entry the platform stores outside the collection, or a release asset
fetched for its declared hash, keeps its own answer. The builder and the
install manifest both read this.
"""
if override and status not in ("external", "release_asset"):
return override, "slot_arbitrated"
return local_path, status
def _strongest(claims: list[Claim]) -> Claim:
"""The profile claim with the strongest proof, the first emulator breaking ties.
+8 -6
View File
@@ -1047,18 +1047,20 @@ def _resolve_for_platform(
) -> tuple[str | None, str]:
"""Resolve one platform entry the way the pack builder does.
A slot the arbitration decided wins over the resolver, and a frontend that
The builder's own resolution (packresolve.resolve_declaration), read from
disk and the large-file cache: verify never downloads. A frontend that
never reads the bytes takes the filename-free core's own image.
"""
from packresolve import resolve_declaration
override = slot_overrides.get(
sanitize_pack_path(file_entry.get("destination", file_entry.get("name", "")))
)
if override:
return override, "slot_arbitrated"
local_path, status = resolve_local_file(
file_entry, db, zip_contents, data_dir_registry=data_dir_registry
local_path, status = resolve_declaration(
file_entry, db, DEFAULT_BIOS_DIR, zip_contents, data_dir_registry,
override, offline=True,
)
if local_path is None and not reads_file_contents(mode):
if status == "not_found" and not reads_file_contents(mode):
found = agnostic_substitute(file_entry, sys_id, db, platform_profiles)
if found:
return found[0], "agnostic_fallback"