From 5f14ace46355bea0a877b28312ff755ebd09b942 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Tue, 10 Nov 2026 03:47:58 +0100 Subject: [PATCH] fix: say start a game on the device itself Run on the device detection found (KNULLI, Batocera), the last line said to start that system, which is already running. A computer still names its emulator, and a card mounted on one is still put back. --- install.ps1 | 2 +- install.py | 13 +++++++++---- install.sh | 2 +- install/launchers/index.json | 16 ++++++++-------- tests/test_install.py | 27 +++++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/install.ps1 b/install.ps1 index dc3d0c50b..14cd37ef8 100644 --- a/install.ps1 +++ b/install.ps1 @@ -16,7 +16,7 @@ # and Invoke-WebRequest throws on a cut transfer before the hash is read: # the site's build rewrites this line there (scripts/sitebootstrap.py). $mismatchAdvice = "The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." - $defaultInstallSha256 = "e9bfce57f1aab1123937498d7ed7913223762df755bb572b9a36f2d6a69b7a55" + $defaultInstallSha256 = "535fea1d81dfc7fc6f2bafce27fa836048b43c488ddb7493b804ce443f13350b" # The pin above refuses any changed byte: this cap only stops a body that # cannot be the installer (a sign-in portal's page) before it is hashed. $maximumInstallerBytes = 8MB diff --git a/install.py b/install.py index 5dab26d55..3a3ca6ebd 100644 --- a/install.py +++ b/install.py @@ -6880,6 +6880,9 @@ def _report_outcome( NEXT_ON_CARD = "Next: put the card back in the device and start a game." +# On the device detection found the installer running on (KNULLI, Batocera): +# that system is already started. +NEXT_ON_DEVICE = "Next: start a game." def next_step_words(platform_of: dict[Path, str], paths: list[Path]) -> str: @@ -6888,8 +6891,9 @@ def next_step_words(platform_of: dict[Path, str], paths: list[Path]) -> str: setups = [(platform_of.get(path, ""), path) for path in paths] if setups and all(plat and on_its_card(plat, path) for plat, path in setups): return NEXT_ON_CARD - names = list(dict.fromkeys(detected_os(plat, path) or display_name(plat) - for plat, path in setups if plat)) + if setups and all(plat and detected_os(plat, path) for plat, path in setups): + return NEXT_ON_DEVICE + names = list(dict.fromkeys(display_name(plat) for plat, path in setups if plat)) if len(names) == 1: return f"Next: start {names[0]} and play." return "Next: start your emulators and play." @@ -23024,8 +23028,9 @@ def tui_next_words(state: TuiState) -> str: """The step after an install the result says went well.""" if _on_its_card(state): return NEXT_ON_CARD - name = detected_os(state.platform, state.dest) if state.dest is not None else "" - return f"Next: start {name or display_name(state.platform, state.manifest)} and play." + if state.dest is not None and detected_os(state.platform, state.dest): + return NEXT_ON_DEVICE + return f"Next: start {display_name(state.platform, state.manifest)} and play." def _dest_error_outcome(state: TuiState, installed: int) -> tuple[str, list[str]]: diff --git a/install.sh b/install.sh index 92e49ff45..e02e4839f 100755 --- a/install.sh +++ b/install.sh @@ -23,7 +23,7 @@ DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/ins # curl or wget stop on a cut transfer before the hash is read: the site's # build rewrites this line there (scripts/sitebootstrap.py). MISMATCH_ADVICE="The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." -DEFAULT_INSTALL_SHA256="e9bfce57f1aab1123937498d7ed7913223762df755bb572b9a36f2d6a69b7a55" +DEFAULT_INSTALL_SHA256="535fea1d81dfc7fc6f2bafce27fa836048b43c488ddb7493b804ce443f13350b" # The pin above refuses any changed byte: this cap only stops a body that # cannot be the installer (a sign-in portal's page) before it is hashed. MAX_INSTALLER_BYTES=8388608 diff --git a/install/launchers/index.json b/install/launchers/index.json index 5f955c7bf..3ed9e88da 100644 --- a/install/launchers/index.json +++ b/install/launchers/index.json @@ -27,8 +27,8 @@ { "dest": "roms/ports/retrobios/install.py", "repo_path": "install.py", - "size": 1142976, - "sha256": "e9bfce57f1aab1123937498d7ed7913223762df755bb572b9a36f2d6a69b7a55", + "size": 1143192, + "sha256": "535fea1d81dfc7fc6f2bafce27fa836048b43c488ddb7493b804ce443f13350b", "executable": false }, { @@ -71,8 +71,8 @@ "muos": { "archive": { "dest": "ARCHIVE/RetroBIOS.muxapp", - "size": 1196601, - "sha256": "9305dd087110937f9c4c2d08cf4b52aa55dc0c8835109991f913e23ca30f3926" + "size": 1196817, + "sha256": "140f836d1bceb5535db8357f5a2c82481de5e1a06c33eea1c9f764aa12adc580" }, "members": [ { @@ -92,8 +92,8 @@ { "name": "RetroBIOS/install.py", "repo_path": "install.py", - "size": 1142976, - "sha256": "e9bfce57f1aab1123937498d7ed7913223762df755bb572b9a36f2d6a69b7a55", + "size": 1143192, + "sha256": "535fea1d81dfc7fc6f2bafce27fa836048b43c488ddb7493b804ce443f13350b", "executable": false }, { @@ -166,8 +166,8 @@ { "dest": ".config/modules/retrobios/install.py", "repo_path": "install.py", - "size": 1142976, - "sha256": "e9bfce57f1aab1123937498d7ed7913223762df755bb572b9a36f2d6a69b7a55", + "size": 1143192, + "sha256": "535fea1d81dfc7fc6f2bafce27fa836048b43c488ddb7493b804ce443f13350b", "executable": false }, { diff --git a/tests/test_install.py b/tests/test_install.py index a6d974726..ea4c2cc6e 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -7706,5 +7706,32 @@ class AnErrorIsOneShortSentence(unittest.TestCase): self.assertEqual(long, []) +class TheNextStepFitsWhereTheInstallerRuns(unittest.TestCase): + """Run on a KNULLI device, the last line said "Next: start KNULLI and + play.": the system it runs on is already started.""" + + def test_on_the_device_detection_found(self): + folder = Path("/userdata/bios") + with unittest.mock.patch.dict(install._DETECTED_OS, {("knulli", folder): "KNULLI"}, + clear=True), \ + unittest.mock.patch.object(install, "_mounted_cards", return_value=[]): + self.assertEqual(install.next_step_words({folder: "knulli"}, [folder]), + "Next: start a game.") + + def test_on_a_computer(self): + folder = Path("/home/me/.config/retroarch/system") + with unittest.mock.patch.dict(install._DETECTED_OS, clear=True), \ + unittest.mock.patch.object(install, "_mounted_cards", return_value=[]): + self.assertEqual(install.next_step_words({folder: "retroarch"}, [folder]), + "Next: start RetroArch and play.") + + def test_a_card_mounted_on_a_computer(self): + card = Path("/media/me/KNULLI") + with unittest.mock.patch.dict(install._DETECTED_OS, clear=True), \ + unittest.mock.patch.object(install, "on_its_card", return_value=True): + self.assertEqual(install.next_step_words({card / "bios": "knulli"}, [card / "bios"]), + install.NEXT_ON_CARD) + + if __name__ == "__main__": unittest.main()