From 8892432866daf1d5c446befaa5842981fdfa92a8 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 16 Oct 2026 22:09:12 +0200 Subject: [PATCH] fix: fail install --check when files are missing --- install.ps1 | 2 +- install.py | 5 +++++ install.sh | 2 +- tests/test_install.py | 8 ++++++++ wiki/installer.md | 3 ++- 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/install.ps1 b/install.ps1 index e79f313e..6a62c50f 100644 --- a/install.ps1 +++ b/install.ps1 @@ -8,7 +8,7 @@ param( $ErrorActionPreference = "Stop" $defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py" -$defaultInstallSha256 = "f9e46dd53fc7501ddf18ece3fc7f08dbf738c617fec93707c6a7f40e8db39673" +$defaultInstallSha256 = "e0d8fad4e7e55afa57c412e98726992d82b92286b752c9a8cce0978f0a355127" $maximumInstallerBytes = 2MB $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } $temporary = $null diff --git a/install.py b/install.py index 47bbe1d4..f3d7125d 100644 --- a/install.py +++ b/install.py @@ -2702,6 +2702,7 @@ def _install(args: argparse.Namespace, real_stdout) -> None: total_bytes = 0 total_seconds = 0.0 total_declined = 0 + check_pending = 0 failures: list[tuple[str, str]] = [] installed_paths: list[Path] = [] @@ -2881,6 +2882,7 @@ def _install(args: argparse.Namespace, real_stdout) -> None: if args.check: if to_download: print(f"\n {len(to_download)} files need downloading.") + check_pending += len(to_download) else: print("\n All files up to date.") continue @@ -2960,6 +2962,9 @@ def _install(args: argparse.Namespace, real_stdout) -> None: ) sys.stdout = real_stdout + # A check scripted as `--check && launch` reads the exit code only. + if args.check and check_pending: + sys.exit(1) if not args.check and not listing and not args.dry_run: _report_outcome( installed_paths, diff --git a/install.sh b/install.sh index 91c71c1c..71727445 100755 --- a/install.sh +++ b/install.sh @@ -18,7 +18,7 @@ esac TEMP_INSTALLER="" TEMP_DIRECTORY="" DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py" -DEFAULT_INSTALL_SHA256="f9e46dd53fc7501ddf18ece3fc7f08dbf738c617fec93707c6a7f40e8db39673" +DEFAULT_INSTALL_SHA256="e0d8fad4e7e55afa57c412e98726992d82b92286b752c9a8cce0978f0a355127" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/tests/test_install.py b/tests/test_install.py index b90c76df..f766052f 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -946,6 +946,14 @@ class InstallerStaysOnPython38AndTheStdlib(unittest.TestCase): self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr) self.assertNotIn("Traceback", proc.stderr) self.assertTrue((dest / "lynxboot.img").is_file()) + # A check is scripted as `--check && launch`: missing files fail it. + proc = subprocess.run( + base + ["--dest", str(home / "empty"), "--system", "atari-lynx", "--check"], + cwd=REPO_ROOT, env=env, capture_output=True, text=True, timeout=300, + check=False, + ) + self.assertEqual(proc.returncode, 1, proc.stdout + proc.stderr) + self.assertIn("need downloading", proc.stdout) def test_no_syntax_a_312_parser_lets_through(self): """Parenthesized context managers (3.9) and f-strings reusing their diff --git a/wiki/installer.md b/wiki/installer.md index 3f3ff76f..d961da5e 100644 --- a/wiki/installer.md +++ b/wiki/installer.md @@ -224,7 +224,8 @@ what the options name, everything by default. | `--standalone-copies` | Also copy into detected standalone emulator directories | | `--help`, `-h` | Print the option list and exit | -`--check` reads the same file list, hashes the destination and exits. Without +`--check` reads the same file list, hashes the destination and exits, with +code 1 when a file is missing or does not match and 0 when every one does. Without it, a file already present with the expected hash is left untouched, and one whose contents do not match is re-downloaded and replaced by the verified copy. Files the list does not name are never read, moved or deleted.