mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-12 13:03:54 -06:00
fix: refuse profile narrowings without cores
MiSTer and BizHawk declare cores: []. --region, --one-per-slot and --no-game-data read the profiles of the cores a platform runs, so their packs and manifests withdrew nothing under a name and README that said they had. generate_pack and verify now refuse the flags for a named platform and leave it out under --all.
This commit is contained in:
1 parent
13a10da993
commit
6bf62d5746
6 files changed
+123
-1
No files matched your search
@@ -1011,7 +1011,9 @@ platforms:
|
||||
# EmuHawk finds firmware by SHA1 against FirmwareDatabase.FirmwareRecords
|
||||
# and its cores are its own builds (CoreNames.cs): no libretro profile
|
||||
# describes what it reads, so the database alone decides, as MiSTer's
|
||||
# BiosDB does.
|
||||
# BiosDB does. emulators/bizhawk.yml also documents the options the scan
|
||||
# never takes, so it is not listed here, and --region, --one-per-slot
|
||||
# and --no-game-data are refused for this platform.
|
||||
cores: []
|
||||
target_scraper: null
|
||||
target_source: null
|
||||
|
||||
@@ -2761,6 +2761,29 @@ def preferred_profile(index: dict[str, set[str]], name: str) -> str | None:
|
||||
return name if name in claimants else sorted(claimants)[0]
|
||||
|
||||
|
||||
def profile_blind_platforms(
|
||||
platforms: list[str],
|
||||
platforms_dir: str,
|
||||
profiles: dict[str, dict],
|
||||
target_cores: dict[str, set[str] | None] | None = None,
|
||||
) -> list[str]:
|
||||
"""Platforms that run no core a profile describes.
|
||||
|
||||
Regions, search order and game data are read from the profiles of the
|
||||
cores a platform runs. MiSTer and BizHawk declare `cores: []`: a
|
||||
--region, --one-per-slot or --no-game-data pack of theirs withdrew
|
||||
nothing while its name and README said it had.
|
||||
"""
|
||||
return [
|
||||
name for name in platforms
|
||||
if not resolve_platform_cores(
|
||||
load_platform_config(name, platforms_dir),
|
||||
profiles,
|
||||
target_cores=(target_cores or {}).get(name),
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def resolve_platform_cores(
|
||||
config: dict,
|
||||
profiles: dict[str, dict],
|
||||
|
||||
@@ -75,6 +75,7 @@ from common import (
|
||||
load_database,
|
||||
load_emulator_profiles,
|
||||
load_platform_config,
|
||||
profile_blind_platforms,
|
||||
MANUFACTURER_PREFIXES,
|
||||
require_yaml,
|
||||
ProfileSelectionError,
|
||||
@@ -3074,6 +3075,42 @@ def _pack_label(source: str, required_only: bool) -> str:
|
||||
return f"[source={source}, required]" if required_only else f"[source={source}]"
|
||||
|
||||
|
||||
def _without_profile_blind(
|
||||
args: argparse.Namespace,
|
||||
platforms: list[str],
|
||||
emu_profiles: dict,
|
||||
target_cores_cache: dict[str, set[str] | None],
|
||||
) -> list[str]:
|
||||
"""Refuse a narrowing read from profiles on a platform that runs none.
|
||||
|
||||
Named, the platform is refused. Under --all it is left out with a
|
||||
notice, as an empty truth pack is under --all-variants.
|
||||
"""
|
||||
flags = [
|
||||
flag for flag, given in (
|
||||
("--region", getattr(args, "regions", None)),
|
||||
("--one-per-slot", getattr(args, "one_per_slot", False)),
|
||||
("--no-game-data", getattr(args, "no_game_data", False)),
|
||||
) if given
|
||||
]
|
||||
if not flags:
|
||||
return platforms
|
||||
blind = profile_blind_platforms(
|
||||
platforms, args.platforms_dir, emu_profiles,
|
||||
target_cores_cache if args.target else None,
|
||||
)
|
||||
for name in blind:
|
||||
message = (
|
||||
f"{name} runs no core a profile describes, and {', '.join(flags)} "
|
||||
"reads the profiles"
|
||||
)
|
||||
if not args.all:
|
||||
print(f"ERROR: {message}: drop {', '.join(flags)}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
print(f" {message}: left out")
|
||||
return [name for name in platforms if name not in blind]
|
||||
|
||||
|
||||
def _truth_layer_is_empty(
|
||||
platform: str, platforms_dir: str, emu_profiles: dict, target_cores: set[str] | None
|
||||
) -> bool:
|
||||
@@ -3785,6 +3822,9 @@ def _main(held: contextlib.ExitStack) -> None:
|
||||
platforms = _platforms_with_systems(
|
||||
args, platforms, system_filter, emu_profiles, target_cores_cache
|
||||
)
|
||||
platforms = _without_profile_blind(
|
||||
args, platforms, emu_profiles, target_cores_cache
|
||||
)
|
||||
|
||||
data_registry = load_data_dir_registry(args.platforms_dir)
|
||||
# The output directory is claimed before the data directory refresh: a
|
||||
|
||||
@@ -65,6 +65,7 @@ from common import (
|
||||
load_database,
|
||||
load_emulator_profiles,
|
||||
load_platform_config,
|
||||
profile_blind_platforms,
|
||||
resolve_system_arg,
|
||||
print_platform_listing,
|
||||
select_systems,
|
||||
@@ -3017,6 +3018,30 @@ def _main(held: contextlib.ExitStack) -> None:
|
||||
print(f"ERROR: {reason}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# generate_pack refuses these on a platform whose cores no profile
|
||||
# describes, and the report answers the same request the same way.
|
||||
flags = [
|
||||
flag for flag, given in (
|
||||
("--region", requested_regions),
|
||||
("--no-game-data", getattr(args, "no_game_data", False)),
|
||||
) if given
|
||||
]
|
||||
if flags:
|
||||
blind = profile_blind_platforms(
|
||||
platforms, args.platforms_dir, emu_profiles,
|
||||
target_cores_cache if args.target else None,
|
||||
)
|
||||
for name in blind:
|
||||
message = (
|
||||
f"{name} runs no core a profile describes, and "
|
||||
f"{', '.join(flags)} reads the profiles"
|
||||
)
|
||||
if not args.all:
|
||||
print(f"ERROR: {message}: drop {', '.join(flags)}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
print(f" {message}: left out")
|
||||
platforms = [name for name in platforms if name not in blind]
|
||||
|
||||
# Group identical platforms (same function as generate_pack)
|
||||
groups = group_identical_platforms(
|
||||
platforms, args.platforms_dir, target_cores_cache if args.target else None
|
||||
|
||||
@@ -6374,6 +6374,33 @@ struct BurnDriver BurnDrvneogeo = {
|
||||
[f for f in os.listdir(out) if f.endswith(".zip")] if os.path.isdir(out) else []
|
||||
)
|
||||
|
||||
def test_a_platform_without_cores_refuses_profile_narrowings(self):
|
||||
"""MiSTer and BizHawk declare cores: []. --region, --one-per-slot
|
||||
and --no-game-data read the profiles, so their packs withdrew
|
||||
nothing under a name and README that said otherwise."""
|
||||
import subprocess
|
||||
|
||||
repo = os.path.join(os.path.dirname(__file__), "..")
|
||||
out = os.path.join(self.root, "blind")
|
||||
runs = [
|
||||
["scripts/generate_pack.py", "--platform", "misterfpga", "--region", "us"],
|
||||
["scripts/generate_pack.py", "--platform", "misterfpga", "--one-per-slot"],
|
||||
["scripts/generate_pack.py", "--platform", "misterfpga", "--no-game-data"],
|
||||
["scripts/generate_pack.py", "--platform", "bizhawk", "--manifest",
|
||||
"--region", "us"],
|
||||
["scripts/verify.py", "--platform", "bizhawk", "--region", "us"],
|
||||
]
|
||||
for argv in runs:
|
||||
extra = ["--offline", "--output-dir", out] if "generate_pack" in argv[0] else []
|
||||
with self.subTest(argv=argv):
|
||||
proc = subprocess.run(
|
||||
[sys.executable, *argv, *extra],
|
||||
capture_output=True, text=True, cwd=repo, timeout=300,
|
||||
)
|
||||
self.assertEqual(proc.returncode, 1, proc.stdout + proc.stderr)
|
||||
self.assertIn("runs no core a profile describes", proc.stderr)
|
||||
self.assertFalse(os.listdir(out) if os.path.isdir(out) else [])
|
||||
|
||||
def test_a_full_pack_is_not_announced_as_narrowed(self):
|
||||
from generate_pack import _build_readme, _narrowings
|
||||
|
||||
|
||||
@@ -140,6 +140,11 @@ Three rules keep a filtered pack usable:
|
||||
- **Untagged files always survive.** Most BIOS are not regional and carry no
|
||||
`region:` at all.
|
||||
|
||||
Regions, the search order `--one-per-slot` reads and the game data
|
||||
`--no-game-data` cuts all come from the profiles of the cores a platform runs.
|
||||
MiSTer and BizHawk declare no cores, their own databases decide, so the three
|
||||
flags are refused for them. Under `--all` they are left out with a notice.
|
||||
|
||||
What this does and does not do: it shrinks the pack. It does not change how cores
|
||||
pick a BIOS. Most cores already select per region from fixed filename lists driven
|
||||
by the game's region (PicoDrive in `libretro.c`, Genesis Plus GX in `loadrom.c`),
|
||||
|
||||
Reference in new issue
Block a user