From 9ea80dfb7090fb74fbf520b7ac2ee2c0a642820c Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Thu, 5 Nov 2026 16:36:17 +0100 Subject: [PATCH] fix: keep the installer bootstraps of both batches The tooling merge took its own install.sh and install.ps1, which only moved the pin, and dropped the bootstrap checks of the installer batch. The ported checksum test calls the TypeScript node helper of its merged module, and the retrodeck excerpt follows the run. --- install.ps1 | 35 +++++++++++++---------- install.sh | 54 +++++++++++++++++++++++++++++++++-- tests/test_site_components.py | 2 +- wiki/reading-reports.md | 2 +- 4 files changed, 74 insertions(+), 19 deletions(-) diff --git a/install.ps1 b/install.ps1 index 8b8b18bd7..d321dfe7b 100644 --- a/install.ps1 +++ b/install.ps1 @@ -68,30 +68,35 @@ $installer = $temporary } - # The py launcher first, then python3 and python. The Microsoft Store - # places a python.exe that only points at the Store: it fails the - # version check like a missing one. - $findPython = { - $found = Get-Command py -ErrorAction SilentlyContinue - if ($found) { return ,@($found, @("-3")) } - foreach ($name in @("python3", "python")) { - $found = Get-Command $name -ErrorAction SilentlyContinue - if ($found) { return ,@($found, @()) } - } - return $null - } $usable = { param($candidate) if (-not $candidate) { return $false } $arguments = $candidate[1] - & $candidate[0].Source @arguments -c "import sys; raise SystemExit(sys.version_info < (3, 8))" | Out-Null + & $candidate[0].Source @arguments -c "import sys, ssl, unicodedata, zlib; raise SystemExit(sys.version_info < (3, 8))" 2>$null | Out-Null return ($LASTEXITCODE -eq 0) } + # The py launcher first, then python3 and python, the first that + # passes the check: a py launcher left with no usable runtime hid a + # Python 3.12 on PATH. The Microsoft Store places a python.exe that + # only points at the Store: it fails the check like a missing one. + $findPython = { + $candidates = @() + $found = Get-Command py -ErrorAction SilentlyContinue + if ($found) { $candidates += ,@($found, @("-3")) } + foreach ($name in @("python3", "python")) { + $found = Get-Command $name -ErrorAction SilentlyContinue + if ($found) { $candidates += ,@($found, @()) } + } + foreach ($candidate in $candidates) { + if (& $usable $candidate) { return ,$candidate } + } + return $null + } $needPython = "Python 3.8 or newer is required. Install it with " + "'winget install Python.Python.3.12' or from https://www.python.org/downloads/ " + "(tick 'Add python.exe to PATH'), then open a new PowerShell window and run this command again." $candidate = & $findPython - if (-not (& $usable $candidate)) { + if (-not $candidate) { # winget ships with Windows 10 and 11: at a console the bootstrap # offers to run the install the message names, then carries on. $winget = Get-Command winget -ErrorAction SilentlyContinue @@ -109,7 +114,7 @@ $candidate = & $findPython } } - if (-not (& $usable $candidate)) { throw $needPython } + if (-not $candidate) { throw $needPython } } $python = $candidate[0] $launcher = $candidate[1] diff --git a/install.sh b/install.sh index 408efd478..ebf1fc626 100755 --- a/install.sh +++ b/install.sh @@ -121,14 +121,29 @@ if [ -z "$INSTALLER" ] || [ ! -f "$INSTALLER" ]; then INSTALLER="$TEMP_INSTALLER" fi +# A Python can be built without ssl, unicodedata or zlib, and the installer +# needs all three: a python3 lacking ssl was chosen over a full python and +# every download then failed as if the network were down. find_python() { PYTHON="" + PYTHON_LACKING="" + PYTHON_OLD="" for command_name in python3 python; do - if command -v "$command_name" >/dev/null 2>&1 \ - && "$command_name" -c 'import sys; raise SystemExit(sys.version_info < (3, 8))' 2>/dev/null; then + command -v "$command_name" >/dev/null 2>&1 || continue + if ! "$command_name" -c 'import sys; raise SystemExit(sys.version_info < (3, 8))' \ + 2>/dev/null; then + found_version=$("$command_name" -c \ + 'import sys; print("%d.%d.%d" % tuple(sys.version_info[:3]))' 2>/dev/null) + if [ -n "$found_version" ]; then + PYTHON_OLD=${PYTHON_OLD:-"$command_name here is $found_version"} + fi + continue + fi + if "$command_name" -c 'import ssl, unicodedata, zlib' 2>/dev/null; then PYTHON=$command_name return 0 fi + PYTHON_LACKING=${PYTHON_LACKING:-$command_name} done return 1 } @@ -172,6 +187,20 @@ if ! find_python; then esac fi fi +if [ -z "$PYTHON" ] && [ -n "$PYTHON_LACKING" ]; then + echo "Error: $PYTHON_LACKING is built without a module the installer needs" >&2 + echo " (ssl, unicodedata or zlib). Run it with a full Python 3.8 or newer." >&2 + exit 1 +fi +if [ -z "$PYTHON" ] && [ -n "$PYTHON_OLD" ]; then + # Debian Buster ships 3.7: apt answers that python3 is already the newest + # version, and the same advice looped. + echo "Error: Python 3.8 or newer is required, and $PYTHON_OLD." >&2 + echo " Install a newer one: from this system's packages if they offer one, by" >&2 + echo " updating the system, or from https://www.python.org/downloads/." >&2 + echo " Then run this command again." >&2 + exit 1 +fi if [ -z "$PYTHON" ]; then echo "Error: Python 3.8 or newer is required." >&2 if [ -n "$install_command" ]; then @@ -183,6 +212,27 @@ if [ -z "$PYTHON" ]; then exit 1 fi +# Termux reaches shared storage, where RetroArch keeps its system folder, +# once termux-setup-storage has run: the installer told the user to run it +# and start again. At a terminal the bootstrap runs it here. It only asks +# the Termux app, which shows Android's permission dialog and creates +# ~/storage once allowed: the wait gives the user time to answer. +case "${TERMUX_VERSION:-}:${PREFIX:-}" in + ?*:*|*com.termux*) + if [ ! -d "$HOME/storage" ] && command -v termux-setup-storage >/dev/null 2>&1 \ + && (: /dev/null; then + echo "Android asks for the storage permission: allow it, so that the files reach" >/dev/tty + echo "the RetroArch folder." >/dev/tty + termux-setup-storage /dev/tty 2>&1 || true + waited=0 + while [ ! -d "$HOME/storage" ] && [ "$waited" -lt 60 ]; do + sleep 1 + waited=$((waited + 1)) + done + fi + ;; +esac + # Piped from curl, standard input is this script, not the terminal: the # installer would skip every question it can ask. Hand it the terminal when # there is one. diff --git a/tests/test_site_components.py b/tests/test_site_components.py index 2fe86df77..4bd277d60 100644 --- a/tests/test_site_components.py +++ b/tests/test_site_components.py @@ -1069,7 +1069,7 @@ class AChecksumLineIsAHash(unittest.TestCase): "deadbeef.bin", f"{md5} {sha1}", ] - out = _node(code + f"console.log(JSON.stringify({json.dumps(cases)}.map((c) => " + out = _node_typescript(code + f"console.log(JSON.stringify({json.dumps(cases)}.map((c) => " "[normalizeHash(c), isHash(normalizeHash(c))])));") self.assertEqual(json.loads(out), [ [md5, True], [sha1, True], [sha1, True], [sha1, True], [md5, True], diff --git a/wiki/reading-reports.md b/wiki/reading-reports.md index 066432d47..eda8e261f 100644 --- a/wiki/reading-reports.md +++ b/wiki/reading-reports.md @@ -107,7 +107,7 @@ RetroDECK: 2007/2008 OK, 1 untested [md5] UNTESTED (required): nintendo-ds/dsifirmware.bin: declared hash contradicted by the local file DISCREPANCY: nintendo-snes/sgb2.boot.rom: RetroDECK says OK but supersnes9x says size mismatch: got 524288, accepted [256] supersnes9x [size] - Core files: 1797 in pack, 1 required missing, 27 optional missing (--verbose lists them) + Core files: 1798 in pack, 1 required missing, 26 optional missing (--verbose lists them) Core files held but not packed: 154 (142 installed with its emulator, 8 read below a save folder per system and no system runs the core there, 4 a packed file occupies its directory) MISSING (required): FinalBurn Neo needs sfiii2a.zip (1 file) Game data: 5099 in pack, 38 missing (--verbose lists them)