chore: audit 24 and 17 cases, host kept out

This commit is contained in:
Abdessamad Derraz committed 2026-11-03 10:45:18 +01:00
1 parent 6454de8772
commit 48fa8abf44
38 files changed
+1208 -544

No files matched your search

+1 -1
View File
@@ -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 = "403b6e8a7efcd24858b0f46ffa19c2b9012cdeef149768729d8e48d0b68a296a"
$defaultInstallSha256 = "a5713bf93a8b48b5649aa7040a429ec4ac2a2ae62b14b07eb6c91cb96c15d984"
$maximumInstallerBytes = 2MB
$installerExit = 0
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
+12 -2
View File
@@ -12164,8 +12164,12 @@ def card_setups() -> list[CardSetup]:
below = next((rule.bios[len(_card_mount(rule.bios)):] for rule in _EMBEDDED_RULES
if rule.name == name and rule.bios and _card_mount(rule.bios)), "")
if below:
setups.append(CardSetup(name, "retroarch", below,
tuple(rule for rule in rules if rule.name == name)))
own = tuple(rule for rule in rules if rule.name in (name, _built_on(name)))
# Told by the games part alone, as AmberELEC's: a card that holds
# none of it yet is taken as named, said so (tui_audit_17 P2-3).
setups.append(CardSetup(name, "retroarch", below, own,
bool(own) and all(rule.method == "games_part"
for rule in own)))
return setups
@@ -19173,7 +19177,13 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple:
for event in events}
held = [event for event in chosen if event["dest"] in took]
rest = len(chosen) - 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 (tui_audit_17 P3-5).
lines[0] = _styled(
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"{len(state.systems)} systems"
+1 -1
View File
@@ -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="403b6e8a7efcd24858b0f46ffa19c2b9012cdeef149768729d8e48d0b68a296a"
DEFAULT_INSTALL_SHA256="a5713bf93a8b48b5649aa7040a429ec4ac2a2ae62b14b07eb6c91cb96c15d984"
MAX_INSTALLER_BYTES=2097152
cleanup() {
+18 -18
View File
@@ -373,6 +373,7 @@
^[[0;1m ^[[0;1;32mEverything is in place^[[0m
BIOS folder: ^[[0;1m~/.config/retroarch/system^[[0m
^[[0;32m5 in place^[[0m, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced, the old one kept in a backup folder.
Free space: 50.0 GB
^[[0;7;35m > Close^[[0m
@@ -404,20 +405,19 @@
^[[0;1;35mA/Enter^[[0m Close ^[[0;2mB/Esc^[[0m Back ^[[0;2mY/o^[[0m Options ^[[0;2m?^[[0m Help
=== systems
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Choose systems^[[0m
Filter (/ to type)
[x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
^[[0;7;35m > [ ] nintendo-famicom-disk (ファミコン) in place^[[0m
All
None
Filter (/ to type)
^[[0;7;35m > [x] nintendo-gba (gba) 1 file, 16.0 KB^[[0m
[x] sony-playstation 3 files, 1.0 MB
^[[0;2m [ ] nintendo-famicom-disk (ファミコン) in place^[[0m
^[[0;32mDone^[[0m
@@ -448,7 +448,7 @@
^[[0;1m ^[[0;1;35m2^[[0;1m of ^[[0;1;35m3^[[0;1m systems: ^[[0;1;35m4^[[0;1m files, ^[[0;1;35m1.0 MB^[[0m
^[[0;1;35mA/Enter^[[0m Continue ^[[0;2mB/Esc^[[0m Back ^[[0;2mX/Space^[[0m Tick ^[[0;2m?^[[0m Help
^[[0;1;35mA/Enter^[[0m Tick ^[[0;2mB/Esc^[[0m Done ^[[0;2m?^[[0m Help
=== options
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Options^[[0m
@@ -498,8 +498,8 @@
^[[0;7;35m > [1] North America^[[0m
[ ] Japan
None
^[[0;32mDone^[[0m
@@ -534,14 +534,15 @@
=== cores
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Cores^[[0m
Every core ticked keeps every core's files. Untick the cores you do not use: the platform's own
files are always kept.
Untick the cores you do not use: the platform's own files are always kept, and a core with no
extra file reads only those.
^[[0;7;35m > All^[[0m
^[[0;7;35m > Filter (/ to type)^[[0m
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (/ to type)
[ ] mesen
[x] pcsx_rearmed
^[[0;32mDone^[[0m
@@ -570,8 +571,7 @@
^[[0;1;35mA/Enter^[[0m Tick all ^[[0;2mB/Esc^[[0m Back ^[[0;2mX/Space^[[0m Tick ^[[0;2m?^[[0m Help
^[[0;1;35mA/Enter^[[0m Filter ^[[0;2mB/Esc^[[0m Done ^[[0;2m?^[[0m Help
=== preview
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Preview^[[0m
@@ -742,6 +742,7 @@
^[[0;1m ^[[0;1;32m3 installed^[[0;1m, ^[[0;1;31m1 failed^[[0;1m.^[[0m
BIOS folder: ^[[0;1m/home/user/.config/retroarch/system^[[0m
^[[0;1;31mfailed:^[[0m scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in /home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
To put them back: python3 install.py \
--restore /home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
@@ -773,7 +774,6 @@
^[[0;1;35mA/Enter^[[0m Exit
+22 -22
View File
@@ -122,25 +122,25 @@
BIOS folder:
^[[0;1m~/.config/retroarch/system^[[0m
^[[0;32m5 in place^[[0m, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
^[[0;7;35m > Close^[[0m
Options
^[[0;1;35mA^[[0m Close ^[[0;2mB^[[0m Back ^[[0;2mY^[[0m Options ^[[0;2m?^[[0m Help
=== systems
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Choose systems^[[0m
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
^[[0;7;35m > [ ] nintendo-famicom-disk in place^[[0m
All
None
Filter (/ to type)
^[[0;7;35m > [x] nintendo-gba (gba) 16.0 KB^[[0m
[x] sony-playstation 1.0 MB
^[[0;2m [ ] nintendo-famicom-disk in place^[[0m
^[[0;2m 1-3 of 3^[[0m
nintendo-famicom-disk (ファミコン): in
place
^[[0;1m ^[[0;1;35m2^[[0;1m of ^[[0;1;35m3^[[0;1m systems: ^[[0;1;35m4^[[0;1m files, ^[[0;1;35m1.0 MB^[[0m
^[[0;1;35mA^[[0m Continue ^[[0;2mB^[[0m Back ^[[0;2mX^[[0m Tick ^[[0;2m?^[[0m Help
^[[0;1;35mA^[[0m Tick ^[[0;2mB^[[0m Done ^[[0;2m?^[[0m Help
=== options
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Options^[[0m
@@ -165,21 +165,21 @@
^[[0;7;35m > [1] North America^[[0m
[ ] Japan
^[[0;2m 1-2 of 2^[[0m
^[[0;1;35mA^[[0m Tick ^[[0;2mB^[[0m Done ^[[0;2m<>^[[0m Order ^[[0;2m?^[[0m Help
=== cores
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Cores^[[0m
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
^[[0;7;35m > All^[[0m
None
Filter (/ to type)
[ ] mesen
[x] pcsx_rearmed
^[[0;1;35mA^[[0m Tick all ^[[0;2mB^[[0m Back ^[[0;2mX^[[0m Tick ^[[0;2m?^[[0m Help
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
^[[0;7;35m > Filter (/ to type)^[[0m
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
^[[0;2m 1-2 of 2^[[0m
^[[0;1;35mA^[[0m Filter ^[[0;2mB^[[0m Done ^[[0;2m?^[[0m Help
=== preview
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Preview^[[0m
@@ -239,11 +239,11 @@
BIOS folder:
^[[0;1m/home/user/.config/retroarch/system^[[0m
^[[0;1;31mfailed:^[[0m scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
To put them back: python3 install.py \
^[[0;2m 1-8 of 16^[[0m
^[[0;2m 1-8 of 17^[[0m
^[[0;1;35mA^[[0m Exit ^[[0;2m^v^[[0m Scroll
=== error
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: ^[[0;1;31mSomething went wrong^[[0m
+24 -24
View File
@@ -149,31 +149,31 @@
BIOS folder:
^[[0;1m~/.config/retroarch/system^[[0m
^[[0;32m5 in place^[[0m, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
^[[0;7;35m > Close^[[0m
Options
^[[0;1;35mA^[[0m Close ^[[0;2mB^[[0m Back ^[[0;2mY^[[0m Options ^[[0;2m?^[[0m Help
=== systems
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Choose systems^[[0m
Filter (/ to type)
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
^[[0;7;35m > [ ] nintendo-famicom-disk in place^[[0m
All
None
Filter (/ to type)
^[[0;7;35m > [x] nintendo-gba (gba) 16.0 KB^[[0m
[x] sony-playstation 1.0 MB
^[[0;2m [ ] nintendo-famicom-disk in place^[[0m
^[[0;32mDone^[[0m
nintendo-famicom-disk (ファミコン): in
place
^[[0;1m ^[[0;1;35m2^[[0;1m of ^[[0;1;35m3^[[0;1m systems: ^[[0;1;35m4^[[0;1m files, ^[[0;1;35m1.0 MB^[[0m
^[[0;1;35mA^[[0m Continue ^[[0;2mB^[[0m Back ^[[0;2mX^[[0m Tick ^[[0;2m?^[[0m Help
^[[0;1;35mA^[[0m Tick ^[[0;2mB^[[0m Done ^[[0;2m?^[[0m Help
=== options
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Options^[[0m
@@ -201,27 +201,27 @@
^[[0;7;35m > [1] North America^[[0m
[ ] Japan
None
^[[0;32mDone^[[0m
^[[0;1;35mA^[[0m Tick ^[[0;2mB^[[0m Done ^[[0;2m<>^[[0m Order ^[[0;2m?^[[0m Help
=== cores
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Cores^[[0m
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
^[[0;7;35m > All^[[0m
^[[0;7;35m > Filter (/ to type)^[[0m
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (/ to type)
[ ] mesen
[x] pcsx_rearmed
^[[0;32mDone^[[0m
^[[0;1;35mA^[[0m Tick all ^[[0;2mB^[[0m Back ^[[0;2mX^[[0m Tick ^[[0;2m?^[[0m Help
^[[0;1;35mA^[[0m Filter ^[[0;2mB^[[0m Done ^[[0;2m?^[[0m Help
=== preview
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Preview^[[0m
@@ -293,14 +293,14 @@
BIOS folder:
^[[0;1m/home/user/.config/retroarch/system^[[0m
^[[0;1;31mfailed:^[[0m scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
To put them back: python3 install.py \
--restore .../2026-10-23_1200
^[[0;2m Shortened to fit this window.^[[0m
Same choice without questions:
^[[0;2m 1-11 of 16^[[0m
^[[0;2m 1-11 of 17^[[0m
^[[0;1;35mA^[[0m Exit ^[[0;2m^v^[[0m Scroll
=== error
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: ^[[0;1;31mSomething went wrong^[[0m
+18 -18
View File
@@ -229,6 +229,7 @@
^[[0;1m ^[[0;1;32mEverything is in place^[[0m
BIOS folder: ^[[0;1m~/.config/retroarch/system^[[0m
^[[0;32m5 in place^[[0m, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced, the old one kept in a backup folder.
Free space: 50.0 GB
^[[0;7;35m > Close^[[0m
@@ -246,18 +247,17 @@
^[[0;1;35mA/Enter^[[0m Close ^[[0;2mB/Esc^[[0m Back ^[[0;2mY/o^[[0m Options ^[[0;2m?^[[0m Help
=== systems
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Choose systems^[[0m
Filter (/ to type)
[x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
^[[0;7;35m > [ ] nintendo-famicom-disk (ファミコン) in place^[[0m
All
None
Filter (/ to type)
^[[0;7;35m > [x] nintendo-gba (gba) 1 file, 16.0 KB^[[0m
[x] sony-playstation 3 files, 1.0 MB
^[[0;2m [ ] nintendo-famicom-disk (ファミコン) in place^[[0m
^[[0;32mDone^[[0m
@@ -272,7 +272,7 @@
^[[0;1m ^[[0;1;35m2^[[0;1m of ^[[0;1;35m3^[[0;1m systems: ^[[0;1;35m4^[[0;1m files, ^[[0;1;35m1.0 MB^[[0m
^[[0;1;35mA/Enter^[[0m Continue ^[[0;2mB/Esc^[[0m Back ^[[0;2mX/Space^[[0m Tick ^[[0;2m?^[[0m Help
^[[0;1;35mA/Enter^[[0m Tick ^[[0;2mB/Esc^[[0m Done ^[[0;2m?^[[0m Help
=== options
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Options^[[0m
@@ -307,8 +307,8 @@
^[[0;7;35m > [1] North America^[[0m
[ ] Japan
None
^[[0;32mDone^[[0m
@@ -326,14 +326,15 @@
=== cores
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Cores^[[0m
Every core ticked keeps every core's files. Untick the cores you do not use:
the platform's own files are always kept.
Untick the cores you do not use: the platform's own files are always kept, and
a core with no extra file reads only those.
^[[0;7;35m > All^[[0m
^[[0;7;35m > Filter (/ to type)^[[0m
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (/ to type)
[ ] mesen
[x] pcsx_rearmed
^[[0;32mDone^[[0m
@@ -346,8 +347,7 @@
^[[0;1;35mA/Enter^[[0m Tick all ^[[0;2mB/Esc^[[0m Back ^[[0;2mX/Space^[[0m Tick ^[[0;2m?^[[0m Help
^[[0;1;35mA/Enter^[[0m Filter ^[[0;2mB/Esc^[[0m Done ^[[0;2m?^[[0m Help
=== preview
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Preview^[[0m
@@ -454,6 +454,7 @@
^[[0;1m ^[[0;1;32m3 installed^[[0;1m, ^[[0;1;31m1 failed^[[0;1m.^[[0m
BIOS folder: ^[[0;1m/home/user/.config/retroarch/system^[[0m
^[[0;1;31mfailed:^[[0m scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
To put them back: python3 install.py \
@@ -471,7 +472,6 @@
^[[0;1;35mA/Enter^[[0m Exit
=== error
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: ^[[0;1;31mSomething went wrong^[[0m
+8 -8
View File
@@ -1,13 +1,14 @@
RetroBIOS: Cores
Every core ticked keeps every core's files. Untick the cores you do not use: the platform's own
files are always kept.
Untick the cores you do not use: the platform's own files are always kept, and a core with no
extra file reads only those.
> All
> Filter (/ to type)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (/ to type)
[ ] mesen
[x] pcsx_rearmed
Done
@@ -36,5 +37,4 @@
A/Enter Tick all B/Esc Back X/Space Tick ? Help
A/Enter Filter B/Esc Done ? Help
+10 -10
View File
@@ -1,12 +1,12 @@
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
> All
None
Filter (/ to type)
[ ] mesen
[x] pcsx_rearmed
A Tick all B Back X Tick ? Help
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> Filter (/ to type)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
1-2 of 2
A Filter B Done ? Help
+10 -10
View File
@@ -1,15 +1,15 @@
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> All
> Filter (/ to type)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (/ to type)
[ ] mesen
[x] pcsx_rearmed
Done
A Tick all B Back X Tick ? Help
A Filter B Done ? Help
+8 -8
View File
@@ -1,13 +1,14 @@
RetroBIOS: Cores
Every core ticked keeps every core's files. Untick the cores you do not use:
the platform's own files are always kept.
Untick the cores you do not use: the platform's own files are always kept, and
a core with no extra file reads only those.
> All
> Filter (/ to type)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (/ to type)
[ ] mesen
[x] pcsx_rearmed
Done
@@ -20,5 +21,4 @@
A/Enter Tick all B/Esc Back X/Space Tick ? Help
A/Enter Filter B/Esc Done ? Help
+1 -1
View File
@@ -3,6 +3,7 @@
Everything is in place
BIOS folder: ~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced, the old one kept in a backup folder.
Free space: 50.0 GB
> Close
@@ -34,7 +35,6 @@
A/Enter Close B/Esc Back Y/o Options ? Help
+2 -2
View File
@@ -4,9 +4,9 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
A Close B Back Y Options ? Help
+2 -2
View File
@@ -4,12 +4,12 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
A Close B Back Y Options ? Help
+1 -1
View File
@@ -3,6 +3,7 @@
Everything is in place
BIOS folder: ~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced, the old one kept in a backup folder.
Free space: 50.0 GB
> Close
@@ -20,5 +21,4 @@
A/Enter Close B/Esc Back Y/o Options ? Help
+2 -2
View File
@@ -5,8 +5,8 @@
> [1] North America
[ ] Japan
None
Done
+1 -1
View File
@@ -8,5 +8,5 @@
> [1] North America
[ ] Japan
1-2 of 2
A Tick B Done <> Order ? Help
+2 -2
View File
@@ -8,8 +8,8 @@
> [1] North America
[ ] Japan
None
Done
A Tick B Done <> Order ? Help
+2 -2
View File
@@ -6,8 +6,8 @@
> [1] North America
[ ] Japan
None
Done
+1 -1
View File
@@ -3,6 +3,7 @@
3 installed, 1 failed.
BIOS folder: /home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in /home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
To put them back: python3 install.py \
--restore /home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
@@ -34,7 +35,6 @@
A/Enter Exit
+2 -2
View File
@@ -4,9 +4,9 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
To put them back: python3 install.py \
1-8 of 16
1-8 of 17
A Exit ^v Scroll
+2 -2
View File
@@ -4,12 +4,12 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
To put them back: python3 install.py \
--restore .../2026-10-23_1200
Shortened to fit this window.
Same choice without questions:
1-11 of 16
1-11 of 17
A Exit ^v Scroll
+1 -1
View File
@@ -3,6 +3,7 @@
3 installed, 1 failed.
BIOS folder: /home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
To put them back: python3 install.py \
@@ -20,5 +21,4 @@
A/Enter Exit
+62 -62
View File
@@ -462,11 +462,11 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
A Close B Back Y Options
=== plan-in-place 40x15
RetroBIOS: RetroArch
@@ -475,14 +475,14 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
A Close B Back Y Options
=== plan-in-place 80x24
RetroBIOS: RetroArch
@@ -490,6 +490,7 @@
Everything is in place
BIOS folder: ~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced, the old one kept in a backup folder.
Free space: 50.0 GB
> Close
@@ -507,47 +508,46 @@
A Close B Back Y Options
=== systems 40x12
RetroBIOS: Choose systems
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (with a keyboard)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
1-3 of 3
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
A Continue B Back X Tick
A Tick B Done
=== systems 40x15
RetroBIOS: Choose systems
Filter (with a keyboard)
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (with a keyboard)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
Done
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
A Continue B Back X Tick
A Tick B Done
=== systems 80x24
RetroBIOS: Choose systems
Filter (with a keyboard)
[x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
> [ ] nintendo-famicom-disk (ファミコン) in place
All
None
Filter (with a keyboard)
> [x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
[ ] nintendo-famicom-disk (ファミコン) in place
Done
@@ -562,7 +562,7 @@
2 of 3 systems: 4 files, 1.0 MB
A Continue B Back X Tick
A Tick B Done
=== options 40x12
RetroBIOS: Options
@@ -628,7 +628,7 @@
> [1] North America
[ ] Japan
1-2 of 2
A Tick B Done <> Order
=== regions 40x15
RetroBIOS: Preferred regions
@@ -641,8 +641,8 @@
> [1] North America
[ ] Japan
None
Done
A Tick B Done <> Order
@@ -655,8 +655,8 @@
> [1] North America
[ ] Japan
None
Done
@@ -674,43 +674,44 @@
=== cores 40x12
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
> All
None
Filter (with a keyboard)
[ ] mesen
[x] pcsx_rearmed
A Tick all B Back X Tick
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> Filter (with a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
1-2 of 2
A Filter B Done
=== cores 40x15
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> All
> Filter (with a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (with a keyboard)
[ ] mesen
[x] pcsx_rearmed
Done
A Tick all B Back X Tick
A Filter B Done
=== cores 80x24
RetroBIOS: Cores
Every core ticked keeps every core's files. Untick the cores you do not use:
the platform's own files are always kept.
Untick the cores you do not use: the platform's own files are always kept, and
a core with no extra file reads only those.
> All
> Filter (with a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (with a keyboard)
[ ] mesen
[x] pcsx_rearmed
Done
@@ -723,8 +724,7 @@
A Tick all B Back X Tick
A Filter B Done
=== preview 80x24
RetroBIOS: Preview
@@ -890,11 +890,11 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
Details: /tmp/retrobios-x/install.log
A Exit
=== result 40x15
RetroBIOS: Finished with errors
@@ -903,6 +903,7 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
@@ -910,7 +911,6 @@
A Exit
=== result 80x24
RetroBIOS: Finished with errors
@@ -918,6 +918,7 @@
3 installed, 1 failed.
BIOS folder: /home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
Details: /tmp/retrobios-x/install.log
@@ -935,7 +936,6 @@
A Exit
=== error 40x12
RetroBIOS: Something went wrong
+62 -62
View File
@@ -462,11 +462,11 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
A Close B Back Y Options
=== plan-in-place 40x15
RetroBIOS: RetroArch
@@ -475,14 +475,14 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
A Close B Back Y Options
=== plan-in-place 80x24
RetroBIOS: RetroArch
@@ -490,6 +490,7 @@
Everything is in place
BIOS folder: ~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced, the old one kept in a backup folder.
Free space: 50.0 GB
> Close
@@ -507,47 +508,46 @@
A Close B Back Y Options
=== systems 40x12
RetroBIOS: Choose systems
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (with a keyboard)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
1-3 of 3
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
A Continue B Back X Tick
A Tick B Done
=== systems 40x15
RetroBIOS: Choose systems
Filter (with a keyboard)
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (with a keyboard)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
Done
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
A Continue B Back X Tick
A Tick B Done
=== systems 80x24
RetroBIOS: Choose systems
Filter (with a keyboard)
[x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
> [ ] nintendo-famicom-disk (ファミコン) in place
All
None
Filter (with a keyboard)
> [x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
[ ] nintendo-famicom-disk (ファミコン) in place
Done
@@ -562,7 +562,7 @@
2 of 3 systems: 4 files, 1.0 MB
A Continue B Back X Tick
A Tick B Done
=== options 40x12
RetroBIOS: Options
@@ -628,7 +628,7 @@
> [1] North America
[ ] Japan
1-2 of 2
A Tick B Done <> Order
=== regions 40x15
RetroBIOS: Preferred regions
@@ -641,8 +641,8 @@
> [1] North America
[ ] Japan
None
Done
A Tick B Done <> Order
@@ -655,8 +655,8 @@
> [1] North America
[ ] Japan
None
Done
@@ -674,43 +674,44 @@
=== cores 40x12
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
> All
None
Filter (with a keyboard)
[ ] mesen
[x] pcsx_rearmed
A Tick all B Back X Tick
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> Filter (with a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
1-2 of 2
A Filter B Done
=== cores 40x15
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> All
> Filter (with a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (with a keyboard)
[ ] mesen
[x] pcsx_rearmed
Done
A Tick all B Back X Tick
A Filter B Done
=== cores 80x24
RetroBIOS: Cores
Every core ticked keeps every core's files. Untick the cores you do not use:
the platform's own files are always kept.
Untick the cores you do not use: the platform's own files are always kept, and
a core with no extra file reads only those.
> All
> Filter (with a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (with a keyboard)
[ ] mesen
[x] pcsx_rearmed
Done
@@ -723,8 +724,7 @@
A Tick all B Back X Tick
A Filter B Done
=== preview 80x24
RetroBIOS: Preview
@@ -890,11 +890,11 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
Details: /tmp/retrobios-x/install.log
A Exit
=== result 40x15
RetroBIOS: Finished with errors
@@ -903,6 +903,7 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
@@ -910,7 +911,6 @@
A Exit
=== result 80x24
RetroBIOS: Finished with errors
@@ -918,6 +918,7 @@
3 installed, 1 failed.
BIOS folder: /home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
Details: /tmp/retrobios-x/install.log
@@ -935,7 +936,6 @@
A Exit
=== error 40x12
RetroBIOS: Something went wrong
+62 -62
View File
@@ -462,11 +462,11 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
A Close B Back Y Options
=== plan-in-place 40x15
RetroBIOS: RetroArch
@@ -475,14 +475,14 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
A Close B Back Y Options
=== plan-in-place 80x24
RetroBIOS: RetroArch
@@ -490,6 +490,7 @@
Everything is in place
BIOS folder: ~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced, the old one kept in a backup folder.
Free space: 50.0 GB
> Close
@@ -507,47 +508,46 @@
A Close B Back Y Options
=== systems 40x12
RetroBIOS: Choose systems
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (with a keyboard)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
1-3 of 3
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
A Continue B Back X Tick
A Tick B Done
=== systems 40x15
RetroBIOS: Choose systems
Filter (with a keyboard)
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (with a keyboard)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
Done
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
A Continue B Back X Tick
A Tick B Done
=== systems 80x24
RetroBIOS: Choose systems
Filter (with a keyboard)
[x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
> [ ] nintendo-famicom-disk (ファミコン) in place
All
None
Filter (with a keyboard)
> [x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
[ ] nintendo-famicom-disk (ファミコン) in place
Done
@@ -562,7 +562,7 @@
2 of 3 systems: 4 files, 1.0 MB
A Continue B Back X Tick
A Tick B Done
=== options 40x12
RetroBIOS: Options
@@ -628,7 +628,7 @@
> [1] North America
[ ] Japan
1-2 of 2
A Tick B Done <> Order
=== regions 40x15
RetroBIOS: Preferred regions
@@ -641,8 +641,8 @@
> [1] North America
[ ] Japan
None
Done
A Tick B Done <> Order
@@ -655,8 +655,8 @@
> [1] North America
[ ] Japan
None
Done
@@ -674,43 +674,44 @@
=== cores 40x12
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
> All
None
Filter (with a keyboard)
[ ] mesen
[x] pcsx_rearmed
A Tick all B Back X Tick
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> Filter (with a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
1-2 of 2
A Filter B Done
=== cores 40x15
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> All
> Filter (with a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (with a keyboard)
[ ] mesen
[x] pcsx_rearmed
Done
A Tick all B Back X Tick
A Filter B Done
=== cores 80x24
RetroBIOS: Cores
Every core ticked keeps every core's files. Untick the cores you do not use:
the platform's own files are always kept.
Untick the cores you do not use: the platform's own files are always kept, and
a core with no extra file reads only those.
> All
> Filter (with a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (with a keyboard)
[ ] mesen
[x] pcsx_rearmed
Done
@@ -723,8 +724,7 @@
A Tick all B Back X Tick
A Filter B Done
=== preview 80x24
RetroBIOS: Preview
@@ -890,11 +890,11 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
Details: /tmp/retrobios-x/install.log
A Exit
=== result 40x15
RetroBIOS: Finished with errors
@@ -903,6 +903,7 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
@@ -910,7 +911,6 @@
A Exit
=== result 80x24
RetroBIOS: Finished with errors
@@ -918,6 +918,7 @@
3 installed, 1 failed.
BIOS folder: /home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
Details: /tmp/retrobios-x/install.log
@@ -935,7 +936,6 @@
A Exit
=== error 40x12
RetroBIOS: Something went wrong
+64 -64
View File
@@ -437,11 +437,11 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
Enter Close Esc Back o Options
=== plan-in-place 40x15
RetroBIOS: RetroArch
@@ -450,14 +450,14 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
Enter Close Esc Back o Options
=== plan-in-place 80x24
RetroBIOS: RetroArch
@@ -465,6 +465,7 @@
Everything is in place
BIOS folder: ~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced, the old one kept in a backup folder.
Free space: 50.0 GB
> Close
@@ -482,47 +483,46 @@
Enter Close Esc Back o Options ? Help
=== systems 40x12
RetroBIOS: Choose systems
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (/ to type)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
1-3 of 3
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
Enter Continue Esc Back Space Tick
Enter Tick Esc Done ? Help
=== systems 40x15
RetroBIOS: Choose systems
Filter (/ to type)
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (/ to type)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
Done
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
Enter Continue Esc Back Space Tick
Enter Tick Esc Done ? Help
=== systems 80x24
RetroBIOS: Choose systems
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
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
Done
@@ -537,7 +537,7 @@
2 of 3 systems: 4 files, 1.0 MB
Enter Continue Esc Back Space Tick ? Help
Enter Tick Esc Done ? Help
=== options 40x12
RetroBIOS: Options
@@ -603,7 +603,7 @@
> [1] North America
[ ] Japan
1-2 of 2
Enter Tick Esc Done <> Order ? Help
=== regions 40x15
RetroBIOS: Preferred regions
@@ -616,8 +616,8 @@
> [1] North America
[ ] Japan
None
Done
Enter Tick Esc Done <> Order ? Help
@@ -630,8 +630,8 @@
> [1] North America
[ ] Japan
None
Done
@@ -649,43 +649,44 @@
=== cores 40x12
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
> All
None
Filter (/ to type)
[ ] mesen
[x] pcsx_rearmed
Enter Tick all Esc Back Space Tick
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> Filter (/ to type)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
1-2 of 2
Enter Filter Esc Done ? Help
=== cores 40x15
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> All
> Filter (/ to type)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (/ to type)
[ ] mesen
[x] pcsx_rearmed
Done
Enter Tick all Esc Back Space Tick
Enter Filter Esc Done ? Help
=== cores 80x24
RetroBIOS: Cores
Every core ticked keeps every core's files. Untick the cores you do not use:
the platform's own files are always kept.
Untick the cores you do not use: the platform's own files are always kept, and
a core with no extra file reads only those.
> All
> Filter (/ to type)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (/ to type)
[ ] mesen
[x] pcsx_rearmed
Done
@@ -698,8 +699,7 @@
Enter Tick all Esc Back Space Tick ? Help
Enter Filter Esc Done ? Help
=== preview 40x12
RetroBIOS: Preview
@@ -923,11 +923,11 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
To put them back: python3 install.py \
1-8 of 16
1-8 of 17
Enter Exit ^v Scroll
=== result 40x15
RetroBIOS: Finished with errors
@@ -936,14 +936,14 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
To put them back: python3 install.py \
--restore .../2026-10-23_1200
Shortened to fit this window.
Same choice without questions:
1-11 of 16
1-11 of 17
Enter Exit ^v Scroll
=== result 80x24
RetroBIOS: Finished with errors
@@ -951,6 +951,7 @@
3 installed, 1 failed.
BIOS folder: /home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
To put them back: python3 install.py \
@@ -968,7 +969,6 @@
Enter Exit
=== error 40x12
RetroBIOS: Something went wrong
+62 -62
View File
@@ -491,11 +491,11 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
A Close R2 Back L2 Options
=== plan-in-place 40x15
RetroBIOS: RetroArch
@@ -504,14 +504,14 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
A Close R2 Back L2 Options
=== plan-in-place 80x24
RetroBIOS: RetroArch
@@ -519,6 +519,7 @@
Everything is in place
BIOS folder: ~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced, the old one kept in a backup folder.
Free space: 50.0 GB
> Close
@@ -536,47 +537,46 @@
A Close R2 Back L2 Options
=== systems 40x12
RetroBIOS: Choose systems
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (with a keyboard)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
1-3 of 3
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
Start Continue A Tick R2 Back
A Tick R2 Done
=== systems 40x15
RetroBIOS: Choose systems
Filter (with a keyboard)
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (with a keyboard)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
Done
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
Start Continue A Tick R2 Back
A Tick R2 Done
=== systems 80x24
RetroBIOS: Choose systems
Filter (with a keyboard)
[x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
> [ ] nintendo-famicom-disk (ファミコン) in place
All
None
Filter (with a keyboard)
> [x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
[ ] nintendo-famicom-disk (ファミコン) in place
Done
@@ -591,7 +591,7 @@
2 of 3 systems: 4 files, 1.0 MB
Start Continue A Tick R2 Back
A Tick R2 Done
=== options 40x12
RetroBIOS: Options
@@ -657,7 +657,7 @@
> [1] North America
[ ] Japan
1-2 of 2
A Tick R2 Done <> Order
=== regions 40x15
RetroBIOS: Preferred regions
@@ -670,8 +670,8 @@
> [1] North America
[ ] Japan
None
Done
A Tick R2 Done <> Order
@@ -684,8 +684,8 @@
> [1] North America
[ ] Japan
None
Done
@@ -703,43 +703,44 @@
=== cores 40x12
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
> All
None
Filter (with a keyboard)
[ ] mesen
[x] pcsx_rearmed
A Tick all R2 Back
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> Filter (with a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
1-2 of 2
A Filter R2 Done
=== cores 40x15
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> All
> Filter (with a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (with a keyboard)
[ ] mesen
[x] pcsx_rearmed
Done
A Tick all R2 Back
A Filter R2 Done
=== cores 80x24
RetroBIOS: Cores
Every core ticked keeps every core's files. Untick the cores you do not use:
the platform's own files are always kept.
Untick the cores you do not use: the platform's own files are always kept, and
a core with no extra file reads only those.
> All
> Filter (with a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (with a keyboard)
[ ] mesen
[x] pcsx_rearmed
Done
@@ -752,8 +753,7 @@
A Tick all R2 Back
A Filter R2 Done
=== preview 80x24
RetroBIOS: Preview
@@ -919,11 +919,11 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
Details: /tmp/retrobios-x/install.log
A Exit
=== result 40x15
RetroBIOS: Finished with errors
@@ -932,6 +932,7 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
@@ -939,7 +940,6 @@
A Exit
=== result 80x24
RetroBIOS: Finished with errors
@@ -947,6 +947,7 @@
3 installed, 1 failed.
BIOS folder: /home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
Details: /tmp/retrobios-x/install.log
@@ -964,7 +965,6 @@
A Exit
=== error 40x12
RetroBIOS: Something went wrong
+62 -62
View File
@@ -491,11 +491,11 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
Start Close B Back
=== plan-in-place 40x15
RetroBIOS: RetroArch
@@ -504,14 +504,14 @@
BIOS folder:
~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced,
the old one kept in a backup folder.
Free space: 50.0 GB
> Close
Options
Start Close B Back
=== plan-in-place 80x24
RetroBIOS: RetroArch
@@ -519,6 +519,7 @@
Everything is in place
BIOS folder: ~/.config/retroarch/system
5 in place, 0 missing, 0 wrong copies
1 of the 0 wrong copies is replaced, the old one kept in a backup folder.
Free space: 50.0 GB
> Close
@@ -536,47 +537,46 @@
Start Close B Back
=== systems 40x12
RetroBIOS: Choose systems
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (Select shows a keyboard)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
1-3 of 3
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
Start Continue B Back Y Tick
Start Tick B Done
=== systems 40x15
RetroBIOS: Choose systems
Filter (Select shows a keyboard)
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (Select shows a keyboard)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
Done
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
Start Continue B Back Y Tick
Start Tick B Done
=== systems 80x24
RetroBIOS: Choose systems
Filter (Select shows a keyboard)
[x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
> [ ] nintendo-famicom-disk (ファミコン) in place
All
None
Filter (Select shows a keyboard)
> [x] nintendo-gba (gba) 1 file, 16.0 KB
[x] sony-playstation 3 files, 1.0 MB
[ ] nintendo-famicom-disk (ファミコン) in place
Done
@@ -591,7 +591,7 @@
2 of 3 systems: 4 files, 1.0 MB
Start Continue B Back Y Tick
Start Tick B Done
=== options 40x12
RetroBIOS: Options
@@ -657,7 +657,7 @@
> [1] North America
[ ] Japan
1-2 of 2
Start Tick B Done <> Order
=== regions 40x15
RetroBIOS: Preferred regions
@@ -670,8 +670,8 @@
> [1] North America
[ ] Japan
None
Done
Start Tick B Done <> Order
@@ -684,8 +684,8 @@
> [1] North America
[ ] Japan
None
Done
@@ -703,43 +703,44 @@
=== cores 40x12
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
> All
None
Filter (Select shows a keyboard)
[ ] mesen
[x] pcsx_rearmed
Start Tick all B Back Y Tick
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> Filter (Select shows a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
1-2 of 2
Start Filter B Done
=== cores 40x15
RetroBIOS: Cores
Every core ticked keeps every core's
files. Untick the cores you do not
use: the platform's own files are
always kept.
Untick the cores you do not use: the
platform's own files are always
kept, and a core with no extra file
reads only those.
> All
> Filter (Select shows a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (Select shows a keyboard)
[ ] mesen
[x] pcsx_rearmed
Done
Start Tick all B Back Y Tick
Start Filter B Done
=== cores 80x24
RetroBIOS: Cores
Every core ticked keeps every core's files. Untick the cores you do not use:
the platform's own files are always kept.
Untick the cores you do not use: the platform's own files are always kept, and
a core with no extra file reads only those.
> All
> Filter (Select shows a keyboard)
[ ] mesen 1 file, 8.0 KB
[x] pcsx_rearmed 1 file, 4 B
All
None
Filter (Select shows a keyboard)
[ ] mesen
[x] pcsx_rearmed
Done
@@ -752,8 +753,7 @@
Start Tick all B Back Y Tick
Start Filter B Done
=== preview 40x12
RetroBIOS: Preview
@@ -977,11 +977,11 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
Details: /tmp/retrobios-x/install.log
Start Exit
=== result 40x15
RetroBIOS: Finished with errors
@@ -990,6 +990,7 @@
BIOS folder:
/home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/
retrobios-backup/2026-10-23_1200
@@ -997,7 +998,6 @@
Start Exit
=== result 80x24
RetroBIOS: Finished with errors
@@ -1005,6 +1005,7 @@
3 installed, 1 failed.
BIOS folder: /home/user/.config/retroarch/system
failed: scph5500.bin (HTTP 404)
Run it again to retry only those.
The files it replaced are kept in
/home/user/.config/retroarch/retrobios-backup/2026-10-23_1200
Details: /tmp/retrobios-x/install.log
@@ -1022,7 +1023,6 @@
Start Exit
=== error 40x12
RetroBIOS: Something went wrong
+6 -6
View File
@@ -1,12 +1,12 @@
RetroBIOS: Choose systems
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
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
Done
@@ -37,4 +37,4 @@
2 of 3 systems: 4 files, 1.0 MB
A/Enter Continue B/Esc Back X/Space Tick ? Help
A/Enter Tick B/Esc Done ? Help
+7 -7
View File
@@ -1,12 +1,12 @@
RetroBIOS: Choose systems
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (/ to type)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
1-3 of 3
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
A Continue B Back X Tick ? Help
A Tick B Done ? Help
+8 -8
View File
@@ -1,15 +1,15 @@
RetroBIOS: Choose systems
Filter (/ to type)
[x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
> [ ] nintendo-famicom-disk in place
All
None
Filter (/ to type)
> [x] nintendo-gba (gba) 16.0 KB
[x] sony-playstation 1.0 MB
[ ] nintendo-famicom-disk in place
Done
nintendo-famicom-disk (ファミコン): in
place
2 of 3 systems: 4 files, 1.0 MB
A Continue B Back X Tick ? Help
A Tick B Done ? Help
+6 -6
View File
@@ -1,12 +1,12 @@
RetroBIOS: Choose systems
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
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
Done
@@ -21,4 +21,4 @@
2 of 3 systems: 4 files, 1.0 MB
A/Enter Continue B/Esc Back X/Space Tick ? Help
A/Enter Tick B/Esc Done ? Help
+33
View File
@@ -0,0 +1,33 @@
"""The guard a test module turns on for itself and the Python it starts
(sitecustomize). module_guard() gives the setUpModule and tearDownModule
pair: the module fails at its end when anything tried to leave the loopback."""
from __future__ import annotations
import os
from pathlib import Path
from typing import Callable
from .sitecustomize import disable, enable, refused
__all__ = ["module_guard", "enable", "disable", "refused"]
def module_guard(name: str) -> tuple[Callable[[], None], Callable[[], None]]:
log = Path(__file__).resolve().parents[2] / "tmp" / "tests" / f"netlog-{name}-{os.getpid()}"
state: dict = {}
def set_up() -> None:
log.parent.mkdir(parents=True, exist_ok=True)
state["before"] = enable(str(log))
def tear_down() -> None:
disable(state.pop("before", {}))
tried = refused(str(log))
log.unlink(missing_ok=True)
if tried:
raise AssertionError(
f"{len(tried)} connections off the loopback during {name} (pid host): "
+ ", ".join(tried[:10]))
return set_up, tear_down
+133
View File
@@ -0,0 +1,133 @@
"""The machine running the installer tests, kept out of them.
Python imports this module at start in every process a test starts with
tests/netguard on PYTHONPATH (enable), and the test module
calls guard() for its own process. Two things the host has never reach a
test: a connection off the loopback, which is refused (OSError, as a network
that is down) and written to RETROBIOS_TEST_NETLOG, and the cards and drives
mounted under /media, /run/media, /mnt and /Volumes, which read as folders
no drive is mounted on. A test module passed on a machine with no network
and no card, and failed with an AmberELEC card in the reader, while 261
connections to GitHub left the module in a run (code_audit_24 P3-13).
"""
from __future__ import annotations
import errno
import os
import socket
import sys
LOOPBACK = frozenset({"127.0.0.1", "::1", "localhost", "0.0.0.0", ""})
MOUNT_ROOTS = ("/media", "/run/media", "/mnt", "/Volumes")
NETLOG = "RETROBIOS_TEST_NETLOG"
# What guard() replaced, for unguard().
_SAVED: dict = {}
def _refuse(host: object) -> None:
where = os.environ.get(NETLOG)
if where:
with open(where, "a", encoding="utf-8") as log:
log.write(f"{os.getpid()} {host} {' '.join(sys.argv)[:300]}\n")
raise OSError(errno.ENETUNREACH, f"a test makes no request to {host}")
def guard() -> None:
"""Refuse every connection off the loopback, hide the host's mounts."""
if _SAVED:
return
_SAVED.update(connect=socket.socket.__dict__.get("connect"),
connect_ex=socket.socket.__dict__.get("connect_ex"),
getaddrinfo=socket.getaddrinfo, ismount=os.path.ismount)
connect = socket.socket.connect
connect_ex = socket.socket.connect_ex
getaddrinfo = socket.getaddrinfo
def host_of(address: object) -> object:
return address[0] if isinstance(address, tuple) and address else None
def checked(sock: socket.socket, address: object) -> None:
if sock.family in (socket.AF_INET, socket.AF_INET6) and \
host_of(address) not in LOOPBACK:
_refuse(host_of(address))
def guarded_connect(self: socket.socket, address: object) -> None:
checked(self, address)
return connect(self, address)
def guarded_connect_ex(self: socket.socket, address: object) -> int:
checked(self, address)
return connect_ex(self, address)
def guarded_getaddrinfo(host: object, *args: object, **kwargs: object) -> list:
if host is not None and str(host) not in LOOPBACK:
_refuse(host)
return getaddrinfo(host, *args, **kwargs)
socket.socket.connect = guarded_connect # type: ignore[method-assign]
socket.socket.connect_ex = guarded_connect_ex # type: ignore[method-assign]
socket.getaddrinfo = guarded_getaddrinfo # type: ignore[assignment]
ismount = os.path.ismount
def guarded_ismount(path: object) -> bool:
text = os.fspath(path) if not isinstance(path, str) else path
if isinstance(text, bytes):
text = text.decode(errors="replace")
if any(text == root or text.startswith(root + "/") for root in MOUNT_ROOTS):
return False
return ismount(path)
os.path.ismount = guarded_ismount # type: ignore[assignment]
def unguard() -> None:
"""The process as it was before guard()."""
if not _SAVED:
return
for name in ("connect", "connect_ex"):
if _SAVED[name] is None:
delattr(socket.socket, name)
else:
setattr(socket.socket, name, _SAVED[name])
socket.getaddrinfo = _SAVED["getaddrinfo"]
os.path.ismount = _SAVED["ismount"]
_SAVED.clear()
def enable(log: str) -> dict:
"""Guard this process and every Python it starts, the refusals written
to log. Returns the variables it changed, for disable()."""
before = {name: os.environ.get(name) for name in ("PYTHONPATH", NETLOG)}
here = os.path.dirname(os.path.abspath(__file__))
paths = [here, *[p for p in os.environ.get("PYTHONPATH", "").split(os.pathsep) if p]]
os.environ["PYTHONPATH"] = os.pathsep.join(dict.fromkeys(paths))
os.environ[NETLOG] = log
with open(log, "w", encoding="utf-8"):
pass
guard()
return before
def disable(before: dict) -> None:
"""This process and the Python it starts as before enable()."""
unguard()
for name, value in before.items():
if value is None:
os.environ.pop(name, None)
else:
os.environ[name] = value
def refused(log: str) -> list[str]:
"""The connections refused since enable(log), one line each."""
try:
with open(log, encoding="utf-8") as text:
return [line.strip() for line in text if line.strip()]
except OSError:
return []
if os.environ.get(NETLOG):
guard()
+53
View File
@@ -175,6 +175,59 @@ class InstallerOutputExample(unittest.TestCase):
self.assertLessEqual(abs(added - float(total) * units[unit]), 0.15 * units[unit])
class InstallerSamplesSayWhatTheCodePrints(unittest.TestCase):
"""code_audit_24 P3-8 to P3-12: samples typed by hand outside the
generated blocks, a sentence on a log read as the terminal's, pages that
described the generator as tables alone, and a sandbox that asked DNS."""
def test_the_refused_and_from_samples_are_generated(self):
import install
page = _page("installer.md")
refused = _generated(page, "check-refused")
self.assertRegex(refused, r"\n \d+ files? [a-z ]+:\n")
self.assertIn("read by beetle_psx, pcsx_rearmed at", refused)
self.assertNotIn("opened at", page)
self.assertIn('"read by ', inspect.getsource(install.opened_line))
ending = _generated(page, "from-run")
self.assertRegex(ending, r"Done\. \d+ files installed\.\n \d+ files copied from ")
self.assertNotIn("a line under\n`Done`", page)
self.assertNotIn("38 files copied from E:\\, 4 downloaded", page)
def test_one_line_per_file_is_said_of_a_log(self):
page = _page("installer.md")
at = page.index("<!-- generated: run-download -->")
before = page[page.rindex("\n\n", 0, at - 2):at]
self.assertIn("At a terminal one progress line", before)
self.assertIn("A pipe or a log gets one line per file", before)
def test_the_generator_pages_name_the_run_samples_and_step_7(self):
tools = _page("tools.md")
row = next(line for line in tools.splitlines()
if line.startswith("| `generate_installer_doc.py`"))
self.assertIn("run samples", row)
self.assertIn("generate_installer_doc.py", next(
line for line in tools.splitlines() if line.startswith("| 7 |")))
self.assertIn("run samples", _page("installer.md").split(
"The tables of options, events, exit codes, keys and card markers", 1)[1][:600])
self.assertIn("generate_installer_doc.py", next(
line for line in _page("adding-a-platform.md").splitlines()
if line.startswith("7. ")))
def test_the_sandbox_looks_nothing_up(self):
import socket
from unittest import mock
import generate_installer_doc
def no_lookup(*_args: object) -> str:
raise AssertionError("the sandbox asked for a name")
with mock.patch.object(socket, "getfqdn", no_lookup), \
generate_installer_doc.Sandbox() as box:
self.assertEqual(box.server.server_name, "127.0.0.1")
class OneResolutionChain(unittest.TestCase):
"""architecture.md drew path_suffix as the first step, before SHA1, while
the code and verification-modes.md try it after every hash."""
+7
View File
@@ -31,6 +31,13 @@ _spec = importlib.util.spec_from_file_location("install", REPO_ROOT / "install.p
install = importlib.util.module_from_spec(_spec)
_spec.loader.exec_module(install)
sys.path.insert(0, str(REPO_ROOT / "tests"))
from netguard import module_guard # noqa: E402
# No connection off the loopback and no card of the host reaches a test
# (code_audit_24 P3-13): the module fails at its end otherwise.
setUpModule, tearDownModule = module_guard("test_install")
def _tempdir(test: unittest.TestCase) -> str:
"""A scratch directory under the repository's tmp/, removed after the test.
+430 -2
View File
@@ -35,7 +35,7 @@ import types
import unittest
import warnings
import zipfile
from pathlib import Path, PureWindowsPath
from pathlib import Path, PurePosixPath, PureWindowsPath
from unittest import mock
REPO_ROOT = Path(__file__).resolve().parent.parent
@@ -45,6 +45,13 @@ sys.path.insert(0, str(REPO_ROOT / "tests"))
import install # noqa: E402
from test_install_app import make_card # noqa: E402
from test_install_selection import FakeRepository, _QuietHandler # noqa: E402
from netguard import module_guard # noqa: E402
# No connection off the loopback and no card of the host reaches a test, in
# this process or one it starts (code_audit_24 P3-13): 261 connections to
# GitHub left this module in a run, and two tests failed with an AmberELEC
# card in the reader. The module fails at its end when one is tried.
setUpModule, tearDownModule = module_guard("test_install_tui")
try:
import pyte
@@ -5801,9 +5808,15 @@ def _card_from_rules(root: Path, setup: install.CardSetup) -> Path:
(root / path).parent.mkdir(parents=True, exist_ok=True)
(root / path).write_text(text + "\n", encoding="utf-8")
continue
if rule.method == "games_part":
# What the system writes beside its bios folder on that part.
(root / "bios").mkdir(exist_ok=True)
for value in rule.values:
(root / value).parent.mkdir(parents=True, exist_ok=True)
(root / value).write_text("", encoding="utf-8")
if rule.method == "games_part" and "." not in PurePosixPath(value).name:
(root / value).mkdir(exist_ok=True)
else:
(root / value).write_text("", encoding="utf-8")
return root
@@ -13970,5 +13983,420 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase):
words.index(install.TUI_INSTALL_ROW))
def core_list(path: Path, files: list) -> Path:
path.write_text(json.dumps({"manifest_version": 2, "platform": "retroarch",
"categorized": True, "base_destination": "system",
"save_directory": {"folder": "saves", "by_core": True},
"files": files}), encoding="utf-8")
return path
class AuditTwentyFourAndSeventeen(unittest.TestCase):
"""code_audit_24 and tui_audit_17: the cores the run accepts, one tick
list, a folder failure said as it happened, every proven card named,
reads that show, and tests that leave the host alone."""
setUp = LineModeAndScreenDecideAlike.setUp
line_run = LineModeAndScreenDecideAlike.line_run
entry = staticmethod(LineModeAndScreenDecideAlike.entry)
drive = AuditTwentyTwoAndFifteen.drive
first_screen = AuditTwentyTwoAndFifteen.first_screen
line_from = AuditTwentyThreeAndSixteen.line_from
# Root cause 1: the cores a choice is made among are the run's.
def files(self) -> list:
entry = self.entry
return [
entry("scph5501.bin", b"S" * 8, ["sony-playstation"]),
entry("pcsx/extra.bin", b"P" * 4, ["sony-playstation"], cores=["pcsx_rearmed"]),
entry("fc/disksys.rom", b"F" * 8, ["nintendo-famicom-disk"], cores=["mesen"]),
# Read from the save directory alone: set aside where it is not known.
entry("3ds/aes_keys.txt", b"K" * 4, ["nintendo-3ds"], cores=["azahar"],
root="save"),
# Game data alone: --no-game-data leaves its core no file.
entry("quake/pak0.pak", b"Q" * 4, ["other"], cores=["tyrquake"],
category="game_data"),
]
def check_events(self, *extra: str) -> list:
listing = core_list(self.root / "cores.json", self.files())
dest = self.root / "dest"
dest.mkdir(exist_ok=True)
done = install_run("--platform", "retroarch", "--dest", str(dest), "--manifest",
str(listing), "--check", "--events", *extra,
env={"HOME": str(self.root / "home"),
"RETROBIOS_INSTALL_OFFLINE": "1"})
return [json.loads(line) for line in done.stdout.splitlines() if line.startswith("{")]
def cores_state(self, events: list, no_game_data: bool = False) -> install.TuiState:
state = checked_state()
state.manifest = {"manifest_version": 2, "platform": "retroarch", "categorized": True,
"files": self.files()}
state.set_aside = set(next(event for event in events
if event["event"] == "set_aside")["dests"])
state.no_game_data = no_game_data
return state
def test_cores_lists_what_the_run_accepts_and_an_untick_runs(self):
"""tui_audit_17 P1-1: Cores listed 189 cores where --core accepted 181,
and an untick sent the 8 save-folder-only cores: "unknown core"."""
events = self.check_events()
self.assertEqual(next(e for e in events if e["event"] == "set_aside")["dests"],
["3ds/aes_keys.txt"])
state = self.cores_state(events)
self.assertNotIn("azahar", install.tui_choices(state)["cores"])
state.stack = ["setup", "plan", "options", "cores"]
row = next(r for r in install.tui_rows(state) if r.value == "mesen")
install._tick(state, row, False)
cores = [value for flag, value in install.tui_flags(state) if flag == "--core"]
self.assertEqual(sorted(cores), ["pcsx_rearmed", "tyrquake"])
listing = self.root / "cores.json"
done = install_run("--platform", "retroarch", "--dest", str(self.root / "dest"),
"--manifest", str(listing), "--dry-run",
*[f"--core={core}" for core in cores],
env={"HOME": str(self.root / "home"),
"RETROBIOS_INSTALL_OFFLINE": "1"})
self.assertNotIn("unknown core", done.stdout + done.stderr)
def test_both_modes_count_out_of_the_cores_the_run_keeps(self):
"""code_audit_24 P3-3: line mode said "1 of 181 cores", the screen
"1 of 189", and 22 more under --no-game-data."""
for no_game_data in (False, True):
with self.subTest(no_game_data=no_game_data):
extra = ("--no-game-data",) if no_game_data else ()
state = self.cores_state(self.check_events(*extra), no_game_data)
expected = ["mesen", "pcsx_rearmed"] + ([] if no_game_data else ["tyrquake"])
self.assertEqual(install.tui_choices(state)["cores"], expected)
listing = core_list(self.root / "line.json", self.files())
# A folder not named system: the save directory is not known.
text, _asked = self.line_run(
_args(manifest=listing, dest=self.root / "dest", declared_only=False,
dry_run=True, no_game_data=no_game_data), ["c", "", "1"])
head = text.rsplit("Counted again for your choices", 1)[1]
self.assertIn(f"1 of {len(expected)} cores", head)
state.cores = ["mesen"]
self.assertIn(f"1 of {len(expected)}",
next(r.label for r in install.tui_rows(
self.options(state)) if r.action == "cores"))
@staticmethod
def text(state: install.TuiState, cols: int, rows: int) -> str:
"""The frame drawn, its folded lines joined into one text."""
return " ".join(" ".join(str(line).split()) for line in
install.tui_view(state, cols, rows))
@staticmethod
def options(state: install.TuiState) -> install.TuiState:
state.stack = ["setup", "plan", "options"]
return state
def test_an_untick_keeps_the_other_systems_cores(self):
"""code_audit_24 P3-1: with --system sony-playstation, one untick on
pcsx_rearmed cleared mesen, drawn ticked under the other systems."""
state = checked_state()
state.ticked = {"sony-playstation"}
state.stack = ["setup", "plan", "options", "cores"]
state.cores_all = True
boxes = {r.value: r.label[:3] for r in install.tui_rows(state) if r.action == "core"}
self.assertEqual(boxes, {"mesen": "[x]", "pcsx_rearmed": "[x]"})
row = next(r for r in install.tui_rows(state) if r.value == "pcsx_rearmed")
install._tick(state, row, None)
boxes = {r.value: r.label[:3] for r in install.tui_rows(state) if r.action == "core"}
self.assertEqual(boxes, {"mesen": "[x]", "pcsx_rearmed": "[ ]"})
# The --core given is the cores ticked, exactly.
self.assertEqual([v for f, v in install.tui_flags(state) if f == "--core"], ["mesen"])
def test_a_core_of_another_system_is_not_all_cores(self):
"""code_audit_24 P3-2: mesen ticked alone with the PlayStation chosen
read "Cores: all", the run keeping none of pcsx_rearmed's files."""
state = checked_state()
state.ticked = {"sony-playstation"}
state.cores = ["mesen"]
options = self.options(state)
self.assertIn("Cores: 0 of 1", [r.label for r in install.tui_rows(options)])
state.stack = ["setup", "plan"]
self.assertIn("0 of 1 cores", self.text(state, 100, 30))
self.assertEqual(install.core_count_words(["mesen"], ["pcsx_rearmed"]), "0 of 1 cores")
def test_none_then_done_says_why_on_a_long_list(self):
"""tui_audit_17 P2-4: on 189 cores the status and the sentence were
dropped, Done with nothing ticked did nothing visible."""
state = checked_state()
state.manifest = {**MANIFEST, "files": [
*MANIFEST["files"],
*({"dest": f"x/{n}.bin", "size": 1, "systems": ["sony-playstation"],
"cores": [f"core{n:03}"]} for n in range(60))]}
state.stack = ["setup", "plan", "options", "cores"]
state.focus["cores"] = install._first_item(state)
press(state, "n")
done = next(i for i, r in enumerate(install.tui_rows(state)) if r.action == "done")
state.focus["cores"] = done
press(state, "enter")
self.assertEqual(state.screen, "cores")
for cols, rows in ((80, 24), (40, 12)):
text = self.text(state, cols, rows)
self.assertIn("No core is ticked", text)
self.assertIn("Untick the cores", text)
press(state, "esc")
self.assertEqual(state.screen, "cores")
def test_core_rows_say_what_each_core_adds(self):
"""tui_audit_17 P3-2: line mode counted each core's files, the
screen named the cores alone."""
state = checked_state()
state.stack = ["setup", "plan", "options", "cores"]
rows = {r.value: r.right for r in install.tui_rows(state) if r.action == "core"}
self.assertEqual(rows["pcsx_rearmed"], "1 file, 4 B")
state.cores_all = True
rows = {r.value: r.right for r in install.tui_rows(state) if r.action == "core"}
self.assertEqual(rows["mesen"], "1 file, 8.0 KB")
def test_one_core_has_no_cores_row(self):
"""tui_audit_17 P3-3: a list with one core offered Cores, where line
mode asks nothing."""
state = checked_state()
state.manifest = {**MANIFEST, "files": [
entry for entry in MANIFEST["files"] if entry["dest"] != "fc/disksys.rom"]}
self.assertNotIn("cores", [r.action for r in install.tui_rows(self.options(state))])
# Root cause 2: one tick list.
def test_the_three_lists_open_and_answer_alike(self):
"""tui_audit_17 P3-1: Choose systems opened on None, A unticking
every system, Cores closed on A, regions ticked on A."""
for route in ("both", "gptokeyb", "muxterm", "miyoo"):
for screen, opener in (("systems", ("plan", "systems")),
("cores", ("options", "cores")),
("regions", ("options", "regions"))):
with self.subTest(route=route, screen=screen):
state = checked_state()
state.pad = route
if opener[0] == "options":
press(state, "o")
state.focus[state.screen] = next(
i for i, r in enumerate(install.tui_rows(state))
if r.action == opener[1])
press(state, "enter")
self.assertEqual(state.screen, screen)
rows = install.tui_rows(state)
focused = rows[state.focus[screen]]
self.assertIn(focused.action, install.TUI_TICK_ROWS)
self.assertEqual([r.action for r in rows[-2:]], ["none", "done"])
hint = install._TUI_VIEWS[screen](state, 78, 21)[2]
self.assertEqual(hint[:2], ("A/Enter Tick", "B/Esc Done"))
before = install.tui_flags(state)
press(state, "enter")
self.assertEqual(state.screen, screen)
self.assertNotEqual(install.tui_flags(state), before)
# Root cause 3: a folder failure as it happened.
def test_a_folder_that_cannot_be_created_ends_on_its_reason(self):
"""tui_audit_17 P2-1: the result said "22 files not fetched
(RETROBIOS_INSTALL_OFFLINE=1)" and sent the user for a pack."""
for os_type in ("linux", "android"):
with self.subTest(os_type=os_type):
state = checked_state()
state.os_type = os_type
install.tui_update(state, Key("enter"))
for event in ({"event": "error", "stage": "dest", "reason": "not_writable",
"platform": "retroarch",
"message": f"{SYSTEM_DIR} cannot be created: Permission denied"},
{"event": "summary", "mode": "install", "installed": 0,
"up_to_date": 0, "pending": 4, "failed": [], "skipped": [],
"left_out": [], "kept": [], "interrupted": False}):
install.tui_receive(state, ("event", state.run_id, event))
install.tui_receive(state, ("ended", state.run_id, 2, []))
title, lines = install.tui_outcome(state)
text = " ".join(map(str, lines))
self.assertEqual(title, "Nothing installed")
self.assertIn("cannot be created (permission denied)", text)
self.assertNotIn("not fetched", text)
self.assertNotIn("not in", text.split("cannot be created")[0])
self.assertEqual("termux-setup-storage" in text, os_type == "android")
self.assertNotIn("sudo", text if os_type == "android" else "")
def test_android_never_offers_sudo_and_a_phone_plan_says_why(self):
"""tui_audit_17 P2-2: Termux was offered sudo, and at 40x12 the plan
offered Install anyway with no word of why."""
hint = install.Invocation()
hint.os_type = "android"
remedy = install.write_remedy(Path("/storage/emulated/0/RetroArch/system"),
"retroarch", hint)
self.assertEqual(remedy, [install.TERMUX_STORAGE_WORDS])
state = checked_state({"free": 50 * 1024 ** 3, "writable": False, "cores": []})
state.os_type = "android"
for cols, rows in ((40, 12), (80, 24)):
text = self.text(state, cols, rows)
self.assertIn("You cannot write to this folder", text)
self.assertNotIn("sudo", text)
# Root cause 4: every proven card named, the real marker said.
def test_an_arkos_card_is_found_beside_an_amberelec_card(self):
"""tui_audit_17 P2-3, code_audit_24 P3-6: an ArkOS card its bgmusic
or launchimages prove was named nowhere, and its route said it
could not tell it."""
games = games_part(self.root / "media" / "GAMES")
for marker in ("bgmusic", "launchimages"):
with self.subTest(marker=marker):
ark = self.drive(f"ARK_{marker}", ("bios", "nes", marker))
self.assertEqual(install.card_system(ark), ("retroarch", ark / "bios", "ArkOS"))
for name in ("ArkOS", "dArkOS"):
setup = install.card_setup(name, "retroarch")
self.assertEqual(install._card_is(setup, ark)[0], "own", name)
state = self.first_screen([games, ark])
text = self.text(state, 80, 24)
self.assertIn(f"ArkOS SD card (ARK_{marker})", text)
self.assertIn("AmberELEC SD card (GAMES)", text)
def test_the_emuelec_refusal_names_its_file(self):
"""code_audit_24 P3-7: the refusal named bezels, which AmberELEC's
card holds too."""
games = games_part(self.root / "media" / "GAMES")
(games / "bezels").mkdir()
setup = install.card_setup("EmuELEC", "emuelec")
choice = install._not_the_card(setup, games, games, "AmberELEC")
self.assertIn("bezels/default.cfg", choice.detail)
# Root cause 5: the reads before the menu show.
def test_the_reads_before_the_menu_show_a_count(self):
"""code_audit_24 P3-4: a rerun read every file before the menu, one at
a time and with nothing on screen."""
payload = b"R" * 16
(self.here / "a.bin").write_bytes(payload)
listing = core_list(self.root / "read.json",
[self.entry("a.bin", payload, ["sony-playstation"])])
text, _asked = self.line_run(_args(manifest=listing, dest=self.here,
declared_only=False), [])
self.assertIn("\r read 1/1", text)
self.assertLess(text.index("read 1/1"), text.index("every one in place"))
# Root cause 6: every other item.
def test_offline_the_plan_promises_no_replacement_it_cannot_make(self):
"""code_audit_24 P3-5: offline, the plan said a wrong copy no folder
holds "is replaced"."""
state = checked_state()
with mock.patch.dict(os.environ, {install.OFFLINE_VARIABLE: "1"}):
text = self.text(state, 100, 30)
self.assertIn("1 wrong copy", text)
self.assertNotIn("wrong copy is replaced", text)
def test_options_name_the_plans_bios_folder(self):
"""tui_audit_17 P3-6: AmberELEC's Options read the games part, its
plan the bios folder below it."""
state = checked_state()
state.manifest = {**MANIFEST, "files": [
{**entry, "dest": f"bios/{entry['dest']}"} for entry in MANIFEST["files"]]}
state.dest = Path("/media/me/GAMES")
row = next(r for r in install.tui_rows(self.options(state)) if r.action == "folder")
self.assertEqual(row.label, "BIOS folder: /media/me/GAMES/bios")
def test_finished_with_errors_says_a_rerun_retries(self):
"""tui_audit_17 P3-7: the screen never said a rerun retries the files
that failed, and line mode named each failure twice."""
state = checked_state()
install.tui_update(state, Key("enter"))
install.tui_receive(state, ("event", state.run_id, {
"event": "summary", "mode": "install", "installed": 3, "up_to_date": 0,
"pending": 1, "failed": [{"dest": "gba_bios.bin", "reason": "timed out"}],
"skipped": [], "left_out": [], "kept": [], "interrupted": False}))
install.tui_receive(state, ("ended", state.run_id, 1, []))
title, lines = install.tui_outcome(state)
self.assertEqual(title, "Finished with errors")
self.assertIn("Run it again to retry only those.", lines)
# Line mode: the FAILED line of the progress names it, the end not again.
install.SAID_FAILED.clear()
install.SAID_FAILED.add("gba_bios.bin")
self.addCleanup(install.SAID_FAILED.clear)
out = io.StringIO()
with contextlib.redirect_stdout(out), contextlib.redirect_stderr(out), \
contextlib.suppress(SystemExit):
install._report_outcome([Path("/b")], 3, 0, 1, 0, False,
failures=[("gba_bios.bin", "timed out")])
self.assertNotIn("gba_bios.bin", out.getvalue())
self.assertIn("Run the same command again to retry only those.", out.getvalue())
def test_below_40_columns_no_word_is_broken(self):
"""tui_audit_17 P3-8: the reason line, Found and Install for were
left to the terminal, which broke "/media/moi/" and "ONION/BIOS"."""
with mock.patch.object(install, "terminal_size", return_value=(39, 11)), \
mock.patch.object(install, "_is_terminal", return_value=True):
for text in (" Found Onion at /media/moi/ONION/BIOS (RetroArch files)",
"The window is 39x11: questions come line by line "
"(40x12 for the full screen)."):
lines = install.fold_line(text).split("\n")
self.assertTrue(all(len(line) <= 38 for line in lines), lines)
self.assertEqual(" ".join(" ".join(lines).split()), " ".join(text.split()))
def test_the_narrowing_line_is_a_sentence(self):
"""tui_audit_17 P3-4: the plan read "--region." on a line alone."""
state = checked_state()
state.regions = ["japan"]
text = self.text(state, 100, 30)
self.assertIn("For your choice: regions ranked.", text)
self.assertNotIn(" --region.", text)
def test_offline_choice_of_systems_is_never_about_0_files(self):
"""tui_audit_17 P3-5: "About 0 files, 0 B, for 10 of 11 systems"."""
state = checked_state()
state.ticked = {"sony-playstation"}
with mock.patch.dict(os.environ, {install.OFFLINE_VARIABLE: "1"}):
text = self.text(state, 100, 30)
self.assertNotIn("About 0 files", text)
self.assertIn("need the internet", text)
def test_a_phone_bar_after_a_tap_keeps_quit_and_one_wording(self):
"""tui_audit_17 P3-11: at 40 columns on Android the armed bar dropped
Esc Quit and said "click", the row "tap again"."""
state = fresh_state()
state.os_type = "android"
state.mouse = True
state.stack = ["setup"]
install.tui_view(state, 40, 12)
state.tapped = install._tapped_row(state)
frame = install.tui_view(state, 40, 12)
text = "\n".join(map(str, frame))
self.assertNotIn("click", text)
self.assertIn("tap again", text)
self.assertIn("Esc Quit", str(frame[-1]))
def test_the_offline_screen_names_the_setups_list(self):
"""tui_audit_17 P3-12: the offline screen said install/<platform>.json
for AmberELEC, chosen one screen before."""
inbox: queue.Queue = queue.Queue()
install.LOCAL.reset()
with mock.patch.dict(os.environ, {install.OFFLINE_VARIABLE: "1"}):
install._tui_fetch("amberelec", inbox, io.StringIO())
message = inbox.get_nowait()
self.assertIn("install/amberelec.json", " ".join(message[3]))
# Root cause 7: the tests leave the host alone.
def test_no_connection_leaves_the_loopback_nor_a_card_comes_in(self):
"""code_audit_24 P3-13: 261 connections to GitHub left this module,
and tests failed with an AmberELEC card in the reader."""
import socket # noqa: PLC0415
log = Path(os.environ["RETROBIOS_TEST_NETLOG"])
before = log.read_text(encoding="utf-8")
self.addCleanup(log.write_text, before, encoding="utf-8")
with self.assertRaisesRegex(OSError, "makes no request"):
socket.create_connection(("192.0.2.1", 80), timeout=1)
child = subprocess.run(
[sys.executable, "-c", "import os, socket\n"
"print(os.path.ismount('/media/x'), os.path.ismount('/mnt/d'))\n"
"socket.create_connection(('192.0.2.1', 80), 1)"],
capture_output=True, text=True, check=False, timeout=60)
self.assertEqual(child.stdout.strip(), "False False")
self.assertIn("makes no request", child.stderr)
self.assertEqual(len(log.read_text(encoding="utf-8").splitlines()),
len(before.splitlines()) + 2)
self.assertFalse(os.path.ismount("/media/x"))
if __name__ == "__main__":
unittest.main()