fix: polish the screens audit 11 named

Long messages scroll with their position, a small window says why the
questions come line by line, one bar rule per width, the folder a
config names sits under it and wraps whole, the help while typing a
filter lists what does not type, the plan names --core and --region,
pc finds the computer setups, rows keep sizes near their names, a
partial result counts once, a quit is said as one, the WSL browser
names drives by letter and No connection names the pack.
This commit is contained in:
Abdessamad Derraz committed 2026-10-27 16:27:47 +01:00
1 parent 302c7737b2
commit 39c2809a4b
37 files changed
+345 -584

No files matched your search

+1 -1
View File
@@ -11,7 +11,7 @@
$ErrorActionPreference = "Stop"
$defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
$defaultInstallSha256 = "c030192b6ecfcedfc114ecf0cbcfc509fcca44e398e6d8cefedc7766065df538"
$defaultInstallSha256 = "c138739989d2ea32639c470f3af89d5038604b7fb446f08cc37659e139b76605"
$maximumInstallerBytes = 2MB
$installerExit = 0
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
+113 -28
View File
@@ -10299,8 +10299,17 @@ def main() -> None:
"or --list-targets")
# The screens have no choice for --declared-only: the questions ask the
# rest, and the run keeps the platform's own list.
if args.tui or not (plain_requested(args) or args.declared_only or tui_blocker(args)):
blocker = "" if args.tui else tui_blocker(args)
if args.tui or not (plain_requested(args) or args.declared_only or blocker):
sys.exit(run_tui(args))
small = re.match(r"the terminal is (\d+x\d+), smaller than", blocker or "")
# A pseudo-terminal nobody sized (script fed from a pipe) is 0x0: no window.
if (small and "0" not in small[1].split("x") and not plain_requested(args)
and not args.declared_only):
# The questions came line by line with no word of why: the page
# says a smaller window says so (tui_audit_11 P3-4).
print(f"The window is {small[1]}: questions come line by line "
f"({TUI_MIN_COLS}x{TUI_MIN_ROWS} for the full screen).")
if args.events:
# The events own stdout. The text a person reads goes to stderr, so a
# program never has to tell one from the other.
@@ -12256,8 +12265,9 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None:
# names it: "found on this machine" followed "from E:\".
sources = list(dict.fromkeys(copy.index.label for copy in copies.values()))
named = ", ".join(screen_text(shown_path(label)) for label in sources)
origin = (f"copied from {named}" if all(copy.index is not bios_index for copy in copies.values())
else "found on this machine")
origin = (f"copied from {named}" if all(
copy.index is not bios_index for copy in copies.values())
else "found on this machine")
print(f"\nCopying {_plural(len(copies), 'file')} {origin}"
f"{rest}{where} ({format_size(dl_size)})...")
elif LOCAL.pack is not None:
@@ -12902,6 +12912,8 @@ class TuiState:
self.cli_regions: list = []
self.cores: list = []
self.no_game_data: bool = False
# A quit the user chose, said as one (tui_quit).
self.quit_asked: bool = False
self.installed_only: bool = False
self.jobs: int = 8
self.passthrough: list = []
@@ -13787,8 +13799,11 @@ def _back(state: TuiState) -> list[tuple]:
return effects
def tui_quit(state: TuiState, code: int = 130) -> list[tuple]:
"""Leave now: with the install's own code once it ran, else 130."""
def tui_quit(state: TuiState, code: int = 130, asked: bool = True) -> list[tuple]:
"""Leave now: with the install's own code once it ran, else 130. asked
is a quit the user chose (q, Quit), said as one: it read "stopped", the
word of an interrupted run (tui_audit_11 P3-19)."""
state.quit_asked = asked
if state.screen == "result":
code = state.code if state.code is not None else 1
elif state.screen == "error":
@@ -13804,7 +13819,7 @@ def tui_interrupt(state: TuiState) -> list[tuple]:
return [("kill",)]
state.stopping = True
return [("stop",)]
return tui_quit(state)
return tui_quit(state, asked=False)
def _start_run(state: TuiState, run: str) -> list[tuple]:
@@ -14868,7 +14883,7 @@ _DESKTOP_LEAD: dict[str, tuple[str, ...]] = {
# and a Linux one (SteamOS), RetroDECK is a Linux Flatpak, BizHawk publishes
# Windows and Linux builds, RetroPie runs on Debian and Ubuntu.
_COMPUTER_SYSTEMS: dict[str, tuple[tuple[str, ...], tuple[str, ...]]] = {
"Windows": (("windows",), ("retroarch", "retrobat", "emudeck", "bizhawk")),
"Windows": (("windows", "pc"), ("retroarch", "retrobat", "emudeck", "bizhawk")),
"macOS": (("macos", "mac", "osx", "macbook"), ("retroarch",)),
"Linux": (("linux", "ubuntu", "debian", "steamos"),
("retroarch", "emudeck", "retrodeck", "bizhawk", "retropie")),
@@ -14878,7 +14893,9 @@ _COMPUTER_SYSTEMS: dict[str, tuple[tuple[str, ...], tuple[str, ...]]] = {
def _computer_named(plat: str, needle: str) -> list[str]:
"""The computer systems the filter names that run plat."""
key = _device_key(needle)
if len(key) < 3:
# Two letters are a word on their way: "wi" said "No setup matches"
# between "w" and "win" (tui_audit_11 P3-17). "pc" is one of the words.
if len(key) < 2:
return []
return [name for name, (words, plats) in _COMPUTER_SYSTEMS.items()
if plat in plats and any(word.startswith(key) for word in words)]
@@ -15200,6 +15217,12 @@ def tui_update(state: TuiState, key: TuiKey) -> list[tuple]:
if char == "q":
return tui_quit(state)
rows = tui_rows(state)
if screen == "error" and key.name in ("pgup", "pgdn"):
# The message scrolls, the rows stay (_view_error).
step = max(1, state.rows - len(rows) - 5)
state.focus["error_text"] = max(0, state.focus.get("error_text", 0)
+ (step if key.name == "pgdn" else -step))
return []
if screen in _PAGERS and not rows:
return _pager_key(state, key)
if not rows:
@@ -15500,11 +15523,17 @@ def _route_hint(state: TuiState, parts: tuple) -> tuple:
_SHORT_VERBS = ((" Only this system", " Only this"), (" First system", " First"))
# Below this many columns of text the bar always uses the short key names.
TUI_LONG_BAR_WIDTH = 52
def _hint(width: int, *parts: str) -> str:
"""The keys that matter now, short names first given up, then whole
entries from the right."""
full = " ".join(parts)
if cell_width(full) <= width:
# One rule for every screen of a width: at 40 columns the plan read
# "A Install" and the next screen "A/Enter Install" (tui_audit_11 P3-5).
if cell_width(full) <= width and width >= TUI_LONG_BAR_WIDTH:
return full
short = []
for part in parts:
@@ -15543,8 +15572,15 @@ _ROW_VERBS = {
}
# The widest a row's two columns spread: at 120 columns a system's size sat
# 85 columns from its name (tui_audit_11 P3-20).
TUI_ROW_SPREAD = 78
def _row_line(row: TuiRow, focused: bool, width: int) -> TuiLine:
left = ("> " if focused else " ") + row.label
if row.right:
width = min(width, max(TUI_ROW_SPREAD, cell_width(left) + 2 + cell_width(row.right)))
if row.keep_right and row.right:
whole = width - cell_width(left) - 2
forms = (row.right, *row.narrow)
@@ -15820,6 +15856,11 @@ def _plan_lines(check: dict, dest: Path | None, state: TuiState) -> list:
_styled(headline, "title"),
_styled(f"BIOS folder: {_short_path(_plan_folder(state, dest), state.home)}", "path"),
]
found_in = _retroarch_config_at(dest) if dest is not None else None
if found_in:
# Right under the folder it names: after the save lines it read as
# naming them (tui_audit_11 P3-6).
lines.append(_styled(f"Named by {_short_path(Path(found_in[0]), state.home)}", "path"))
if state.facts.get("writable") is False:
# The remedy itself comes below, after the counts.
lines += cannot_write_words(dest, state.platform, tui_hint(state),
@@ -15848,9 +15889,6 @@ def _plan_lines(check: dict, dest: Path | None, state: TuiState) -> list:
else state.dry_saves if check is state.dry else None)
saves_lines = _saves_lines(state, saves)
lines += [_styled(line, "path" if index else "") for index, line in enumerate(saves_lines)]
found_in = _retroarch_config_at(dest) if dest is not None else None
if found_in:
lines.append(_styled(f"Named by {_short_path(Path(found_in[0]), state.home)}", "path"))
free = state.facts.get("free")
if free is not None:
lines.append(f"Free space: {format_size(free)}")
@@ -16048,7 +16086,9 @@ def _status_after(state: TuiState) -> list[str]:
def _view_browse(state: TuiState, width: int, height: int) -> tuple:
where = "Drives" if state.browse_dir is None else middle(str(state.browse_dir), width)
# Under WSL a drive is E:\ on every screen: the title said /mnt/e
# (tui_audit_11 P3-13).
where = "Drives" if state.browse_dir is None else middle(shown_path(state.browse_dir), width)
hint: list = []
if state.browse_for == "from":
# Two lines at 40 columns: the long form was cut after "copied,".
@@ -16159,7 +16199,22 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple:
whole = (f"{check['present']} in place, {check['missing']} missing, "
f"{check['wrong_hash']} wrong ")
lines = [line for line in lines if not str(line).startswith(whole)]
lines[2:2] = choice
# Under the folder and what named it, in this order: the card's note,
# the choice named on the command line, the choice made here.
at = next((index + 1 for index, line in enumerate(lines)
if str(line).startswith("BIOS folder:")), 1)
if at < len(lines) and str(lines[at]).startswith("Named by "):
at += 1
named = [*([f"for {len(state.systems)} of {len(tui_systems(state))} systems (--system)"]
if state.cli_systems and state.systems else []),
*(["--core"] if state.cores else []), *(["--region"] if state.regions else [])]
said = ", ".join(named)
# Named on the command line: said in line mode's words, and widened by
# Choose systems. --core and --region were said in line mode alone
# (tui_audit_11 P3-11).
lines[at:at] = [*([state.card_note] if state.card_note
and state.card_note != state.status else []),
*([f"{said[0].upper()}{said[1:]}."] if said else []), *choice]
split = _tui_split(state, [(event["dest"], event["size"]) for event in state.files
if event["state"] != "present"])
if split or (state.no_game_data and _game_data_row(state) is not None):
@@ -16167,16 +16222,16 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple:
# row that leaves it out.
lines[1:1] = [f"{split or 'No game data'}. {GAME_DATA_WORDS[0].upper()}"
f"{GAME_DATA_WORDS[1:]}."]
if state.cli_systems and state.systems:
# Named on the command line: said, and widened by Choose systems.
lines[2:2] = [f"For {len(state.systems)} of {len(tui_systems(state))} "
"systems (--system)."]
if state.card_note and state.card_note != state.status:
# Under the folder it is about: a stick no file names, taken for
# KNULLI, read as a KNULLI card.
lines.insert(2, state.card_note)
if state.status:
lines.append(state.status)
if width > 38:
# A folder that does not fit is wrapped, as the first screen wraps
# it: cut in its middle, the plan hid the part being checked before
# Install. Cut only on a 40-column screen (tui_audit_11 P3-7).
lines = [piece for line in lines for piece in (
[_styled(part) for part in _wrap(str(line), width)]
if getattr(line, "style", "") == "path" and cell_width(str(line)) > width
else [line])]
rows = tui_rows(state)
if width < 54:
rows = [row._replace(label="Copy from your old card or a folder")
@@ -16594,12 +16649,17 @@ def tui_outcome(state: TuiState) -> tuple[str, list[str]]:
# As the plan counted them, and as line mode ends.
games = done.count(GAME_DATA)
lines.append(f"Installed: {kinds_words(len(done) - games, games)}.")
sources = _tui_sources(state, installed, len(failed) + left)
if left and installed and sources:
# One count, then the remedy, as line mode says it: the count came
# twice, the remedy between them (tui_audit_11 P3-18).
lines[0] = sources
sources = ""
if sources:
lines.append(sources)
if left:
lines.append(_offline_remedy([_short_path(Path(folder), state.home)
for folder in state.from_folders]))
sources = _tui_sources(state, installed, len(failed) + left)
if sources:
lines.append(sources)
ok = {dest for dest, good, _why in state.finished if good}
if any(reason and dest in ok for dest, (_folder, reason) in state.local_dests.items()):
# A fix copies: the misplaced files are the user's, never moved.
@@ -16697,9 +16757,22 @@ def _view_result(state: TuiState, width: int, height: int) -> tuple:
def _view_error(state: TuiState, width: int, height: int) -> tuple:
"""The message and its rows. A message longer than the room the rows
leave scrolls, with a line saying which lines are in view: at 40x12 the
offline screen dropped its remedy without a word (tui_audit_11 P3-2)."""
rows = tui_rows(state)
text = _text_lines(list(state.error), width)
room = height - len(rows) - (1 if rows else 0)
hint: tuple = ("A/Enter Choose", "B/Esc Back")
if len(text) > room >= 2:
first = max(0, min(state.focus.get("error_text", 0), len(text) - (room - 1)))
state.focus["error_text"] = first
text = _scrolled(text, first, room)
page = (TUI_ROUTES.get(state.pad, TUI_ROUTES["both"]).help["page"]
or "PgUp/PgDn").split(", ")[0]
hint += (f"{page} Scroll",)
return (state.error_title or "Something went wrong",
_compose(state, width, height, state.error, tui_rows(state)),
("A/Enter Choose", "B/Esc Back"))
_compose(state, width, height, text, rows), hint)
def _view_quit(state: TuiState, width: int, height: int) -> tuple:
@@ -16740,6 +16813,12 @@ def _help_lines(state: TuiState) -> list[tuple[str, str]]:
return [(names["stop"], "Stop: what is done stays done"),
*([(names["kill"], "Stop")] if names["kill"] else []),
*_route_extras(state), *_help_key(state)]
if state.editing:
# Typing a filter: Space, a, n and q type there, and the help listed
# them as ticks, all, none and quit (tui_audit_11 P3-9).
return [("Enter", "Done"), ("Esc", "Clear the filter"),
("Backspace", "Delete a character"), ("Ctrl-U", "Clear"), ("Ctrl-C", "Quit"),
*_route_extras(state)]
if screen == "path":
return [(names["enter"], "Use this folder"), ("Backspace", "Delete a character"),
("Ctrl-U", "Clear"), (names["esc"], "Back"), ("Ctrl-C", "Quit"),
@@ -17228,7 +17307,11 @@ def _tui_fetch(plat: str, inbox: queue.Queue, log: io.StringIO) -> None:
", then choose Try again") + "."]
if code == "network":
lines = [f"The list of BIOS files could not be downloaded: {words}.",
"Check the Wi-Fi or the cable, then choose Try again."]
"Check the Wi-Fi or the cable, then choose Try again.",
# A handheld with no Wi-Fi has the pack as its way
# (tui_audit_11 P3-3).
"Or copy a pack to the card and run the installer with --from-pack "
"PACK: no network is needed then."]
proxy = next((name for name in ("HTTPS_PROXY", "https_proxy", "ALL_PROXY",
"all_proxy") if os.environ.get(name)), "")
if proxy:
@@ -17481,6 +17564,8 @@ def _closing_lines(state: TuiState) -> list[str]:
for line in state.error)]
if state.exit_code == 0:
return [f"RetroBIOS: everything is in place in {state.dest}."]
if state.quit_asked:
return ["RetroBIOS: quit. Nothing was installed."]
return ["RetroBIOS: stopped. Nothing was installed."]
+1 -1
View File
@@ -18,7 +18,7 @@ esac
TEMP_INSTALLER=""
TEMP_DIRECTORY=""
DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
DEFAULT_INSTALL_SHA256="c030192b6ecfcedfc114ecf0cbcfc509fcca44e398e6d8cefedc7766065df538"
DEFAULT_INSTALL_SHA256="c138739989d2ea32639c470f3af89d5038604b7fb446f08cc37659e139b76605"
MAX_INSTALLER_BYTES=2097152
cleanup() {
+8 -8
View File
@@ -27,8 +27,8 @@
{
"dest": "roms/ports/retrobios/install.py",
"repo_path": "install.py",
"size": 813666,
"sha256": "c030192b6ecfcedfc114ecf0cbcfc509fcca44e398e6d8cefedc7766065df538",
"size": 818472,
"sha256": "c138739989d2ea32639c470f3af89d5038604b7fb446f08cc37659e139b76605",
"executable": false
},
{
@@ -71,8 +71,8 @@
"muos": {
"archive": {
"dest": "ARCHIVE/RetroBIOS.muxapp",
"size": 866215,
"sha256": "cfe8dc0a1cda5a63d810ebcc8f28e1f1797446d5ef72447d0a64b3f68639a258"
"size": 871021,
"sha256": "0b2f463994437ab12013039a8eec8ce94040a03594e9d820a0da58a1058ef9e1"
},
"members": [
{
@@ -92,8 +92,8 @@
{
"name": "RetroBIOS/install.py",
"repo_path": "install.py",
"size": 813666,
"sha256": "c030192b6ecfcedfc114ecf0cbcfc509fcca44e398e6d8cefedc7766065df538",
"size": 818472,
"sha256": "c138739989d2ea32639c470f3af89d5038604b7fb446f08cc37659e139b76605",
"executable": false
},
{
@@ -166,8 +166,8 @@
{
"dest": ".config/modules/retrobios/install.py",
"repo_path": "install.py",
"size": 813666,
"sha256": "c030192b6ecfcedfc114ecf0cbcfc509fcca44e398e6d8cefedc7766065df538",
"size": 818472,
"sha256": "c138739989d2ea32639c470f3af89d5038604b7fb446f08cc37659e139b76605",
"executable": false
},
{
+1 -1
View File
@@ -9,4 +9,4 @@
Ctrl-C Quit B/Esc Quit
Ctrl-C Quit B Quit
+1 -1
View File
@@ -12,4 +12,4 @@
Ctrl-C Quit B/Esc Quit
Ctrl-C Quit B Quit
+1 -1
View File
@@ -9,4 +9,4 @@
A/Enter Back
A Back
+1 -1
View File
@@ -12,4 +12,4 @@
A/Enter Back
A Back
+1 -1
View File
@@ -9,4 +9,4 @@
> Install
Back
A/Enter Install B/Esc Back ? Help
A Install B Back ? Help
+1 -1
View File
@@ -12,4 +12,4 @@
A/Enter Install B/Esc Back ? Help
A Install B Back ? Help
+1 -1
View File
@@ -9,4 +9,4 @@
A/Enter Create B/Esc Quit
A Create B Quit
+1 -1
View File
@@ -12,4 +12,4 @@
A/Enter Create B/Esc Quit
A Create B Quit
+3 -3
View File
@@ -5,8 +5,8 @@
-2] Name or service not known
Address:
https://raw.githubusercontent.com/
Abdess/retrobios/main/install/
retroarch.json
1-5 of 7
> Choose another setup or folder
Quit
A/Enter Choose B/Esc Back
A Choose B Back PgUp/PgDn Scroll
+1 -1
View File
@@ -12,4 +12,4 @@
Quit
A/Enter Choose B/Esc Back
A Choose B Back
+1 -1
View File
@@ -9,4 +9,4 @@
> Browse for a folder
Type a path
Look again
A/Enter Browse B/Esc Back ? Help
A Browse B Back ? Help
+1 -1
View File
@@ -12,4 +12,4 @@
Look again
A/Enter Browse B/Esc Back ? Help
A Browse B Back ? Help
+1 -1
View File
@@ -9,4 +9,4 @@
FAILED scph5500.bin (HTTP 404)
ok gba_bios.bin
B/Esc Stop ? Help
B Stop ? Help
+1 -1
View File
@@ -12,4 +12,4 @@
B/Esc Stop ? Help
B Stop ? Help
+8 -8
View File
@@ -2,14 +2,14 @@
Each row is an option of the command line, named on the right.
> Preferred regions: North America, Japan --region
Game data: kept --no-game-data
Installed cores only: no (1 found) --installed-cores
Cores: all --core
Parallel downloads: 8 --jobs
BIOS folder: ~/.config/retroarch/system --dest
Copy from: none --from
Preview the file list --dry-run
> Preferred regions: North America, Japan --region
Game data: kept --no-game-data
Installed cores only: no (1 found) --installed-cores
Cores: all --core
Parallel downloads: 8 --jobs
BIOS folder: ~/.config/retroarch/system --dest
Copy from: none --from
Preview the file list --dry-run
Show the command line
+13 -13
View File
@@ -14,26 +14,26 @@
BizHawk
MiSTer FPGA
RetroPie
Allium, SD card Miyoo Mini, Miyoo Mini Plus, Miyoo Mini Flip
AmberELEC, SD card RG351, RG552
Anbernic stock firmware, SD card RG35XX Plus, RG35XX H, RG35XX SP, RG28XX
Allium, SD card Miyoo Mini, Miyoo Mini Plus, Miyoo Mini Flip
AmberELEC, SD card RG351, RG552
Anbernic stock firmware, SD card RG35XX Plus, RG35XX H, RG35XX SP, RG28XX
ArchR, SD card R36S, R33S, R36S Soysauce, Odroid Go Advance, Odroid Go Super, RG351V, +6
ArkOS, SD card RG353M, RG353V, RG503, RGB30, RK2023, RG351MP, RG351V, R35S, RGB10
CrossMix-OS, SD card TrimUI Smart Pro
dArkOS, SD card Odroid Go Advance, RGB10, RG351MP, G350
EmuELEC, SD card Odroid Go
ArkOS, SD card RG353M, RG353V, RG503, RGB30, RK2023, RG351MP, RG351V, R35S, RGB10
CrossMix-OS, SD card TrimUI Smart Pro
dArkOS, SD card Odroid Go Advance, RGB10, RG351MP, G350
EmuELEC, SD card Odroid Go
JELOS, SD card RG351M, RG351V, RG353M, RG353P, RG353V, RG353VS, RG503, RG552, R33S, R36S, +24
KNULLI, SD card RG ARC-S, RG28XX, RG34XX, RG35XX, RG35XX Plus, RG35XX H, RG35XX 2024, +15
KOLOS, SD card RG353P, RG353M, RG353V, RG353VS, RG503, RK2023, RGB30, RGB10 Max 3
Koriki, SD card Miyoo Mini
KOLOS, SD card RG353P, RG353M, RG353V, RG353VS, RG503, RK2023, RGB30, RGB10 Max 3
Koriki, SD card Miyoo Mini
MinUI, SD card RG28XX, RG34XX, RG34XX SP, RG35XX, RG35XX Plus, RG35XX H, RG35XX SP, +16
MiyooCFW, SD card BittBoy, Pocket Go, PowKiddy Q90, PowKiddy V90, PowKiddy Q20 Mini, Sup M3, +1
muOS, SD card RG35XX H, RG35XX Plus, RG35XX SP, RG35XX 2024, RG34XX, RG40XX H, RG40XX V, +4
MyMinUI, SD card RG35XX, Miyoo Mini, Miyoo Mini Flip, Miyoo Mini Plus, Miyoo A30, +16
NextUI, SD card TrimUI Brick, TrimUI Smart Pro
Onion, SD card Miyoo Mini, Miyoo Mini Plus
plumOS, SD card MagicX XU20 V32
RetroOZ, SD card Odroid Go Super, Odroid Go Advance, RGB10 Max, RGB10 Max 2
NextUI, SD card TrimUI Brick, TrimUI Smart Pro
Onion, SD card Miyoo Mini, Miyoo Mini Plus
plumOS, SD card MagicX XU20 V32
RetroOZ, SD card Odroid Go Super, Odroid Go Advance, RGB10 Max, RGB10 Max 2
ROCKNIX, SD card RG351, RG353, RG503, RG552, RG 55G1, RG ARC, RG35XX 2024, RG35XX Plus, +37
spruceOS, SD card Miyoo A30, Miyoo Flip, Miyoo Mini, Miyoo Mini Plus, Miyoo Mini Flip, +5
UnofficialOS, SD card R35S, R36S, RG351M, RG351P, RG351V, RG353M, RG353P, RG353V, RG503, +5
+1 -1
View File
@@ -9,4 +9,4 @@
missing 16.0 KB gba_bios.bin
A/Enter Back
A Back
+1 -1
View File
@@ -12,4 +12,4 @@
A/Enter Back
A Back
+1 -1
View File
@@ -9,4 +9,4 @@
A/Enter Quit B/Esc Stay
A Quit B Stay
+1 -1
View File
@@ -12,4 +12,4 @@
A/Enter Quit B/Esc Stay
A Quit B Stay
+1 -1
View File
@@ -9,4 +9,4 @@
To put them back: python3 install.py
1-8 of 17
A/Enter Exit Up/Down Scroll
A Exit ^v Scroll
+1 -1
View File
@@ -12,4 +12,4 @@
/home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
1-11 of 17
A/Enter Exit Up/Down Scroll
A Exit ^v Scroll
+6 -138
View File
@@ -322,35 +322,6 @@
A Use this folder B Back
=== create 40x12
RetroBIOS: Create the folder?
/home/user/bios/new does not exist.
The nearest folder that does:
/home/user
> Create it and continue
Choose another folder
A Create B Quit
=== create 40x15
RetroBIOS: Create the folder?
/home/user/bios/new does not exist.
The nearest folder that does:
/home/user
> Create it and continue
Choose another folder
A Create B Quit
=== create 80x24
RetroBIOS: Create the folder?
@@ -604,7 +575,7 @@
Copy from: none
Preview the file list
Show the command line
A Open B Back Left/Right Set
A Open B Back <> Set
=== options 40x15
RetroBIOS: Options
@@ -620,7 +591,7 @@
Sets --region
A Open B Back Left/Right Set
A Open B Back <> Set
=== options 80x24
RetroBIOS: Options
@@ -658,7 +629,7 @@
[ ] Japan
A Tick B Done Left/Right Order
A Tick B Done <> Order
=== regions 40x15
RetroBIOS: Preferred regions
@@ -674,7 +645,7 @@
A Tick B Done Left/Right Order
A Tick B Done <> Order
=== regions 80x24
RetroBIOS: Preferred regions
@@ -754,35 +725,6 @@
A Filter B Back X Tick
=== preview 40x12
RetroBIOS: Preview
4 files to download, 1.0 MB. Nothing
is written.
missing 512.0 KB scph5500.bin
wrong copy 512.0 KB scph5501.bin
missing 4 B pcsx/extra.bin
missing 16.0 KB gba_bios.bin
A Back
=== preview 40x15
RetroBIOS: Preview
4 files to download, 1.0 MB. Nothing
is written.
missing 512.0 KB scph5500.bin
wrong copy 512.0 KB scph5501.bin
missing 4 B pcsx/extra.bin
missing 16.0 KB gba_bios.bin
A Back
=== preview 80x24
RetroBIOS: Preview
@@ -807,35 +749,6 @@
A Back
=== command 40x12
RetroBIOS: Command line
The same choice without questions:
python3 install.py --platform
retroarch --dest
/home/user/.config/retroarch/system
--system nintendo-gba
A Back
=== command 40x15
RetroBIOS: Command line
The same choice without questions:
python3 install.py --platform
retroarch --dest
/home/user/.config/retroarch/system
--system nintendo-gba
A Back
=== command 80x24
RetroBIOS: Command line
@@ -1032,27 +945,11 @@
-2] Name or service not known
Address:
https://raw.githubusercontent.com/
Abdess/retrobios/main/install/
retroarch.json
> Choose another setup or folder
Quit
A Choose B Back
=== error 40x15
RetroBIOS: Something went wrong
Could not fetch the file list for
retroarch after 3 attempts: [Errno
-2] Name or service not known
Address:
https://raw.githubusercontent.com/
Abdess/retrobios/main/install/
retroarch.json
1-5 of 7
> Choose another setup or folder
Quit
A Choose B Back
A Choose B Back L1/R1 Scroll
=== error 80x24
RetroBIOS: Something went wrong
@@ -1078,35 +975,6 @@
A Choose B Back
=== quit 40x12
RetroBIOS: Quit?
Quit without installing? Nothing was
written.
> Quit
Stay
A Quit B Stay
=== quit 40x15
RetroBIOS: Quit?
Quit without installing? Nothing was
written.
> Quit
Stay
A Quit B Stay
=== quit 80x24
RetroBIOS: Quit?
+6 -138
View File
@@ -322,35 +322,6 @@
A Use this folder B Back
=== create 40x12
RetroBIOS: Create the folder?
/home/user/bios/new does not exist.
The nearest folder that does:
/home/user
> Create it and continue
Choose another folder
A Create B Quit
=== create 40x15
RetroBIOS: Create the folder?
/home/user/bios/new does not exist.
The nearest folder that does:
/home/user
> Create it and continue
Choose another folder
A Create B Quit
=== create 80x24
RetroBIOS: Create the folder?
@@ -604,7 +575,7 @@
Copy from: none
Preview the file list
Show the command line
A Open B Back Left/Right Set
A Open B Back <> Set
=== options 40x15
RetroBIOS: Options
@@ -620,7 +591,7 @@
Sets --region
A Open B Back Left/Right Set
A Open B Back <> Set
=== options 80x24
RetroBIOS: Options
@@ -658,7 +629,7 @@
[ ] Japan
A Tick B Done Left/Right Order
A Tick B Done <> Order
=== regions 40x15
RetroBIOS: Preferred regions
@@ -674,7 +645,7 @@
A Tick B Done Left/Right Order
A Tick B Done <> Order
=== regions 80x24
RetroBIOS: Preferred regions
@@ -754,35 +725,6 @@
A Filter B Back X Tick
=== preview 40x12
RetroBIOS: Preview
4 files to download, 1.0 MB. Nothing
is written.
missing 512.0 KB scph5500.bin
wrong copy 512.0 KB scph5501.bin
missing 4 B pcsx/extra.bin
missing 16.0 KB gba_bios.bin
A Back
=== preview 40x15
RetroBIOS: Preview
4 files to download, 1.0 MB. Nothing
is written.
missing 512.0 KB scph5500.bin
wrong copy 512.0 KB scph5501.bin
missing 4 B pcsx/extra.bin
missing 16.0 KB gba_bios.bin
A Back
=== preview 80x24
RetroBIOS: Preview
@@ -807,35 +749,6 @@
A Back
=== command 40x12
RetroBIOS: Command line
The same choice without questions:
python3 install.py --platform
retroarch --dest
/home/user/.config/retroarch/system
--system nintendo-gba
A Back
=== command 40x15
RetroBIOS: Command line
The same choice without questions:
python3 install.py --platform
retroarch --dest
/home/user/.config/retroarch/system
--system nintendo-gba
A Back
=== command 80x24
RetroBIOS: Command line
@@ -1032,27 +945,11 @@
-2] Name or service not known
Address:
https://raw.githubusercontent.com/
Abdess/retrobios/main/install/
retroarch.json
> Choose another setup or folder
Quit
A Choose B Back
=== error 40x15
RetroBIOS: Something went wrong
Could not fetch the file list for
retroarch after 3 attempts: [Errno
-2] Name or service not known
Address:
https://raw.githubusercontent.com/
Abdess/retrobios/main/install/
retroarch.json
1-5 of 7
> Choose another setup or folder
Quit
A Choose B Back
A Choose B Back L1/R1 Scroll
=== error 80x24
RetroBIOS: Something went wrong
@@ -1078,35 +975,6 @@
A Choose B Back
=== quit 40x12
RetroBIOS: Quit?
Quit without installing? Nothing was
written.
> Quit
Stay
A Quit B Stay
=== quit 40x15
RetroBIOS: Quit?
Quit without installing? Nothing was
written.
> Quit
Stay
A Quit B Stay
=== quit 80x24
RetroBIOS: Quit?
+5 -137
View File
@@ -322,35 +322,6 @@
A Use this folder B Back
=== create 40x12
RetroBIOS: Create the folder?
/home/user/bios/new does not exist.
The nearest folder that does:
/home/user
> Create it and continue
Choose another folder
A Create B Quit
=== create 40x15
RetroBIOS: Create the folder?
/home/user/bios/new does not exist.
The nearest folder that does:
/home/user
> Create it and continue
Choose another folder
A Create B Quit
=== create 80x24
RetroBIOS: Create the folder?
@@ -604,7 +575,7 @@
Copy from: none
Preview the file list
Show the command line
A Open B Back Left/Right Set
A Open B Back <> Set
=== options 40x15
RetroBIOS: Options
@@ -620,7 +591,7 @@
Sets --region
A Open B Back Left/Right Set
A Open B Back <> Set
=== options 80x24
RetroBIOS: Options
@@ -658,7 +629,7 @@
[ ] Japan
A Tick B Done Left/Right Order
A Tick B Done <> Order
=== regions 40x15
RetroBIOS: Preferred regions
@@ -674,7 +645,7 @@
A Tick B Done Left/Right Order
A Tick B Done <> Order
=== regions 80x24
RetroBIOS: Preferred regions
@@ -754,35 +725,6 @@
A Filter B Back X Tick
=== preview 40x12
RetroBIOS: Preview
4 files to download, 1.0 MB. Nothing
is written.
missing 512.0 KB scph5500.bin
wrong copy 512.0 KB scph5501.bin
missing 4 B pcsx/extra.bin
missing 16.0 KB gba_bios.bin
A Back
=== preview 40x15
RetroBIOS: Preview
4 files to download, 1.0 MB. Nothing
is written.
missing 512.0 KB scph5500.bin
wrong copy 512.0 KB scph5501.bin
missing 4 B pcsx/extra.bin
missing 16.0 KB gba_bios.bin
A Back
=== preview 80x24
RetroBIOS: Preview
@@ -807,35 +749,6 @@
A Back
=== command 40x12
RetroBIOS: Command line
The same choice without questions:
python3 install.py --platform
retroarch --dest
/home/user/.config/retroarch/system
--system nintendo-gba
A Back
=== command 40x15
RetroBIOS: Command line
The same choice without questions:
python3 install.py --platform
retroarch --dest
/home/user/.config/retroarch/system
--system nintendo-gba
A Back
=== command 80x24
RetroBIOS: Command line
@@ -1032,26 +945,10 @@
-2] Name or service not known
Address:
https://raw.githubusercontent.com/
Abdess/retrobios/main/install/
retroarch.json
> Choose another setup or folder
Quit
A Choose B Back
=== error 40x15
RetroBIOS: Something went wrong
Could not fetch the file list for
retroarch after 3 attempts: [Errno
-2] Name or service not known
Address:
https://raw.githubusercontent.com/
Abdess/retrobios/main/install/
retroarch.json
1-5 of 7
> Choose another setup or folder
Quit
A Choose B Back
=== error 80x24
RetroBIOS: Something went wrong
@@ -1078,35 +975,6 @@
A Choose B Back
=== quit 40x12
RetroBIOS: Quit?
Quit without installing? Nothing was
written.
> Quit
Stay
A Quit B Stay
=== quit 40x15
RetroBIOS: Quit?
Quit without installing? Nothing was
written.
> Quit
Stay
A Quit B Stay
=== quit 80x24
RetroBIOS: Quit?
+4 -4
View File
@@ -928,7 +928,7 @@
To put them back: python3 install.py
1-8 of 17
Enter Exit Up/Down Scroll
Enter Exit ^v Scroll
=== result 40x15
RetroBIOS: Finished with errors
@@ -944,7 +944,7 @@
/home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
1-11 of 17
Enter Exit Up/Down Scroll
Enter Exit ^v Scroll
=== result 80x24
RetroBIOS: Finished with errors
@@ -978,8 +978,8 @@
-2] Name or service not known
Address:
https://raw.githubusercontent.com/
Abdess/retrobios/main/install/
retroarch.json
1-5 of 7
> Choose another setup or folder
Quit
Enter Choose Esc Back
+7 -65
View File
@@ -604,7 +604,7 @@
Copy from: none
Preview the file list
Show the command line
A Open R2 Back Left/Right Set
A Open R2 Back <> Set
=== options 40x15
RetroBIOS: Options
@@ -620,7 +620,7 @@
Sets --region
A Open R2 Back Left/Right Set
A Open R2 Back <> Set
=== options 80x24
RetroBIOS: Options
@@ -658,7 +658,7 @@
[ ] Japan
A Tick R2 Done Left/Right Order
A Tick R2 Done <> Order
=== regions 40x15
RetroBIOS: Preferred regions
@@ -674,7 +674,7 @@
A Tick R2 Done Left/Right Order
A Tick R2 Done <> Order
=== regions 80x24
RetroBIOS: Preferred regions
@@ -754,35 +754,6 @@
A Filter R2 Back
=== preview 40x12
RetroBIOS: Preview
4 files to download, 1.0 MB. Nothing
is written.
missing 512.0 KB scph5500.bin
wrong copy 512.0 KB scph5501.bin
missing 4 B pcsx/extra.bin
missing 16.0 KB gba_bios.bin
A Back
=== preview 40x15
RetroBIOS: Preview
4 files to download, 1.0 MB. Nothing
is written.
missing 512.0 KB scph5500.bin
wrong copy 512.0 KB scph5501.bin
missing 4 B pcsx/extra.bin
missing 16.0 KB gba_bios.bin
A Back
=== preview 80x24
RetroBIOS: Preview
@@ -807,35 +778,6 @@
A Back
=== command 40x12
RetroBIOS: Command line
The same choice without questions:
python3 install.py --platform
retroarch --dest
/home/user/.config/retroarch/system
--system nintendo-gba
A Back
=== command 40x15
RetroBIOS: Command line
The same choice without questions:
python3 install.py --platform
retroarch --dest
/home/user/.config/retroarch/system
--system nintendo-gba
A Back
=== command 80x24
RetroBIOS: Command line
@@ -1032,11 +974,11 @@
-2] Name or service not known
Address:
https://raw.githubusercontent.com/
Abdess/retrobios/main/install/
retroarch.json
1-5 of 7
> Choose another setup or folder
Quit
A Choose R2 Back
A Choose R2 Back L1/R1 Scroll
=== error 40x15
RetroBIOS: Something went wrong
+6 -6
View File
@@ -604,7 +604,7 @@
Copy from: none
Preview the file list
Show the command line
Start Open B Back Left/Right Set
Start Open B Back <> Set
=== options 40x15
RetroBIOS: Options
@@ -620,7 +620,7 @@
Sets --region
Start Open B Back Left/Right Set
Start Open B Back <> Set
=== options 80x24
RetroBIOS: Options
@@ -658,7 +658,7 @@
[ ] Japan
Start Tick B Done Left/Right Order
Start Tick B Done <> Order
=== regions 40x15
RetroBIOS: Preferred regions
@@ -674,7 +674,7 @@
Start Tick B Done Left/Right Order
Start Tick B Done <> Order
=== regions 80x24
RetroBIOS: Preferred regions
@@ -1032,8 +1032,8 @@
-2] Name or service not known
Address:
https://raw.githubusercontent.com/
Abdess/retrobios/main/install/
retroarch.json
1-5 of 7
> Choose another setup or folder
Quit
Start Choose B Back
+1 -1
View File
@@ -9,4 +9,4 @@
BIOS folder:
/home/user/.config/retroarch/system
ES-DE found: its BIOS files go to each
A/Enter Continue B/Esc Quit ? Help
A Continue B Quit ? Help
+1 -1
View File
@@ -12,4 +12,4 @@
emulator, not to ES-DE itself.
A/Enter Continue B/Esc Quit ? Help
A Continue B Quit ? Help
+3 -3
View File
@@ -3,9 +3,9 @@
All
None
Filter (/ to type)
> [x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
[ ] nintendo-famicom-disk (ファミコン) in place
> [x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
[ ] nintendo-famicom-disk (ファミコン) in place
+139 -9
View File
@@ -1013,7 +1013,7 @@ class Views(unittest.TestCase):
with self.subTest(screen=name):
hint = install.tui_view(state, 40, 15)[-1].strip()
self.assertTrue(hint.startswith(("A/Enter", "A ", "Enter", "Ctrl-C", "Any key",
"B/Esc Stop")), hint)
"B/Esc Stop", "B Stop")), hint)
def test_focus_is_marked_without_colour(self):
lines = install.tui_view(fresh_state(), 80, 24)
@@ -1030,12 +1030,12 @@ def _bar_keys(line: str) -> set:
# The keys each route has, as the bar may name them. "Any" opens "Any key
# closes this help", <> and ^v are the narrow forms of Left/Right, Up/Down.
ROUTE_KEYS = {
"keys": {"Enter", "Esc", "Space", "o", "?", "/", "Ctrl-C", "Ctrl-U"},
"gptokeyb": {"A", "B", "X", "Y", "Select+Start"},
"gptokeyb_muxterm": {"A", "B", "X", "Y", "Select+Start"},
"evmapy": {"A", "B", "X", "Y"},
"muxterm": {"Start", "B", "Y", "Menu", "Select"},
"miyoo": {"A", "Start", "R2", "L2"},
"keys": {"Enter", "Esc", "Space", "o", "?", "/", "Ctrl-C", "Ctrl-U", "PgUp/PgDn"},
"gptokeyb": {"A", "B", "X", "Y", "Select+Start", "L1/R1"},
"gptokeyb_muxterm": {"A", "B", "X", "Y", "Select+Start", "D-pad"},
"evmapy": {"A", "B", "X", "Y", "L1/R1"},
"muxterm": {"Start", "B", "Y", "Menu", "Select", "D-pad"},
"miyoo": {"A", "Start", "R2", "L2", "L1/R1"},
}
EVERY_ROUTE_HAS = {"Left/Right", "Up/Down", "<>", "^v", "Any"}
@@ -1628,7 +1628,11 @@ class AuditRoundTwo(unittest.TestCase):
kind, plat, title, lines, code = inbox.get_nowait()
self.assertEqual((kind, title, code), ("manifest_failed", "No connection", 1))
self.assertIn("could not be downloaded: the server refused the connection", lines[0])
self.assertNotIn("--", " ".join(lines))
# The pack is the one option named: the way of a handheld with no
# Wi-Fi (tui_audit_11 P3-3).
self.assertIn("Or copy a pack to the card and run the installer with --from-pack",
" ".join(lines))
self.assertNotIn("--", " ".join(lines).replace("--from-pack", ""))
state = fresh_state()
with mock.patch.object(install.Path, "exists", return_value=True):
press(state, "enter")
@@ -5803,7 +5807,8 @@ class AuditSix(unittest.TestCase):
self.assertNotIn("before Install", text)
self.assertNotIn("backup folder", text)
self.assertIn("Copy them from your old card", text)
self.assertEqual(view[-1].strip(), "A/Enter Back ? Help")
# The short names at 40 columns, as every screen of that width.
self.assertEqual(view[-1].strip(), "A Back ? Help")
def test_a_refusal_shows_at_40x12_on_type_a_path(self):
"""P2-2: Enter seemed to do nothing, the refusal drawn below the
@@ -9072,6 +9077,131 @@ class AuditEighteenAndEleven(unittest.TestCase):
rows = install.tui_rows(state)
self.assertEqual(rows[state.focus.get("plan", 0)].action, "fromcard")
# tui_audit_11 P3-2 to P3-20: the screens' polish.
def test_a_long_message_scrolls_with_its_position(self):
"""P3-2: at 40x12 the offline screen dropped its remedy unsaid."""
state = fresh_state()
state.stack = ["error"]
state.error_title = install.TUI_OFFLINE_TITLE
state.error = ["This run makes no network request (--offline), and the list of BIOS "
"files comes from the network.",
"Run the installer again with the list saved as a file (--manifest "
"FILE, a copy of install/<platform>.json) or with a pack (--from-pack "
"PACK), or without --offline."]
state.cols, state.rows = 40, 12
view = [str(line) for line in install.tui_view(state, 40, 12)]
self.assertTrue(any(re.fullmatch(r" 1-\d+ of \d+", line) for line in view), view)
self.assertIn("Scroll", view[-1])
press(state, "pgdn")
end = " ".join(" ".join(str(line) for line in install.tui_view(state, 40, 12)).split())
self.assertIn("--offline.", end)
def test_a_small_window_says_why_the_questions_come_line_by_line(self):
"""P3-4."""
with mock.patch.object(install, "tui_blocker",
return_value="the terminal is 39x12, smaller than 40x12"), \
mock.patch.object(install, "_run", side_effect=SystemExit(0)), \
mock.patch.object(install, "detect_os", return_value="linux"), \
mock.patch.dict(install._WSL), \
mock.patch.object(sys, "argv", ["install.py"]), \
contextlib.redirect_stdout(io.StringIO()) as out, \
self.assertRaises(SystemExit):
install.main()
self.assertIn("The window is 39x12: questions come line by line (40x12 for the full "
"screen).", out.getvalue())
def test_one_bar_rule_per_width(self):
"""P3-5: at 40 columns the plan read "A Install", Confirm "A/Enter"."""
states = golden_states()
for name in ("preview", "confirm", "result", "quit"):
with self.subTest(screen=name):
bar = str(install.tui_view(states[name], 40, 12)[-1])
self.assertNotIn("A/Enter", bar)
self.assertNotIn("B/Esc", bar)
def test_the_folder_its_config_named_is_said_under_it(self):
"""P3-6, P3-7."""
state = checked_state()
long_dest = Path("/home/user/" + "a-long-folder-name/" * 5 + "system")
state.dest = long_dest
with mock.patch.object(install, "_retroarch_config_at",
return_value=(HOME / ".config/retroarch/retroarch.cfg", HOME)):
lines = [str(line).strip() for line in install.tui_view(state, 80, 30)]
at = next(index for index, line in enumerate(lines) if line.startswith("BIOS folder:"))
tail = next(index for index, line in enumerate(lines) if line.startswith("Named by"))
self.assertNotIn("...", " ".join(lines[at:tail]))
self.assertIn(str(long_dest).replace("/home/user", "~")[-20:], " ".join(lines[at:tail]))
self.assertLessEqual(tail - at, 3)
def test_the_help_while_typing_lists_what_does_not_type(self):
"""P3-9."""
state = checked_state()
state.stack.append("systems")
state.editing = "systems"
state.help = True
help_text = " ".join(" ".join(install.tui_view(state, 80, 24)).split())
self.assertIn("Esc Clear the filter", help_text)
self.assertIn("Ctrl-U Clear", help_text)
self.assertNotIn("Tick, untick", help_text)
def test_the_plan_names_core_and_region_as_line_mode(self):
"""P3-11."""
state = checked_state()
state.cli_systems, state.cores, state.regions = ["sony-playstation"], ["x"], ["us"]
text = " ".join(" ".join(install.tui_view(state, 120, 40)).split())
self.assertIn("(--system), --core, --region.", text)
def test_pc_and_short_prefixes_find_the_computer_setups(self):
"""P3-17."""
for typed in ("pc", "wi", "win"):
with self.subTest(typed=typed):
found = {row.value for row in install.setup_list([], set(), typed, "linux")
if row.action == "platform"}
self.assertIn("retrobat", found)
def test_a_partial_result_counts_once_then_says_the_remedy(self):
"""P3-18."""
state = _installed_state(Path("/x/system"))
state.summary.update(installed=6, pending=16, failed=[])
state.from_folders = [Path("/media/me/OLD")]
with mock.patch.object(install, "_offline_only", return_value=True), \
mock.patch.object(install, "_tui_sources",
return_value="6 files copied from OLD, 16 still missing."):
_title, lines = install.tui_outcome(state)
self.assertEqual(lines[0], "6 files copied from OLD, 16 still missing.")
self.assertIn("They are not in", lines[1])
def test_q_is_said_as_a_quit(self):
"""P3-19: q reported "stopped", the word of an interrupted run."""
state = checked_state()
press(state, "q")
self.assertEqual(state.exit_code, 130)
self.assertEqual(install._closing_lines(state),
["RetroBIOS: quit. Nothing was installed."])
other = checked_state()
install.tui_interrupt(other)
self.assertEqual(install._closing_lines(other),
["RetroBIOS: stopped. Nothing was installed."])
def test_wide_rows_keep_the_size_near_the_name(self):
"""P3-20."""
row = install.TuiRow("system", "[x] 3DO 3do", "2 files, 4.9 KB")
line = str(install._row_line(row, False, 118))
self.assertLessEqual(len(line.rstrip()), install.TUI_ROW_SPREAD)
def test_the_wsl_browser_titles_a_drive_by_its_letter(self):
"""P3-13."""
state = fresh_state()
state.stack = ["browse"]
state.browse_dir = Path("/mnt/e")
with mock.patch.dict(install._WSL, {"active": True, "root": "/mnt"}), \
mock.patch.object(install, "_browse_rows", return_value=([], "")):
state.browse_rows = []
title = " ".join(str(line) for line in install.tui_view(state, 80, 24)[:4])
self.assertIn("E:\\", title)
self.assertNotIn("/mnt/e", title)
def test_the_card_marker_table_is_written_from_the_rules(self):
"""code_audit_18 P3-6, tui_audit_11 P2-2: the table left out the
SHARE drives. It is generated: every card rule and SHARE drive file
+1 -1
View File
@@ -1485,7 +1485,7 @@ fields, the installer refuses to narrow rather than install everything.
| `0` | everything asked for is installed or already up to date |
| `1` | a failure: the one-liner could not download or verify `install.py`, or found no Python 3.8 (nothing was run), an unusable base URL, an unknown platform or target, `--installed-cores` with no core found, a manifest that fails validation, a fetch that never succeeded, no platform to install for in a non-interactive run, some files failed or were left out by `--offline` while others installed, `--check` found files to fetch, a `--from-pack` pack that cannot be read, lacks a part or is for another platform, a `--from` folder that does not exist or cannot be read, a `--dest` that is not the card of the system named (another system's card, a folder inside one, a drive with none of its files where its card always has them, or a folder that does not exist), `--restore` could not put a file back, or `--add-app` could not put every file of the app on the card |
| `2` | nothing was installed: every file the run tried failed (a BIOS folder that cannot be written, for one), or `--offline` left every file out, the drive has too little free space for the download (checked before any folder is created), or the question about a folder that does not exist, named with `--dest` or typed at the folder question, was answered no. Also an option the installer refused before any download: an unknown option, `--jobs` outside 1 to 32, `--target` with `--every-board` or `--from-pack`, `--target` or `--list-targets` with `--offline` (or `RETROBIOS_INSTALL_OFFLINE` set), which read a core list from the network, `--add-app` with `--check`, `--dry-run`, a listing, `--from-pack` or `--offline`. The message then starts with `install.py: error:`. Also `--add-app` for a folder on no card that takes the app, said in an `Error:` line and an `app` event before anything is written. With `--restore`, a folder that is not a dated folder inside `retrobios-backup` |
| `130` | stopped with Ctrl+C, or with `q`, Ctrl+C or Ctrl+D at a question, or the full screen closed with no button pressed (`RETROBIOS_IDLE_EXIT`) before an install. Run the same command again to carry on |
| `130` | stopped with Ctrl+C, or with `q`, Ctrl+C or Ctrl+D at a question, or the full screen closed with no button pressed (`RETROBIOS_IDLE_EXIT`) before an install. A quit chosen (`q`, **Quit**) is code `130` too, and the terminal keeps `RetroBIOS: quit. Nothing was installed.` where a stop keeps `stopped`. Run the same command again to carry on |
| `141` | the output was piped to a reader that closed early (`--list-platforms \| head`) |
<!-- /generated: exit-codes -->