From 92b7d071c6ce9f575edbb996a91dc6bd25544dfd Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Mon, 9 Nov 2026 06:27:48 +0100 Subject: [PATCH] fix: one size for the ticked systems on the plan With systems ticked since the check, the headline counted them (About 3479 files, 82.2 MB) and the Install row kept the whole list's size (Install 6.6 GB). _ticked_estimate is the one count both read, offline the files the folders copied from hold. --- install.ps1 | 2 +- install.py | 41 ++++++++++++++++++++++++++---------- install.sh | 2 +- install/launchers/index.json | 16 +++++++------- tests/test_install_tui.py | 17 +++++++++++++++ 5 files changed, 57 insertions(+), 21 deletions(-) diff --git a/install.ps1 b/install.ps1 index 41ff5d5c1..345d07c29 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 = "7bfcc3b63b3d8c34998e021d84f873a49c91837fc266e593e918ac7871ef78b2" + $defaultInstallSha256 = "1d6c36d12d2cb728020e8a4cf0994e7c1779a5f2903163a83ed4caea6c54cc42" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index 2d35e99ba..de16057b6 100644 --- a/install.py +++ b/install.py @@ -18308,8 +18308,9 @@ def _plan_rows(state: TuiState) -> list[TuiRow]: # The size the pack can give: "Install 6.6 GB" from a pack holding # none of the files. lacking = set(_tui_pack_lacks(state, [event["dest"] for event in state.files])) - size = check.get("bytes_needed", 0) - sum(event["size"] for event in state.files - if event["dest"] in lacking) + size = (_ticked_estimate(state)[1] if _tui_estimating(state) + else check.get("bytes_needed", 0) - sum(event["size"] for event in state.files + if event["dest"] in lacking)) label = (f"{TUI_INSTALL_ROW} {format_size(size)}" if size >= CONFIRM_FROM_BYTES else TUI_INSTALL_ROW) rows = [TuiRow("install", label)] @@ -21849,20 +21850,17 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple: # The headline counts the systems ticked, as the list just did: at # 40x12 the line below it was dropped, and the plan showed the # total of all of them. Their data files too, as line mode's head. - chosen = _ticked_files(state) # One total, the data files in it, the kinds under the folder # adding up to it. - lines[0] = _styled(f"About {_plural(len(chosen) + data, 'file')}, " - f"{format_size(sum(e['size'] for e in chosen) + (data_size or 0))}" + count, size = _ticked_estimate(state) + lines[0] = _styled(f"About {_plural(count, 'file')}, {format_size(size)}" f", for {len(state.ticked)} of {len(state.systems)} systems", "title") if _offline_only(): # Offline, what the folders copied from hold of the systems # ticked: the plan counted the whole list beside "For your 1 of # 11 systems". - took = {event["dest"] for events in _tui_found_elsewhere(state).values() - for event in events} - held = [event for event in chosen if event["dest"] in took] - rest = len(chosen) - len(held) + data + held = _ticked_held(state) + rest = len(_ticked_files(state)) - len(held) + data # Nothing at hand: the head the whole list's plan says, for the # systems ticked. "About 0 files, 0 B" stood over 20 files the # internet would bring. @@ -21870,8 +21868,8 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple: f"{agree(rest, 'file needs', 'files need')} the internet, which " f"{offline_named()} does not use, for {len(state.ticked)} of " f"{len(state.systems)} systems", "title") if not held else _styled( - f"About {_plural(len(held), 'file')}, " - f"{format_size(sum(e['size'] for e in held))}, for {len(state.ticked)} of " + f"About {_plural(count, 'file')}, " + f"{format_size(size)}, for {len(state.ticked)} of " f"{len(state.systems)} systems" + (f", {agree(rest, 'needs', 'need')} the internet " f"({offline_named()})" if rest else ""), "title") @@ -22116,6 +22114,27 @@ def _ticked_files(state: TuiState) -> list[dict]: or (not event["systems"] and OTHER_SYSTEMS in state.ticked)] +def _ticked_held(state: TuiState) -> list[dict]: + """Offline, the files of the systems ticked that the folders copied + from hold: all an install without the internet brings.""" + took = {event["dest"] for events in _tui_found_elsewhere(state).values() + for event in events} + return [event for event in _ticked_files(state) if event["dest"] in took] + + +def _ticked_estimate(state: TuiState) -> tuple[int, int]: + """The files and bytes the systems ticked since the check bring, their + data files in them, or offline what the folders copied from hold: the + plan's headline and its Install row both say it. One system ticked, + the headline said 82.2 MB and Install 6.6 GB, the whole list's size.""" + if _offline_only(): + held = _ticked_held(state) + return len(held), sum(event["size"] for event in held) + chosen = _ticked_files(state) + data, data_size = _plan_data(state, state.check or {}) + return len(chosen) + data, sum(event["size"] for event in chosen) + (data_size or 0) + + def _view_systems(state: TuiState, width: int, height: int) -> tuple: rows = tui_rows(state) whole_rows = rows diff --git a/install.sh b/install.sh index 8126910bd..5742d9a2f 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="7bfcc3b63b3d8c34998e021d84f873a49c91837fc266e593e918ac7871ef78b2" +DEFAULT_INSTALL_SHA256="1d6c36d12d2cb728020e8a4cf0994e7c1779a5f2903163a83ed4caea6c54cc42" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/install/launchers/index.json b/install/launchers/index.json index 109e8c2a6..a0c5a8eb9 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": 1125652, - "sha256": "7bfcc3b63b3d8c34998e021d84f873a49c91837fc266e593e918ac7871ef78b2", + "size": 1126510, + "sha256": "1d6c36d12d2cb728020e8a4cf0994e7c1779a5f2903163a83ed4caea6c54cc42", "executable": false }, { @@ -71,8 +71,8 @@ "muos": { "archive": { "dest": "ARCHIVE/RetroBIOS.muxapp", - "size": 1179279, - "sha256": "bce18e6f5457057162d0c9113a9c41bd6dad53bd5badaa46d44b62e7fd7a9299" + "size": 1180137, + "sha256": "193463b29e96c5380fe026134c8d0c76aa79b938b7f40de4a579bda7cec2b630" }, "members": [ { @@ -92,8 +92,8 @@ { "name": "RetroBIOS/install.py", "repo_path": "install.py", - "size": 1125652, - "sha256": "7bfcc3b63b3d8c34998e021d84f873a49c91837fc266e593e918ac7871ef78b2", + "size": 1126510, + "sha256": "1d6c36d12d2cb728020e8a4cf0994e7c1779a5f2903163a83ed4caea6c54cc42", "executable": false }, { @@ -166,8 +166,8 @@ { "dest": ".config/modules/retrobios/install.py", "repo_path": "install.py", - "size": 1125652, - "sha256": "7bfcc3b63b3d8c34998e021d84f873a49c91837fc266e593e918ac7871ef78b2", + "size": 1126510, + "sha256": "1d6c36d12d2cb728020e8a4cf0994e7c1779a5f2903163a83ed4caea6c54cc42", "executable": false }, { diff --git a/tests/test_install_tui.py b/tests/test_install_tui.py index 610c70221..9431b4a78 100644 --- a/tests/test_install_tui.py +++ b/tests/test_install_tui.py @@ -1722,6 +1722,23 @@ class TicksBarAndPaths(unittest.TestCase): rows = install.tui_rows(state) return rows[state.focus[state.screen]] + def test_install_says_the_size_the_headline_says(self): + """One system ticked: the headline said About 3479 files, 82.2 MB + and the row Install 6.6 GB, the whole list's size.""" + big = 6 * 1024 ** 3 + state = checked_state() + state.files[0] = {**state.files[0], "size": big} + state.check = {**state.check, "bytes_needed": state.check["bytes_needed"] + big} + self.assertEqual(install.tui_rows(state)[0].label, "Install 6.0 GB") + for system, label, head in (("nintendo-gba", "Install", "About 1 file, 16.0 KB"), + ("sony-playstation", "Install 6.0 GB", + "About 3 files, 6.0 GB")): + with self.subTest(system=system): + state.ticked = {system} + self.assertTrue(install._tui_estimating(state)) + self.assertEqual(install.tui_rows(state)[0].label, label) + self.assertIn(head, "\n".join(install.tui_view(state, 80, 24))) + def test_the_filter_never_changes_the_ticks(self): state = self.systems() press(state, "n")