mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-23 20:29:06 -05:00
fix: count an uncached release asset as fetched
verify resolved offline, so a release asset absent from bios/ and the cache read as missing while an online build fetched and packed it. verify now reads the database record of the registered path and counts such a declaration present, listed as fetched at build time. --offline keeps the old count, and the offline pipeline passes it to its verify step.
This commit is contained in:
1 parent
b4e5e42c97
commit
9a0501d9d3
6 files changed
+251
-4
No files matched your search
+50
-3
@@ -149,6 +149,11 @@ class Status:
|
||||
MISSING = "missing"
|
||||
|
||||
|
||||
# A declaration whose file is a release asset the cache does not hold yet:
|
||||
# an online build fetches it, verify reads the database record instead.
|
||||
RELEASE_ASSET_PENDING = "release_asset_pending"
|
||||
|
||||
|
||||
class Severity:
|
||||
CRITICAL = "critical" # required file missing or bad hash (Recalbox RED)
|
||||
WARNING = "warning" # optional missing or hash mismatch (Recalbox YELLOW)
|
||||
@@ -1075,7 +1080,7 @@ def _resolve_for_platform(
|
||||
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
|
||||
from packresolve import pending_release_asset, resolve_declaration, run_is_offline
|
||||
|
||||
override = slot_overrides.get(
|
||||
sanitize_pack_path(file_entry.get("destination", file_entry.get("name", "")))
|
||||
@@ -1084,6 +1089,12 @@ def _resolve_for_platform(
|
||||
file_entry, db, DEFAULT_BIOS_DIR, zip_contents, data_dir_registry,
|
||||
override, offline=True,
|
||||
)
|
||||
if status in ("not_found", "hash_mismatch") and not run_is_offline():
|
||||
# Not in the cache, and the release holds a copy that answers the
|
||||
# declaration: an online build fetches and packs it (resolve_file).
|
||||
asset = pending_release_asset(file_entry, db)
|
||||
if asset:
|
||||
return asset, RELEASE_ASSET_PENDING
|
||||
if status == "not_found" and not reads_file_contents(mode):
|
||||
found = agnostic_substitute(file_entry, sys_id, db, platform_profiles)
|
||||
if found:
|
||||
@@ -1234,7 +1245,23 @@ def verify_platform(
|
||||
file_entry.get("destination", file_entry.get("name", ""))
|
||||
)
|
||||
stored = _storage_verdict(file_entry, emulator_pack=False)
|
||||
if stored is not None:
|
||||
if resolve_status == RELEASE_ASSET_PENDING:
|
||||
# Counted as an online build counts it, which fetches the
|
||||
# asset. Under --offline the builder cannot, and neither
|
||||
# does this report (_resolve_for_platform).
|
||||
result = {
|
||||
"name": file_entry.get("name", ""),
|
||||
"required": file_entry.get("required", True),
|
||||
"status": Status.OK,
|
||||
"release_asset": local_path,
|
||||
"reason": "release asset, fetched when the pack is built",
|
||||
}
|
||||
packed_order.append((
|
||||
sys_id, f"{base_dest}/{destination}" if base_dest else destination, None,
|
||||
))
|
||||
shipped_keys.add(_dest_key(file_entry, sys_id))
|
||||
local_path = None
|
||||
elif stored is not None:
|
||||
result = stored
|
||||
local_path = None
|
||||
# The builder keeps the slot: instructions for a user_provided
|
||||
@@ -1744,6 +1771,12 @@ def print_platform_result(
|
||||
if missing:
|
||||
parts.append(f"{missing} missing")
|
||||
print(f"{label}: {', '.join(parts)} [{mode}]")
|
||||
fetched = sorted({d["name"] for d in result["details"] if d.get("release_asset")})
|
||||
if fetched:
|
||||
# Counted present: an online build downloads them. --offline counts
|
||||
# them missing, as an offline build leaves them out.
|
||||
shown = ", ".join(fetched[:10]) + (f" (+{len(fetched) - 10})" if len(fetched) > 10 else "")
|
||||
print(f" Release assets fetched when the pack is built ({len(fetched)}): {shown}")
|
||||
fallbacks = result.get("region_fallbacks") or []
|
||||
if fallbacks:
|
||||
from packreadme import _group_label
|
||||
@@ -2440,6 +2473,7 @@ def _refuse_listing_narrowings(
|
||||
("--strict", args.strict),
|
||||
("--verbose", args.verbose),
|
||||
("--destinations", args.destinations),
|
||||
("--offline", args.offline),
|
||||
):
|
||||
if on:
|
||||
parser.error(f"{flag} is incompatible with {listing}")
|
||||
@@ -2457,6 +2491,8 @@ def _refuse_mode_flags(args: argparse.Namespace, parser: argparse.ArgumentParser
|
||||
"--target is incompatible with --emulator and --system"),
|
||||
(args.destinations and not (args.platform or args.all),
|
||||
"--destinations requires --platform or --all"),
|
||||
(args.offline and not (args.platform or args.all),
|
||||
"--offline requires --platform or --all"),
|
||||
(args.destinations and getattr(args, "region", None),
|
||||
"--destinations describes the full pack and is incompatible with --region"),
|
||||
):
|
||||
@@ -2536,6 +2572,11 @@ def _main(held: contextlib.ExitStack) -> None:
|
||||
help="Show emulator ground truth details",
|
||||
)
|
||||
parser.add_argument("--json", action="store_true", help="JSON output")
|
||||
parser.add_argument(
|
||||
"--offline", action="store_true",
|
||||
help="Report as an offline build packs: a release asset the cache "
|
||||
"lacks is missing. Without it, it counts as fetched at build time",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--destinations", metavar="FILE",
|
||||
help="With --platform or --all, also write the paths each pack holds "
|
||||
@@ -2552,6 +2593,10 @@ def _main(held: contextlib.ExitStack) -> None:
|
||||
work_from_repo_root(args, parser, ["db", "platforms_dir", "emulators_dir"])
|
||||
if args.platform:
|
||||
require_platform(args.platform, args.platforms_dir)
|
||||
if args.offline:
|
||||
import packresolve
|
||||
|
||||
packresolve.set_offline(True)
|
||||
|
||||
requested_regions: list[str] = []
|
||||
if getattr(args, "region", None):
|
||||
@@ -2696,7 +2741,9 @@ def _json_details(details: list[dict], verbose: bool) -> list[dict]:
|
||||
used to be accepted beside --json and dropped, the output byte for byte
|
||||
the same, so a script asking for the passing entries got nothing.
|
||||
"""
|
||||
return list(details) if verbose else [d for d in details if d["status"] != Status.OK]
|
||||
return list(details) if verbose else [
|
||||
d for d in details if d["status"] != Status.OK or d.get("release_asset")
|
||||
]
|
||||
|
||||
|
||||
def _exit_if_strict(strict: bool, results: list[dict]) -> None:
|
||||
|
||||
Reference in new issue
Block a user