diff --git a/install.ps1 b/install.ps1 index 922c553e..fd56fa47 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 = "324baf5363d46da75cb7f166e83b323a40ce6502084314360f909e9d1ff4dd4e" +$defaultInstallSha256 = "aec72e43585459efb0fd49d2eafb49b0e898b9ddc0f9ca2f44c7636080e21425" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index e200f844..7d1bff91 100644 --- a/install.py +++ b/install.py @@ -340,19 +340,34 @@ class Progress: def _draw(self) -> None: share = min(self.bytes / self.total_bytes, 1.0) - filled = int(share * self.BAR) - bar = "#" * filled + "-" * (self.BAR - filled) elapsed = self.elapsed() speed = self.bytes / elapsed if elapsed > 0 else 0 left = (self.total_bytes - self.bytes) / speed if speed > 0 else 0 - text = ( - f" [{bar}] {share * 100:5.1f}% " - f"{format_size(self.bytes)} / {format_size(self.total_bytes)} " - f"{format_size(int(speed))}/s " - f"{format_duration(left)} left " - f"({self.files}/{self.total_files} files)" - ) - print(f"\r\033[K{text}", end="", file=self.term.stream, flush=True) + parts = [ + f"{share * 100:5.1f}%", + f"{format_size(self.bytes)} / {format_size(self.total_bytes)}", + f"{format_size(int(speed))}/s", + f"{format_duration(left)} left", + f"({self.files}/{self.total_files} files)", + ] + # One physical line, whatever the width: \r\033[K clears only the + # line the cursor is on, so a wrapped line left a ghost per redraw + # on an 80-column console. The bar gives way first, then the least + # telling figures. + width = shutil.get_terminal_size((80, 24)).columns - 1 + while True: + tail = " ".join(parts) + room = width - len(tail) - 6 + if room >= 10 or len(parts) == 1: + break + parts.pop() + if room >= 10: + bar_width = min(self.BAR, room) + filled = int(share * bar_width) + text = f" [{'#' * filled}{'-' * (bar_width - filled)}] {tail}" + else: + text = f" {tail}" + print(f"\r\033[K{text[:width]}", end="", file=self.term.stream, flush=True) # The three RetroArch packages published for Android, newest ABI first. diff --git a/install.sh b/install.sh index f3e568b3..c3c595c7 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="324baf5363d46da75cb7f166e83b323a40ce6502084314360f909e9d1ff4dd4e" +DEFAULT_INSTALL_SHA256="aec72e43585459efb0fd49d2eafb49b0e898b9ddc0f9ca2f44c7636080e21425" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/tests/test_install.py b/tests/test_install.py index c6f64238..9541af2e 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -2631,5 +2631,31 @@ class AChunkedCutIsADownloadFailure(unittest.TestCase): self.assertIn("IncompleteRead", reason) + +class TheProgressLineFitsTheTerminal(unittest.TestCase): + """At 80 columns the 94-100 column line wrapped, and every redraw left + a ghost line behind.""" + + def test_each_width(self): + import os as _os + + for columns in (40, 60, 80, 120): + with self.subTest(columns=columns): + out = io.StringIO() + term = install.Terminal(out) + term.live = True + progress = install.Progress(5865, 2_300_000_000, term) + progress.bytes = 1_000_000_000 + progress.files = 5000 + with unittest.mock.patch.object( + install.shutil, "get_terminal_size", + return_value=_os.terminal_size((columns, 24)), + ): + progress._draw() + line = out.getvalue().split("\033[K")[-1] + self.assertLess(len(line), columns) + self.assertIn("%", line) + + if __name__ == "__main__": unittest.main()