mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-18 09:23:26 -05:00
fix: hold installer detection to the registry
This commit is contained in:
1 parent
ce2417ce0f
commit
3799d4a1a4
9 files changed
+139
-59
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 = "8faaf944ff4e0cc23e9049299145077567163837eaabdd65c530554980080ed7"
|
||||
$defaultInstallSha256 = "236441baeb94f442c15a93ac01a203ce63f2938553b491db13dfb19074bbef46"
|
||||
$maximumInstallerBytes = 2MB
|
||||
$installerExit = 0
|
||||
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
|
||||
|
||||
+26
-47
@@ -621,55 +621,34 @@ def _parse_ps1_var(path: Path, key: str) -> str | None:
|
||||
return None
|
||||
|
||||
|
||||
# Embedded systems, first match wins: Knulli also carries the Batocera
|
||||
# markers. The registry publishes the same rules as each manifest's
|
||||
# `detect`; a test holds the two equal. MiSTer is a path rule below.
|
||||
_EMBEDDED_RULES: tuple[tuple[str, str, tuple[str, ...], str], ...] = (
|
||||
("rocknix", "os_release", ("rocknix",), "/storage/roms/bios"),
|
||||
("batocera", "file_exists", ("/etc/knulli-release",), "/userdata/bios"),
|
||||
("lakka", "os_release", ("lakka",), "/storage/system"),
|
||||
("batocera", "file_exists", ("/etc/batocera-version",), "/userdata/bios"),
|
||||
("recalbox", "file_exists", ("/recalbox/recalbox.version",), "/recalbox/share/bios"),
|
||||
("recalbox", "file_exists", ("/usr/bin/recalbox-settings",), "/recalbox/share/bios"),
|
||||
("retroarch", "file_exists", ("/opt/muos",), "/mnt/mmc/MUOS/bios"),
|
||||
("retroarch", "file_exists", ("/mnt/mmc/MUOS",), "/mnt/mmc/MUOS/bios"),
|
||||
("retroarch", "file_exists", ("/home/ark", "/opt/system"), "/roms/bios"),
|
||||
("retroarch", "file_exists", ("/mnt/vendor/bin/dmenu.bin",), "/mnt/mmc/bios"),
|
||||
)
|
||||
|
||||
|
||||
def _detect_embedded() -> list[tuple[str, Path]]:
|
||||
"""Check for embedded Linux retrogaming OSes."""
|
||||
found: list[tuple[str, Path]] = []
|
||||
os_release = _parse_os_release()
|
||||
os_id = os_release.get("ID", "").lower()
|
||||
|
||||
if os_id == "rocknix":
|
||||
found.append(("rocknix", Path("/storage/roms/bios")))
|
||||
return found
|
||||
|
||||
# MiSTer keeps the SD card at /media/fat with the main binary at its root
|
||||
# (Main_MiSTer file_io.cpp:1150-1156), and cores read from games/
|
||||
# (file_io.h:168)
|
||||
if Path("/media/fat/MiSTer").exists():
|
||||
found.append(("misterfpga", Path("/media/fat/games")))
|
||||
return found
|
||||
|
||||
if Path("/etc/knulli-release").exists():
|
||||
found.append(("batocera", Path("/userdata/bios")))
|
||||
return found
|
||||
|
||||
if os_id == "lakka":
|
||||
found.append(("lakka", Path("/storage/system")))
|
||||
return found
|
||||
|
||||
if Path("/etc/batocera-version").exists():
|
||||
found.append(("batocera", Path("/userdata/bios")))
|
||||
return found
|
||||
|
||||
if (
|
||||
Path("/recalbox/recalbox.version").exists()
|
||||
or Path("/usr/bin/recalbox-settings").exists()
|
||||
):
|
||||
found.append(("recalbox", Path("/recalbox/share/bios")))
|
||||
return found
|
||||
|
||||
if Path("/opt/muos").exists() or Path("/mnt/mmc/MUOS/").exists():
|
||||
found.append(("retroarch", Path("/mnt/mmc/MUOS/bios")))
|
||||
return found
|
||||
|
||||
if Path("/home/ark").exists() and Path("/opt/system").exists():
|
||||
found.append(("retroarch", Path("/roms/bios")))
|
||||
return found
|
||||
|
||||
if Path("/mnt/vendor/bin/dmenu.bin").exists():
|
||||
found.append(("retroarch", Path("/mnt/mmc/bios")))
|
||||
return found
|
||||
|
||||
return found
|
||||
os_id = _parse_os_release().get("ID", "").lower()
|
||||
for platform_name, method, values, bios in _EMBEDDED_RULES:
|
||||
if method == "os_release":
|
||||
matched = os_id in values
|
||||
else:
|
||||
matched = all(Path(value).exists() for value in values)
|
||||
if matched:
|
||||
return [(platform_name, Path(bios))]
|
||||
return []
|
||||
|
||||
|
||||
def _android_storage_root() -> Path:
|
||||
|
||||
+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="8faaf944ff4e0cc23e9049299145077567163837eaabdd65c530554980080ed7"
|
||||
DEFAULT_INSTALL_SHA256="236441baeb94f442c15a93ac01a203ce63f2938553b491db13dfb19074bbef46"
|
||||
MAX_INSTALLER_BYTES=2097152
|
||||
|
||||
cleanup() {
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
"generated": "2026-10-18T11:24:19Z",
|
||||
"base_destination": "bios",
|
||||
"detect": [
|
||||
{
|
||||
"os": "linux",
|
||||
"method": "file_exists",
|
||||
"file": "/etc/knulli-release",
|
||||
"bios_path": "/userdata/bios"
|
||||
},
|
||||
{
|
||||
"os": "linux",
|
||||
"method": "file_exists",
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
"generated": "2026-10-18T11:24:19Z",
|
||||
"base_destination": "bios",
|
||||
"detect": [
|
||||
{
|
||||
"os": "linux",
|
||||
"method": "file_exists",
|
||||
"file": "/recalbox/recalbox.version",
|
||||
"bios_path": "/recalbox/share/bios"
|
||||
},
|
||||
{
|
||||
"os": "linux",
|
||||
"method": "file_exists",
|
||||
|
||||
@@ -38,6 +38,33 @@
|
||||
"method": "config_file",
|
||||
"config": "%APPDATA%\\RetroArch\\retroarch.cfg",
|
||||
"parse_key": "system_directory"
|
||||
},
|
||||
{
|
||||
"os": "linux",
|
||||
"method": "file_exists",
|
||||
"file": "/opt/muos",
|
||||
"bios_path": "/mnt/mmc/MUOS/bios"
|
||||
},
|
||||
{
|
||||
"os": "linux",
|
||||
"method": "file_exists",
|
||||
"file": "/mnt/mmc/MUOS",
|
||||
"bios_path": "/mnt/mmc/MUOS/bios"
|
||||
},
|
||||
{
|
||||
"os": "linux",
|
||||
"method": "file_exists",
|
||||
"file": [
|
||||
"/home/ark",
|
||||
"/opt/system"
|
||||
],
|
||||
"bios_path": "/roms/bios"
|
||||
},
|
||||
{
|
||||
"os": "linux",
|
||||
"method": "file_exists",
|
||||
"file": "/mnt/vendor/bin/dmenu.bin",
|
||||
"bios_path": "/mnt/mmc/bios"
|
||||
}
|
||||
],
|
||||
"standalone_copies": [
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
"detect": [
|
||||
{
|
||||
"os": "linux",
|
||||
"method": "file_exists",
|
||||
"file": "/etc/os-release",
|
||||
"match": "ID=rocknix",
|
||||
"method": "os_release",
|
||||
"id": "rocknix",
|
||||
"bios_path": "/storage/roms/bios"
|
||||
}
|
||||
],
|
||||
|
||||
+29
-3
@@ -187,6 +187,24 @@ platforms:
|
||||
method: config_file
|
||||
config: '%APPDATA%\RetroArch\retroarch.cfg'
|
||||
parse_key: system_directory
|
||||
# Handheld firmwares that run RetroArch as their frontend: muOS,
|
||||
# ArkOS, and the stock Linux of Anbernic devices (dmenu).
|
||||
- os: linux
|
||||
method: file_exists
|
||||
file: /opt/muos
|
||||
bios_path: /mnt/mmc/MUOS/bios
|
||||
- os: linux
|
||||
method: file_exists
|
||||
file: /mnt/mmc/MUOS
|
||||
bios_path: /mnt/mmc/MUOS/bios
|
||||
- os: linux
|
||||
method: file_exists
|
||||
file: [/home/ark, /opt/system]
|
||||
bios_path: /roms/bios
|
||||
- os: linux
|
||||
method: file_exists
|
||||
file: /mnt/vendor/bin/dmenu.bin
|
||||
bios_path: /mnt/mmc/bios
|
||||
standalone_copies: *standalone_copies
|
||||
batocera:
|
||||
config: batocera.yml
|
||||
@@ -202,6 +220,11 @@ platforms:
|
||||
target_source: https://github.com/batocera-linux/batocera.linux
|
||||
install:
|
||||
detect:
|
||||
# Knulli is a Batocera derivative and carries its markers too.
|
||||
- os: linux
|
||||
method: file_exists
|
||||
file: /etc/knulli-release
|
||||
bios_path: /userdata/bios
|
||||
- os: linux
|
||||
method: file_exists
|
||||
file: /etc/batocera-version
|
||||
@@ -223,6 +246,10 @@ platforms:
|
||||
target_source: https://gitlab.com/recalbox/recalbox/-/tree/master/configs
|
||||
install:
|
||||
detect:
|
||||
- os: linux
|
||||
method: file_exists
|
||||
file: /recalbox/recalbox.version
|
||||
bios_path: /recalbox/share/bios
|
||||
- os: linux
|
||||
method: file_exists
|
||||
file: /usr/bin/recalbox-settings
|
||||
@@ -388,9 +415,8 @@ platforms:
|
||||
install:
|
||||
detect:
|
||||
- os: linux
|
||||
method: file_exists
|
||||
file: /etc/os-release
|
||||
match: 'ID=rocknix'
|
||||
method: os_release
|
||||
id: rocknix
|
||||
bios_path: /storage/roms/bios
|
||||
retropie:
|
||||
config: retropie.yml
|
||||
|
||||
+41
-4
@@ -264,10 +264,15 @@ class TestEmbeddedDetection(unittest.TestCase):
|
||||
install._parse_os_release = real_parse
|
||||
|
||||
def test_mister_detected_from_main_binary(self):
|
||||
self.assertEqual(
|
||||
self._detect_with({"/media/fat/MiSTer"}),
|
||||
[("misterfpga", Path("/media/fat/games"))],
|
||||
)
|
||||
# A path rule of the registry, read by _detect_by_path.
|
||||
real_exists = install.Path.exists
|
||||
install.Path.exists = lambda self: str(self) == "/media/fat/MiSTer"
|
||||
try:
|
||||
found: list = []
|
||||
install._detect_by_path("linux", found)
|
||||
finally:
|
||||
install.Path.exists = real_exists
|
||||
self.assertEqual(found, [("misterfpga", Path("/media/fat/games"))])
|
||||
|
||||
def test_rocknix_wins_over_path_probes(self):
|
||||
self.assertEqual(
|
||||
@@ -940,6 +945,38 @@ class DetectionFollowsTheRegistry(unittest.TestCase):
|
||||
}
|
||||
self.assertEqual(set(install._PATH_RULES), rules)
|
||||
|
||||
def test_the_embedded_table_is_the_registry(self):
|
||||
"""Only the path rules were compared: Knulli, muOS, ArkOS and the
|
||||
Recalbox version file were detected by the installer and absent
|
||||
from every manifest's `detect`, and ROCKNIX was declared another
|
||||
way. A changed bios_path in the registry reached no installer."""
|
||||
import yaml # noqa: PLC0415
|
||||
|
||||
registry = yaml.safe_load(
|
||||
(Path(__file__).resolve().parents[1] / "platforms" / "_registry.yml").read_text()
|
||||
)
|
||||
rules = set()
|
||||
for name, entry in registry["platforms"].items():
|
||||
for rule in (entry.get("install") or {}).get("detect", []):
|
||||
if rule["method"] == "os_release":
|
||||
rules.add((name, "os_release", (rule["id"],), rule["bios_path"]))
|
||||
elif rule["method"] == "file_exists":
|
||||
files = rule["file"] if isinstance(rule["file"], list) else [rule["file"]]
|
||||
rules.add((name, "file_exists", tuple(files), rule["bios_path"]))
|
||||
self.assertEqual(set(install._EMBEDDED_RULES), rules)
|
||||
|
||||
def test_the_first_embedded_match_wins(self):
|
||||
with unittest.mock.patch.object(install, "_parse_os_release", return_value={}), \
|
||||
unittest.mock.patch.object(
|
||||
Path, "exists",
|
||||
lambda p: str(p) in ("/etc/knulli-release", "/etc/batocera-version"),
|
||||
):
|
||||
self.assertEqual(install._detect_embedded(), [("batocera", Path("/userdata/bios"))])
|
||||
with unittest.mock.patch.object(install, "_parse_os_release", return_value={"ID": "ROCKNIX"}):
|
||||
self.assertEqual(
|
||||
install._detect_embedded(), [("rocknix", Path("/storage/roms/bios"))]
|
||||
)
|
||||
|
||||
def _home(self) -> Path:
|
||||
home = Path(_tempdir(self))
|
||||
patcher = unittest.mock.patch.dict(os.environ, {"HOME": str(home), "USERPROFILE": str(home)})
|
||||
|
||||
Reference in new issue
Block a user