fix: default each platform to the folder it reads

This commit is contained in:
Abdessamad Derraz committed 2026-10-06 12:46:35 +02:00
1 parent 53c5504330
commit 0ea8840f14
4 files changed
+74 -5

No files matched your search

+1 -1
View File
@@ -8,7 +8,7 @@ param(
$ErrorActionPreference = "Stop"
$defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
$defaultInstallSha256 = "42b1747ae867d41da39b11daf783c0106daa6ed18861a2214c196f3a5c9a3c60"
$defaultInstallSha256 = "60e18da18b5a9a43b18d37020b676ad47babd6d12c5314e8fcc1370e4864c4e5"
$maximumInstallerBytes = 2MB
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
$temporary = $null
+31 -2
View File
@@ -103,8 +103,35 @@ DEFAULT_DESTS = {
"rocknix": Path("/storage/roms/bios"),
"misterfpga": Path("/media/fat/games"),
"retropie": Path.home() / "RetroPie" / "BIOS",
"romm": Path("/romm/library/bios"),
}
def _os_default_dests(os_type: str) -> dict[str, Path]:
"""Where a platform keeps its BIOS on this OS, when it is not detected.
The same folders the platform's detection looks for: a platform named on
the command line but not found must not land in ~/bios, which none of
them reads.
"""
home = Path.home()
if os_type == "windows":
profile = Path(os.environ.get("USERPROFILE", str(home)))
appdata = Path(os.environ.get("APPDATA", str(home / "AppData" / "Roaming")))
return {
"retroarch": appdata / "RetroArch" / "system",
"retrobat": profile / "RetroBat" / "bios",
"bizhawk": profile / "BizHawk" / "Firmware",
}
if os_type == "darwin":
return {
"retroarch": home / "Library" / "Application Support" / "RetroArch" / "system",
}
return {
"retroarch": home / ".config" / "retroarch" / "system",
"bizhawk": home / ".config" / "BizHawk" / "Firmware",
}
# Set when the run is interrupted, so queued downloads end instead of draining
# the pool: every future is submitted before the first one completes.
_stop = threading.Event()
@@ -1385,7 +1412,7 @@ def _prompt_manual_platform(os_type: str) -> list[tuple[str, Path]]:
plat = AVAILABLE_PLATFORMS[int(choice) - 1]
elif choice in AVAILABLE_PLATFORMS:
plat = choice
default_dest = DEFAULT_DESTS.get(plat, Path.home() / "bios")
default_dest = _default_dest(os_type, plat)
try:
raw = input(f"BIOS directory [{default_dest}]: ").strip()
except (EOFError, KeyboardInterrupt):
@@ -1405,7 +1432,9 @@ def _default_dest(os_type: str, platform_name: str) -> Path:
"""
if os_type == "android" and platform_name == "retroarch":
return _android_storage_root() / "RetroArch" / "system"
return DEFAULT_DESTS.get(platform_name, Path.home() / "bios")
return _os_default_dests(os_type).get(
platform_name, DEFAULT_DESTS.get(platform_name, Path.home() / "bios")
)
def _manual_usage_hint(os_type: str) -> list[str]:
+1 -1
View File
@@ -18,7 +18,7 @@ esac
TEMP_INSTALLER=""
TEMP_DIRECTORY=""
DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
DEFAULT_INSTALL_SHA256="42b1747ae867d41da39b11daf783c0106daa6ed18861a2214c196f3a5c9a3c60"
DEFAULT_INSTALL_SHA256="60e18da18b5a9a43b18d37020b676ad47babd6d12c5314e8fcc1370e4864c4e5"
MAX_INSTALLER_BYTES=2097152
cleanup() {
+41 -1
View File
@@ -183,6 +183,44 @@ class TestDefaultDests(unittest.TestCase):
)
class TestDefaultsFollowTheRegistry(unittest.TestCase):
"""A platform named but not detected fell back to ~/bios on every OS for
RetroArch, RetroBat, BizHawk and RomM, a folder none of them reads."""
ENV = {"USERPROFILE": "/u", "APPDATA": "/u/AppData/Roaming"}
def _expand(self, raw: str) -> Path:
text = raw.replace("$HOME", str(Path.home()))
for name, value in self.ENV.items():
text = text.replace(f"%{name}%", value)
return Path(text.replace("\\", "/"))
def test_the_default_is_a_folder_detection_looks_for(self):
import yaml
registry = yaml.safe_load(
(Path(__file__).resolve().parent.parent / "platforms" / "_registry.yml")
.read_text(encoding="utf-8")
)["platforms"]
checked = 0
with unittest.mock.patch.dict(os.environ, self.ENV):
for name, entry in registry.items():
by_os: dict[str, set[Path]] = {}
for rule in (entry.get("install") or {}).get("detect", []):
if rule.get("bios_path"):
by_os.setdefault(rule["os"], set()).add(self._expand(rule["bios_path"]))
elif rule.get("method") == "path_exists":
by_os.setdefault(rule["os"], set()).add(self._expand(rule["path"]))
elif rule.get("parse_key") == "system_directory":
config = self._expand(rule["config"])
by_os.setdefault(rule["os"], set()).add(config.parent / "system")
for os_type, candidates in by_os.items():
with self.subTest(platform=name, os=os_type):
self.assertIn(install._default_dest(os_type, name), candidates)
checked += 1
self.assertGreater(checked, 10)
class TestEmbeddedDetection(unittest.TestCase):
"""MiSTer is identified by the main binary at the SD card root."""
@@ -1025,7 +1063,9 @@ class TestManualPlatformPrompt(unittest.TestCase):
answers = iter(["1", ""])
with unittest.mock.patch("builtins.input", lambda _prompt="": next(answers)):
chosen = install._prompt_manual_platform("linux")
self.assertEqual(chosen, [("retroarch", Path.home() / "bios")])
self.assertEqual(
chosen, [("retroarch", Path.home() / ".config" / "retroarch" / "system")]
)
def test_name_and_explicit_directory(self):
answers = iter(["batocera", "~/my bios"])