fix: read EmuELEC's home in launcher paths

EmuELEC links /storage/.local/share/flycast to /storage/roms/bios/dc
(flycast.sh:11-14 at v4.8), and Flycast reads
$HOME/.local/share/flycast. Root's home there is /storage
(packages/sysutils/busybox/package.mk:168, profile.d/98-busybox.conf:4,
sourced by flycast.sh:7), which nothing recorded, so the link bound
nothing and flycastsa's files went to the BIOS root.

The registry's home_directory now spells that directory as ~ in the
handles and directories of launcher records. flycastsa's ten files
land in bios/dc, where the libretro build already reads them. The
manifest drops dc_boot.bin and dc_nvmem.bin from the BIOS root, which
no emulator reads there, and six arcade archives at the root go back
to the MAME sets the mame cores claim.
This commit is contained in:
Abdessamad Derraz committed 2026-11-10 12:02:36 +01:00
1 parent adac87ec32
commit 5255716273
3 files changed
+40 -4

No files matched your search

+4
View File
@@ -931,6 +931,10 @@ platforms:
# retroarch/package.mk:115 at v4.8) and setsettings.sh never sets it, so
# RetroArch saves beside each game: no single place.
save_directory: null
# root's home, which every launcher script gets from /etc/profile
# (packages/sysutils/busybox/package.mk:168 and
# packages/sysutils/busybox/profile.d/98-busybox.conf:4 at v4.8).
home_directory: /storage
schedule: monthly
target_scraper: emuelec_targets
target_source: https://github.com/EmuELEC/EmuELEC/blob/dev/packages/sx05re/emuelec/package.mk
+10 -4
View File
@@ -347,14 +347,19 @@ _HOME = re.compile(r"^(?:\$\{HOME\}|\$HOME|\$home|~)(?=/|$)")
_FLATPAK_DATA = re.compile(r"^~/\.var/app/[^/]+/data(?=/|$)")
def normalize_handle(token: str) -> str:
def normalize_handle(token: str, home: str = "") -> str:
"""One spelling for a path, setting or function a launcher record names.
``$home``, ``$HOME``, ``${HOME}`` and ``~`` are one directory, and a
Flatpak's data directory is its ``$XDG_DATA_HOME``.
Flatpak's data directory is its ``$XDG_DATA_HOME``. ``home`` is the
platform's home directory spelled out (``home_directory``): EmuELEC
links /storage/.local/share/flycast, Flycast's ~/.local/share/flycast.
"""
token = token.strip().strip("\"'").rstrip(",;").rstrip("/")
token = token.removesuffix("()")
home = home.rstrip("/")
if home and _below(token, home) is not None:
token = "~" + token[len(home):]
token = _HOME.sub("~", token)
return _FLATPAK_DATA.sub("$XDG_DATA_HOME", token)
@@ -464,6 +469,7 @@ def handed_directories(config: dict) -> list[HandedDirectory]:
holds <system> gives one directory per system the platform declares.
"""
base = str(config.get("base_destination") or "bios")
home = str(config.get("home_directory") or "")
natives = native_systems(config)
declared = {d.lower() for d in declared_destinations(config)}
found: list[HandedDirectory] = []
@@ -490,7 +496,7 @@ def handed_directories(config: dict) -> list[HandedDirectory]:
if any(re.search(r"[\s,:;]", part) for part in parts):
continue
for part in parts:
directory = normalize_handle(part)
directory = normalize_handle(part, home)
if passes_to.startswith(WORKING_DIRECTORY_PASSED):
# The program runs from the directory: what its code
# reads through getcwd(), or relative to it, is below it.
@@ -499,7 +505,7 @@ def handed_directories(config: dict) -> list[HandedDirectory]:
handles = frozenset(
handle
for token in passes_to.split()
if (handle := normalize_handle(token)) and handle != directory
if (handle := normalize_handle(token, home)) and handle != directory
) | ini_keys(passes_to)
folder = _folder_in_bios(part, base)
for emulator in (e.strip() for e in str(record.get("emulator", "")).split(",")):
+26
View File
@@ -721,5 +721,31 @@ class Quasi88OnRetroPie(unittest.TestCase):
)
class FlycastOnEmuELEC(unittest.TestCase):
"""EmuELEC links /storage/.local/share/flycast to bios/dc (flycast.sh:11-14),
and root's home is /storage (busybox profile.d/98-busybox.conf:4)."""
def test_the_home_directory_is_spelled_as_home(self) -> None:
from launchers import normalize_handle
self.assertEqual(
normalize_handle("/storage/.local/share/flycast", "/storage"), "~/.local/share/flycast"
)
self.assertEqual(normalize_handle("/storage", "/storage/"), "~")
self.assertEqual(normalize_handle("/storagex/a", "/storage"), "/storagex/a")
self.assertEqual(
normalize_handle("/storage/.local/share/flycast"), "/storage/.local/share/flycast"
)
def test_the_bios_lands_in_dc(self) -> None:
profile = load_emulator_profiles(str(REPO_ROOT / "emulators"))["flycast"]
config = load_platform_config("emuelec", str(REPO_ROOT / "platforms"))
layouts = platform_layouts("flycast", profile, standalone_set(config))
(view,) = [v for v, standalone in layouts if standalone]
self.assertTrue(view["files"])
for entry in view["files"]:
self.assertEqual(entry["standalone_path"], "dc/" + entry["layout_path"])
if __name__ == "__main__":
unittest.main()