mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-10 13:33:24 -05:00
fix: publish target aliases and refuse an unknown one
The pack builder accepts the aliases declared in the target overrides, so --target switch works there, but the installer's target manifests carried only canonical names. The documented word was the one that failed, and the installer then carried on with every file: 1911 files and 4.1 GB where the user had asked for the 863 that target needs. Aliases are emitted beside their canonical target, and an unknown target now stops the run and lists what is available. A filter is applied or refused, never ignored.
This commit is contained in:
1 parent
97f7cc1738
commit
34619c778f
6 files changed
+1406
-3
No files matched your search
+1
-1
@@ -8,7 +8,7 @@ param(
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
$defaultInstallSha256 = "b83e7422b8516d666017964cf18fc9ef8c4f8bbdb6a594ed9da0c04158eff870"
|
||||
$defaultInstallSha256 = "1e06e5d364d93beff2f9b98f7bf81b4eca4b6364a6a99c87e8fcc9a472c70764"
|
||||
$maximumInstallerBytes = 2MB
|
||||
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
|
||||
$temporary = $null
|
||||
|
||||
+16
-1
@@ -1336,7 +1336,22 @@ def main() -> None:
|
||||
targets = fetch_targets(plat_name)
|
||||
target_info = targets.get(args.target)
|
||||
if target_info is None:
|
||||
print(f" Warning: target '{args.target}' not found for {plat_name}")
|
||||
# Carrying on would install every file, which is the opposite
|
||||
# of what a filter was asked for: a 4 GB download instead of
|
||||
# the subset the target needs. Refuse rather than ignore.
|
||||
print(
|
||||
f"Error: unknown target '{args.target}' for {plat_name}.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
if targets:
|
||||
print(
|
||||
f" available: {', '.join(sorted(targets))}", file=sys.stderr
|
||||
)
|
||||
else:
|
||||
print(
|
||||
f" {plat_name} publishes no target list", file=sys.stderr
|
||||
)
|
||||
sys.exit(1)
|
||||
elif target_info.get("cores") is None:
|
||||
print(
|
||||
f" Target '{args.target}' publishes no core list; "
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ esac
|
||||
TEMP_INSTALLER=""
|
||||
TEMP_DIRECTORY=""
|
||||
DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
DEFAULT_INSTALL_SHA256="b83e7422b8516d666017964cf18fc9ef8c4f8bbdb6a594ed9da0c04158eff870"
|
||||
DEFAULT_INSTALL_SHA256="1e06e5d364d93beff2f9b98f7bf81b4eca4b6364a6a99c87e8fcc9a472c70764"
|
||||
MAX_INSTALLER_BYTES=2097152
|
||||
|
||||
cleanup() {
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -2798,6 +2798,23 @@ def generate_target_manifests(targets_dir: str, output_dir: str) -> None:
|
||||
targets = data.get("targets", {})
|
||||
if not isinstance(targets, dict):
|
||||
raise ValueError(f"{yml_file}: targets must be a mapping")
|
||||
|
||||
# The pack builder accepts the aliases declared in _overrides.yml, so
|
||||
# --target switch works there. Emitting only canonical names left the
|
||||
# installer rejecting the same word and, worse, carrying on with every
|
||||
# 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]] = {}
|
||||
if overrides_path.is_file():
|
||||
with open(overrides_path) as f:
|
||||
all_overrides = yaml_load(f) or {}
|
||||
for tname, ovr in (
|
||||
all_overrides.get(yml_file.stem, {}).get("targets", {}) or {}
|
||||
).items():
|
||||
names = [a for a in (ovr or {}).get("aliases", []) if isinstance(a, str)]
|
||||
if names:
|
||||
alias_map[tname] = names
|
||||
|
||||
result: dict[str, list[str] | None] = {}
|
||||
for target_name, target_info in targets.items():
|
||||
if not isinstance(target_name, str) or not target_name:
|
||||
@@ -2818,6 +2835,17 @@ def generate_target_manifests(targets_dir: str, output_dir: str) -> None:
|
||||
"non-empty strings"
|
||||
)
|
||||
result[target_name] = cores
|
||||
|
||||
for target_name, names in alias_map.items():
|
||||
if target_name not in result:
|
||||
continue
|
||||
for alias in names:
|
||||
if alias in result:
|
||||
raise ValueError(
|
||||
f"{yml_file}: alias {alias!r} collides with a target name"
|
||||
)
|
||||
result[alias] = result[target_name]
|
||||
|
||||
out_path = Path(output_dir) / f"{yml_file.stem}.json"
|
||||
with open(out_path, "w") as f:
|
||||
json.dump(result, f, indent=2, sort_keys=True)
|
||||
|
||||
@@ -556,6 +556,51 @@ class TestStandaloneCopiesExtraDirs(unittest.TestCase):
|
||||
)
|
||||
|
||||
|
||||
class TargetFlagIsAppliedOrRefused(unittest.TestCase):
|
||||
"""A filter the installer cannot apply must stop it, not be ignored.
|
||||
|
||||
An unknown target used to print a warning and then install every file:
|
||||
4 GB where the user asked for a subset. And the aliases the pack builder
|
||||
accepts -- switch, ps2, psp -- were absent from the published target
|
||||
manifests, so the documented word was the one that failed.
|
||||
"""
|
||||
|
||||
def test_the_published_manifests_carry_the_builder_aliases(self):
|
||||
path = REPO_ROOT / "install" / "targets" / "retroarch.json"
|
||||
if not path.is_file():
|
||||
self.skipTest("no target manifest generated yet")
|
||||
targets = json.loads(path.read_text())
|
||||
self.assertIn("nintendo-switch", targets)
|
||||
for alias in ("switch", "nx"):
|
||||
with self.subTest(alias=alias):
|
||||
self.assertIn(alias, targets, f"builder accepts --target {alias}")
|
||||
self.assertEqual(targets[alias], targets["nintendo-switch"])
|
||||
|
||||
def test_every_alias_resolves_to_its_canonical_core_list(self):
|
||||
import sys as _sys
|
||||
|
||||
_sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
from common import load_target_config
|
||||
|
||||
for name in ("install/targets/retroarch.json",):
|
||||
path = REPO_ROOT / name
|
||||
if not path.is_file():
|
||||
continue
|
||||
targets = json.loads(path.read_text())
|
||||
for alias in ("switch", "ps2", "psp"):
|
||||
if alias not in targets:
|
||||
continue
|
||||
with self.subTest(alias=alias):
|
||||
resolved = load_target_config(
|
||||
"retroarch", alias, str(REPO_ROOT / "platforms")
|
||||
)
|
||||
self.assertEqual(
|
||||
sorted(targets[alias] or []),
|
||||
sorted(resolved),
|
||||
f"{alias} disagrees with what the builder resolves",
|
||||
)
|
||||
|
||||
|
||||
class TestBaseUrlScheme(unittest.TestCase):
|
||||
"""The bootstraps insist on HTTPS; the installer must not be laxer."""
|
||||
|
||||
|
||||
Reference in new issue
Block a user