fix: scope gap report entries by platform

cross_reference --platform read bundled from the profile alone and never
read unread_on. It now calls validation.installed_with_emulator and
unread_on with the platform key, as verify does, and a file installed
with its emulator is reported as bundled whether held or not.
This commit is contained in:
Abdessamad Derraz committed 2026-10-21 09:49:49 +02:00
1 parent 0242dc77ee
commit 3545c1b333
2 files changed
+83 -13

No files matched your search

+28 -13
View File
@@ -45,7 +45,13 @@ from common import (
select_emulator_profiles,
)
from hashing import parse_hash_list
from validation import case_folded_slots, declaration_settles, outside_gap_scope
from validation import (
case_folded_slots,
declaration_settles,
installed_with_emulator,
outside_gap_scope,
unread_on,
)
yaml = require_yaml()
@@ -606,9 +612,15 @@ def _cross_reference_profile(
report: dict,
index: dict,
standalone_cores: set[str] | None = None,
platform: str = "",
) -> None:
"""Compare one emulator profile against what the platforms declare.
*platform* is the platform key under --platform, empty for the whole
tree. It decides, through the functions verify reads, which entries the
platform's launcher never opens and which ones its emulator package
already installs.
Split out of cross_reference, where it was a 200-line loop body that
carried the whole function's branching: every file is resolved by name,
by path, by hash and by archive membership before it can be called a
@@ -667,7 +679,7 @@ def _cross_reference_profile(
if len(layouts) > 1:
# One file read at one path by both builds counts once.
seen_key = (effective_path.casefold(), seen_key)
if not fname or seen_key in seen_files:
if not fname or seen_key in seen_files or unread_on(f, platform):
continue
# Collect unsourceable files separately (documented, not a gap)
@@ -760,7 +772,7 @@ def _cross_reference_profile(
"name": fname,
"path": effective_path,
"required": f.get("required", False),
"bundled": bool(f.get("bundled")),
"bundled": installed_with_emulator(f, platform),
"note": f.get("note", ""),
"source_ref": f.get("source_ref", ""),
"in_platform": False,
@@ -800,6 +812,7 @@ def cross_reference(
all_declared: dict[str, list[tuple[int | None, str]]] | None = None,
standalone_cores: set[str] | None = None,
folded_slots: frozenset[str] = frozenset(),
platform: str = "",
) -> dict:
"""Compare emulator profiles against platform declarations.
@@ -841,7 +854,8 @@ def cross_reference(
}
for emu_name, profile in profiles.items():
_cross_reference_profile(
emu_name, profile, declared, report, index, standalone_cores
emu_name, profile, declared, report, index, standalone_cores,
platform,
)
return report
@@ -872,14 +886,14 @@ def print_report(
if gaps == 0 and not show_clean:
continue
# Counted once, for the heading and the total alike: a file bundled
# with its emulator is not one to source.
emulator_bundled = sum(
1 for g in data["gap_details"]
if g.get("bundled") and g.get("source") == "missing"
)
# Counted once, for the heading and the total alike: a file installed
# with its emulator is neither one to source nor one the pack brings,
# held or not (validation.deliverable leaves it out of every pack).
bundled_gaps = [g for g in data["gap_details"] if g.get("bundled")]
emulator_bundled = len(bundled_gaps)
counts = {key: data.get(f"gap_{key}", 0) for key in totals}
counts["missing"] -= emulator_bundled
for g in bundled_gaps:
counts[g.get("source", "missing")] -= 1
counts["bundled"] = emulator_bundled
parts = [f"{count} {key}" for key, count in counts.items() if count]
status = ", ".join(parts) if parts else "OK"
@@ -896,7 +910,7 @@ def print_report(
for g in data["gap_details"]:
req = "*" if g["required"] else " "
src = g.get("source", "missing").upper()
if g.get("bundled") and g.get("source") == "missing":
if g.get("bundled"):
src = "BUNDLED"
# One line per file: a note spanning lines fell to column 0
# between entries and read as an emulator heading.
@@ -920,7 +934,7 @@ def print_report(
f"large_file: {totals['large_file']})")
print(f" {totals['missing']} missing (need to be sourced)")
if bundled:
print(f" {bundled} bundled with their emulator, not collected")
print(f" {bundled} bundled with their emulator, not packed")
def main() -> None:
@@ -1023,6 +1037,7 @@ def main() -> None:
all_declared=declared_names(args.platforms_dir, selected, db),
standalone_cores=standalone_cores,
folded_slots=folded_declared_slots(args.platforms_dir, selected, db),
platform=config.get("_key", args.platform) if args.platform else "",
)
if args.json: