mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-11 05:53:23 -05:00
fix: publish target lists as the builder resolves them
This commit is contained in:
1 parent
5691e809c7
commit
97f741bf0f
5 files changed
+103
-14
No files matched your search
+16
-11
@@ -275,19 +275,24 @@ def load_target_config(
|
||||
raise ValueError(msg)
|
||||
|
||||
cores = set(str(c) for c in targets[canonical].get("cores", []))
|
||||
return apply_target_overrides(cores, overrides, canonical)
|
||||
|
||||
default_ovr = overrides.get("_default", {})
|
||||
ovr = overrides.get(canonical, {})
|
||||
for c in default_ovr.get("add_cores", []):
|
||||
cores.add(str(c))
|
||||
for c in default_ovr.get("remove_cores", []):
|
||||
cores.discard(str(c))
|
||||
for c in ovr.get("add_cores", []):
|
||||
cores.add(str(c))
|
||||
for c in ovr.get("remove_cores", []):
|
||||
cores.discard(str(c))
|
||||
|
||||
return cores
|
||||
def apply_target_overrides(
|
||||
cores: set[str], overrides: dict, target: str
|
||||
) -> set[str]:
|
||||
"""Cores of one target once the platform's overrides are applied.
|
||||
|
||||
``_default`` applies to every target of the platform, then the target's
|
||||
own entry: a name the scraper reads as a core on every board (a machine
|
||||
variant, a launcher) is written once instead of once per board.
|
||||
"""
|
||||
result = set(cores)
|
||||
for scope in ("_default", target):
|
||||
entry = overrides.get(scope) or {}
|
||||
result |= {str(c) for c in entry.get("add_cores") or []}
|
||||
result -= {str(c) for c in entry.get("remove_cores") or []}
|
||||
return result
|
||||
|
||||
|
||||
def list_available_targets(
|
||||
|
||||
@@ -29,6 +29,7 @@ from pathlib import Path
|
||||
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
from common import (
|
||||
apply_target_overrides,
|
||||
artifact_lock,
|
||||
ArtifactLockBusy,
|
||||
build_target_cores_cache,
|
||||
@@ -1896,12 +1897,14 @@ def generate_target_manifests(targets_dir: str, output_dir: str) -> None:
|
||||
# file instead: the user asked for a filter and got the full pack.
|
||||
overrides_path = targets_path / "_overrides.yml"
|
||||
alias_map: dict[str, list[str]] = {}
|
||||
platform_overrides: dict = {}
|
||||
if overrides_path.is_file():
|
||||
with open(overrides_path) as f:
|
||||
all_overrides = yaml_load(f) or {}
|
||||
for tname, ovr in (
|
||||
platform_overrides = (
|
||||
all_overrides.get(yml_file.stem, {}).get("targets", {}) or {}
|
||||
).items():
|
||||
)
|
||||
for tname, ovr in platform_overrides.items():
|
||||
names = [a for a in (ovr or {}).get("aliases", []) if isinstance(a, str)]
|
||||
if names:
|
||||
alias_map[tname] = names
|
||||
@@ -1925,7 +1928,12 @@ def generate_target_manifests(targets_dir: str, output_dir: str) -> None:
|
||||
f"{yml_file}: target {target_name!r} cores must be unique "
|
||||
"non-empty strings"
|
||||
)
|
||||
result[target_name] = cores
|
||||
# The same add/remove lists the pack builder applies: a list
|
||||
# published without them makes the installer skip files of a
|
||||
# core the pack for that target ships.
|
||||
result[target_name] = sorted(
|
||||
apply_target_overrides(set(cores), platform_overrides, target_name)
|
||||
)
|
||||
|
||||
for target_name, names in alias_map.items():
|
||||
if target_name not in result:
|
||||
|
||||
@@ -166,6 +166,28 @@ class CoreResolutionTests(unittest.TestCase):
|
||||
{"ghost": ["android", "linux"]},
|
||||
)
|
||||
|
||||
def test_a_default_override_drops_a_name_on_every_target(self):
|
||||
index = cf.profile_name_index(self.PROFILES)
|
||||
targets = {
|
||||
"targets": {
|
||||
"x86_64": {"cores": ["A500", "ghost"]},
|
||||
"rpi": {"cores": ["A500", "na"]},
|
||||
}
|
||||
}
|
||||
overrides = {
|
||||
"plat": {
|
||||
"targets": {
|
||||
"_default": {"remove_cores": ["A500"]},
|
||||
"rpi": {"remove_cores": ["na"]},
|
||||
}
|
||||
}
|
||||
}
|
||||
removed = cf._removed_cores(overrides, "plat")
|
||||
self.assertEqual(
|
||||
cf.unresolved_target_cores(targets, index, removed),
|
||||
{"ghost": ["x86_64"]},
|
||||
)
|
||||
|
||||
def test_coreinfo_gaps_fold_case_and_flag_standalone_profiles(self):
|
||||
names = ["FreeIntvTSOverlay", "eka2l1", "wqxemu", "mednafen_psx"]
|
||||
unprofiled, standalone = cf.coreinfo_gaps(names, self.PROFILES)
|
||||
|
||||
@@ -1747,6 +1747,33 @@ class TestE2E(unittest.TestCase):
|
||||
self.assertIn("core_a", cores)
|
||||
self.assertIn("core_b", cores)
|
||||
|
||||
def test_target_default_override_reaches_every_target(self):
|
||||
"""`_default` drops a name on every target, then the target adds its own."""
|
||||
self._write_target_fixtures()
|
||||
from common import load_target_config
|
||||
|
||||
targets_dir = os.path.join(self.platforms_dir, "targets")
|
||||
overrides = {
|
||||
"testplatform": {
|
||||
"targets": {
|
||||
"_default": {"remove_cores": ["core_a"], "add_cores": ["core_z"]},
|
||||
"target-full": {"aliases": ["full"], "add_cores": ["core_a"]},
|
||||
},
|
||||
},
|
||||
}
|
||||
with open(os.path.join(targets_dir, "_overrides.yml"), "w") as f:
|
||||
yaml.dump(overrides, f)
|
||||
self.assertEqual(
|
||||
load_target_config("testplatform", "target-minimal", self.platforms_dir),
|
||||
{"core_z"},
|
||||
)
|
||||
self.assertEqual(
|
||||
load_target_config("testplatform", "full", self.platforms_dir),
|
||||
{"core_a", "core_b", "core_c", "core_z"},
|
||||
)
|
||||
with self.assertRaises(ValueError):
|
||||
load_target_config("testplatform", "_default", self.platforms_dir)
|
||||
|
||||
def test_target_single_target_noop(self):
|
||||
self._write_target_fixtures()
|
||||
from common import load_target_config
|
||||
|
||||
@@ -821,6 +821,33 @@ class TargetFlagIsAppliedOrRefused(unittest.TestCase):
|
||||
f"{alias} disagrees with what the builder resolves",
|
||||
)
|
||||
|
||||
def test_every_published_target_is_the_list_the_builder_resolves(self):
|
||||
"""add_cores and remove_cores reach the installer, not only the builder.
|
||||
|
||||
The published lists were the scraped ones, untouched by the
|
||||
overrides: Batocera x86_64 lacked citron and xenia, which the pack
|
||||
for that target ships, and carried the Amiga machine variants and
|
||||
the launchers the builder drops.
|
||||
"""
|
||||
import sys as _sys
|
||||
|
||||
_sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
from common import load_target_config
|
||||
|
||||
manifests = sorted((REPO_ROOT / "install" / "targets").glob("*.json"))
|
||||
if not manifests:
|
||||
self.skipTest("no target manifest generated yet")
|
||||
for path in manifests:
|
||||
targets = json.loads(path.read_text())
|
||||
for target, cores in targets.items():
|
||||
if cores is None:
|
||||
continue
|
||||
with self.subTest(platform=path.stem, target=target):
|
||||
resolved = load_target_config(
|
||||
path.stem, target, str(REPO_ROOT / "platforms")
|
||||
)
|
||||
self.assertEqual(cores, sorted(resolved))
|
||||
|
||||
|
||||
class TestBaseUrlScheme(unittest.TestCase):
|
||||
"""The bootstraps insist on HTTPS; the installer must not be laxer."""
|
||||
|
||||
Reference in new issue
Block a user