fix: suggest the target when no platform has it

verify --all --target swich ended on 'no platform has it' after seventeen INFO lines, two of which held the suggestion. The refusal now names the closest targets across every platform with the platforms that have them, and the per-platform lines print only when some platform keeps the target.
This commit is contained in:
Abdessamad Derraz committed 2026-11-05 19:21:23 +01:00
1 parent 9ae3919d34
commit 4b54b82966
2 files changed
+48 -3

No files matched your search

+32 -3
View File
@@ -3250,26 +3250,55 @@ def build_target_cores_cache(
"""
cache: dict[str, set[str] | None] = {}
skip: list[str] = []
notes: list[str] = []
for p in platforms:
try:
cache[p] = load_target_config(p, target, platforms_dir)
except FileNotFoundError:
if not is_all:
raise
print(f"INFO: Skipping {p}: no hardware targets")
notes.append(f"INFO: Skipping {p}: no hardware targets")
skip.append(p)
except ValueError as e:
if is_all:
print(f"INFO: Skipping {p}: {e}")
notes.append(f"INFO: Skipping {p}: {e}")
skip.append(p)
else:
raise
kept = [p for p in platforms if p not in skip]
if is_all and platforms and not kept:
raise ValueError(f"unknown target '{target}': no platform has it")
# The seventeen per-platform lines buried the one suggestion that
# mattered: the refusal names the closest target across them all.
raise ValueError(_unknown_target_message(target, platforms, platforms_dir))
for note in notes:
print(note)
return cache, kept
def _unknown_target_message(target: str, platforms: list[str], platforms_dir: str) -> str:
"""A target no platform has, with the closest names any of them knows."""
import difflib # noqa: PLC0415
targets_dir = os.path.join(platforms_dir, "targets")
owners: dict[str, list[str]] = {}
for platform in platforms:
target_file = os.path.join(targets_dir, f"{platform}.yml")
if not os.path.exists(target_file):
continue
with open(target_file) as f:
targets = (yaml_load(f) or {}).get("targets", {})
overrides = _target_overrides(platform, targets_dir)
for name in _target_alias_index(targets, overrides):
owners.setdefault(name, []).append(platform)
message = f"unknown target '{target}': no platform has it."
close = difflib.get_close_matches(target, sorted(owners), n=3, cutoff=0.6)
if close:
named = ", ".join(f"{n} ({', '.join(sorted(owners[n]))})" for n in close)
return f"{message} Did you mean: {named}?"
return (f"{message} python scripts/verify.py --platform <name> --list-targets "
"lists the targets of one platform.")
# Re-exported so the existing call sites keep working while the
# modules above become the place to import from.
from safeparse import ( # noqa: E402,F401
+16
View File
@@ -85,6 +85,22 @@ class AMistypedTargetGetsTheClosestName(unittest.TestCase):
class AMistypedTargetAcrossAllPlatforms(unittest.TestCase):
"""`verify --all --target swich` ended on "no platform has it" after 17
INFO lines, two of which held the suggestion."""
def test_the_refusal_suggests_and_names_the_platforms(self):
platforms = common.list_registered_platforms(str(REPO_ROOT / "platforms"))
out = io.StringIO()
with contextlib.redirect_stdout(out), self.assertRaises(ValueError) as caught:
common.build_target_cores_cache(
platforms, "swich", str(REPO_ROOT / "platforms"), is_all=True
)
self.assertIn("Did you mean: switch (", str(caught.exception))
self.assertIn("retroarch", str(caught.exception))
self.assertEqual(out.getvalue(), "")
class AMistypedDataKeyGetsTheClosestName(unittest.TestCase):
"""`--key dolphin-sis` printed all 27 keys on one line."""