mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-01 00:27:20 -05:00
chore: merge one card list and one card check
This commit is contained in:
commit
5ebc576cb1
28 files changed
+1600
-531
No files matched your search
+1
-1
@@ -11,7 +11,7 @@
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
$defaultInstallSha256 = "b7eec15ba746bbaaaea471396964a83a255a4a1c4bd51316fbdb0ff62a065169"
|
||||
$defaultInstallSha256 = "aebd38c69bc524b655e592ae0407ec6095696b846370e2c726275db8bfd050f4"
|
||||
$maximumInstallerBytes = 2MB
|
||||
$installerExit = 0
|
||||
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
|
||||
|
||||
+677
-228
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -18,7 +18,7 @@ esac
|
||||
TEMP_INSTALLER=""
|
||||
TEMP_DIRECTORY=""
|
||||
DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
DEFAULT_INSTALL_SHA256="b7eec15ba746bbaaaea471396964a83a255a4a1c4bd51316fbdb0ff62a065169"
|
||||
DEFAULT_INSTALL_SHA256="aebd38c69bc524b655e592ae0407ec6095696b846370e2c726275db8bfd050f4"
|
||||
MAX_INSTALLER_BYTES=2097152
|
||||
|
||||
cleanup() {
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
{
|
||||
"dest": "roms/ports/retrobios/install.py",
|
||||
"repo_path": "install.py",
|
||||
"size": 650926,
|
||||
"sha256": "b7eec15ba746bbaaaea471396964a83a255a4a1c4bd51316fbdb0ff62a065169",
|
||||
"size": 673355,
|
||||
"sha256": "aebd38c69bc524b655e592ae0407ec6095696b846370e2c726275db8bfd050f4",
|
||||
"executable": false
|
||||
},
|
||||
{
|
||||
@@ -71,8 +71,8 @@
|
||||
"muos": {
|
||||
"archive": {
|
||||
"dest": "ARCHIVE/RetroBIOS.muxapp",
|
||||
"size": 703475,
|
||||
"sha256": "1928a1ee174ab57d2890fa7d668a34fa996637669446bb6ad4329fa0fc3d76dc"
|
||||
"size": 725904,
|
||||
"sha256": "ec454bce0a07adfd46f7791804c18e69d568b294c2d0f224541887fc2431ba52"
|
||||
},
|
||||
"members": [
|
||||
{
|
||||
@@ -92,8 +92,8 @@
|
||||
{
|
||||
"name": "RetroBIOS/install.py",
|
||||
"repo_path": "install.py",
|
||||
"size": 650926,
|
||||
"sha256": "b7eec15ba746bbaaaea471396964a83a255a4a1c4bd51316fbdb0ff62a065169",
|
||||
"size": 673355,
|
||||
"sha256": "aebd38c69bc524b655e592ae0407ec6095696b846370e2c726275db8bfd050f4",
|
||||
"executable": false
|
||||
},
|
||||
{
|
||||
@@ -166,8 +166,8 @@
|
||||
{
|
||||
"dest": ".config/modules/retrobios/install.py",
|
||||
"repo_path": "install.py",
|
||||
"size": 650926,
|
||||
"sha256": "b7eec15ba746bbaaaea471396964a83a255a4a1c4bd51316fbdb0ff62a065169",
|
||||
"size": 673355,
|
||||
"sha256": "aebd38c69bc524b655e592ae0407ec6095696b846370e2c726275db8bfd050f4",
|
||||
"executable": false
|
||||
},
|
||||
{
|
||||
|
||||
Vendored
+1
-1
@@ -37,4 +37,4 @@
|
||||
|
||||
|
||||
|
||||
A/Enter Back B/Esc Back
|
||||
A/Enter Choose B/Esc Back
|
||||
Vendored
+1
-1
@@ -9,4 +9,4 @@
|
||||
retroarch.json
|
||||
> Choose another setup or folder
|
||||
Quit
|
||||
A/Enter Back B/Esc Back
|
||||
A/Enter Choose B/Esc Back
|
||||
Vendored
+1
-1
@@ -12,4 +12,4 @@
|
||||
Quit
|
||||
|
||||
|
||||
A/Enter Back B/Esc Back
|
||||
A/Enter Choose B/Esc Back
|
||||
Vendored
+1
-1
@@ -21,4 +21,4 @@
|
||||
|
||||
|
||||
|
||||
A/Enter Back B/Esc Back
|
||||
A/Enter Choose B/Esc Back
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD card. Choose the card's root folder, the one holding
|
||||
.system.
|
||||
NextUI keeps its BIOS files at the root of its SD card. Choose the card's top folder, the one
|
||||
holding .system.
|
||||
No NextUI card is mounted. Insert it, then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
|
||||
+4
-4
@@ -1,11 +1,11 @@
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
Type a path
|
||||
Look again
|
||||
|
||||
+4
-4
@@ -1,8 +1,9 @@
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
@@ -11,5 +12,4 @@
|
||||
Look again
|
||||
|
||||
|
||||
|
||||
A/Enter Browse B/Esc Back ? Help
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD card. Choose the card's root folder, the
|
||||
one holding .system.
|
||||
NextUI keeps its BIOS files at the root of its SD card. Choose the card's top
|
||||
folder, the one holding .system.
|
||||
No NextUI card is mounted. Insert it, then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
|
||||
+22
-22
@@ -3,38 +3,38 @@
|
||||
Choose the setup that will use the BIOS files.
|
||||
|
||||
Filter (/ to type)
|
||||
> RetroArch muOS, JELOS, KOLOS, Uno...Anbernic stock firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
MiSTer FPGA
|
||||
RetroPie
|
||||
AmberELEC PAN4ELEC
|
||||
EmuELEC
|
||||
KNULLI
|
||||
MinUI
|
||||
NextUI
|
||||
MyMinUI
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
KNULLI, SD card
|
||||
MinUI, SD card
|
||||
NextUI, SD card
|
||||
MyMinUI, SD card
|
||||
Allium, SD card RetroArch files
|
||||
Anbernic stock firmware, SD card RetroArch files
|
||||
ArchR, SD card RetroArch files
|
||||
ArkOS, SD card RetroArch files
|
||||
CrossMix-OS, SD card RetroArch files
|
||||
dArkOS, SD card RetroArch files
|
||||
JELOS, SD card RetroArch files
|
||||
KOLOS, SD card RetroArch files
|
||||
Koriki, SD card RetroArch files
|
||||
MiyooCFW, SD card RetroArch files
|
||||
muOS, SD card RetroArch files
|
||||
Onion, SD card RetroArch files
|
||||
plumOS, SD card RetroArch files
|
||||
RetroOZ, SD card RetroArch files
|
||||
spruceOS, SD card RetroArch files
|
||||
UnofficialOS, SD card RetroArch files
|
||||
A/Enter Choose B/Esc Back / Filter ? Help
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (/ to type)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
1-7 of 18
|
||||
1-7 of 34
|
||||
A Choose B Back / Filter ? Help
|
||||
+3
-3
@@ -1,15 +1,15 @@
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (/ to type)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
1-10 of 18
|
||||
1-10 of 34
|
||||
A Choose B Back / Filter ? Help
|
||||
+8
-8
@@ -1,24 +1,24 @@
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Choose the setup that will use the BIOS files.
|
||||
|
||||
Filter (/ to type)
|
||||
> RetroArch muOS, JELOS, KOLOS...nic stock firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
MiSTer FPGA
|
||||
RetroPie
|
||||
AmberELEC PAN4ELEC
|
||||
EmuELEC
|
||||
KNULLI
|
||||
MinUI
|
||||
NextUI
|
||||
MyMinUI
|
||||
KNULLI, SD card
|
||||
MinUI, SD card
|
||||
NextUI, SD card
|
||||
MyMinUI, SD card
|
||||
Allium, SD card RetroArch files
|
||||
1-19 of 34
|
||||
A/Enter Choose B/Esc Back / Filter ? Help
|
||||
Vendored
+26
-26
@@ -56,55 +56,55 @@
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (with a keyboard)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
1-7 of 18
|
||||
1-7 of 34
|
||||
A Choose B Back
|
||||
=== platforms 40x15
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (with a keyboard)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
1-10 of 18
|
||||
1-10 of 34
|
||||
A Choose B Back
|
||||
=== platforms 80x24
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Choose the setup that will use the BIOS files.
|
||||
|
||||
Filter (with a keyboard)
|
||||
> RetroArch muOS, JELOS, KOLOS...nic stock firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
MiSTer FPGA
|
||||
RetroPie
|
||||
AmberELEC PAN4ELEC
|
||||
EmuELEC
|
||||
KNULLI
|
||||
MinUI
|
||||
NextUI
|
||||
MyMinUI
|
||||
KNULLI, SD card
|
||||
MinUI, SD card
|
||||
NextUI, SD card
|
||||
MyMinUI, SD card
|
||||
Allium, SD card RetroArch files
|
||||
1-19 of 34
|
||||
A Choose B Back
|
||||
=== folder 40x12
|
||||
RetroBIOS: Which folder?
|
||||
@@ -163,12 +163,12 @@
|
||||
=== folder-card 40x12
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
Type a path
|
||||
Look again
|
||||
@@ -176,9 +176,10 @@
|
||||
=== folder-card 40x15
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
@@ -187,13 +188,12 @@
|
||||
Look again
|
||||
|
||||
|
||||
|
||||
A Browse B Back
|
||||
=== folder-card 80x24
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD card. Choose the card's root folder, the
|
||||
one holding .system.
|
||||
NextUI keeps its BIOS files at the root of its SD card. Choose the card's top
|
||||
folder, the one holding .system.
|
||||
No NextUI card is mounted. Insert it, then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
@@ -1036,7 +1036,7 @@
|
||||
retroarch.json
|
||||
> Choose another setup or folder
|
||||
Quit
|
||||
A Back B Back
|
||||
A Choose B Back
|
||||
=== error 40x15
|
||||
RetroBIOS: Something went wrong
|
||||
|
||||
@@ -1052,7 +1052,7 @@
|
||||
Quit
|
||||
|
||||
|
||||
A Back B Back
|
||||
A Choose B Back
|
||||
=== error 80x24
|
||||
RetroBIOS: Something went wrong
|
||||
|
||||
@@ -1077,7 +1077,7 @@
|
||||
|
||||
|
||||
|
||||
A Back B Back
|
||||
A Choose B Back
|
||||
=== quit 40x12
|
||||
RetroBIOS: Quit?
|
||||
|
||||
|
||||
+26
-26
@@ -56,55 +56,55 @@
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (with a keyboard)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
1-7 of 18
|
||||
1-7 of 34
|
||||
A Choose B Back
|
||||
=== platforms 40x15
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (with a keyboard)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
1-10 of 18
|
||||
1-10 of 34
|
||||
A Choose B Back
|
||||
=== platforms 80x24
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Choose the setup that will use the BIOS files.
|
||||
|
||||
Filter (with a keyboard)
|
||||
> RetroArch muOS, JELOS, KOLOS...nic stock firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
MiSTer FPGA
|
||||
RetroPie
|
||||
AmberELEC PAN4ELEC
|
||||
EmuELEC
|
||||
KNULLI
|
||||
MinUI
|
||||
NextUI
|
||||
MyMinUI
|
||||
KNULLI, SD card
|
||||
MinUI, SD card
|
||||
NextUI, SD card
|
||||
MyMinUI, SD card
|
||||
Allium, SD card RetroArch files
|
||||
1-19 of 34
|
||||
A Choose B Back
|
||||
=== folder 40x12
|
||||
RetroBIOS: Which folder?
|
||||
@@ -163,12 +163,12 @@
|
||||
=== folder-card 40x12
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
Type a path
|
||||
Look again
|
||||
@@ -176,9 +176,10 @@
|
||||
=== folder-card 40x15
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
@@ -187,13 +188,12 @@
|
||||
Look again
|
||||
|
||||
|
||||
|
||||
A Browse B Back
|
||||
=== folder-card 80x24
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD card. Choose the card's root folder, the
|
||||
one holding .system.
|
||||
NextUI keeps its BIOS files at the root of its SD card. Choose the card's top
|
||||
folder, the one holding .system.
|
||||
No NextUI card is mounted. Insert it, then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
@@ -1036,7 +1036,7 @@
|
||||
retroarch.json
|
||||
> Choose another setup or folder
|
||||
Quit
|
||||
A Back B Back
|
||||
A Choose B Back
|
||||
=== error 40x15
|
||||
RetroBIOS: Something went wrong
|
||||
|
||||
@@ -1052,7 +1052,7 @@
|
||||
Quit
|
||||
|
||||
|
||||
A Back B Back
|
||||
A Choose B Back
|
||||
=== error 80x24
|
||||
RetroBIOS: Something went wrong
|
||||
|
||||
@@ -1077,7 +1077,7 @@
|
||||
|
||||
|
||||
|
||||
A Back B Back
|
||||
A Choose B Back
|
||||
=== quit 40x12
|
||||
RetroBIOS: Quit?
|
||||
|
||||
|
||||
+26
-26
@@ -56,55 +56,55 @@
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (with a keyboard)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
1-7 of 18
|
||||
1-7 of 34
|
||||
A Choose B Back
|
||||
=== platforms 40x15
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (with a keyboard)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
1-10 of 18
|
||||
1-10 of 34
|
||||
A Choose B Back
|
||||
=== platforms 80x24
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Choose the setup that will use the BIOS files.
|
||||
|
||||
Filter (with a keyboard)
|
||||
> RetroArch muOS, JELOS, KOLOS...nic stock firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
MiSTer FPGA
|
||||
RetroPie
|
||||
AmberELEC PAN4ELEC
|
||||
EmuELEC
|
||||
KNULLI
|
||||
MinUI
|
||||
NextUI
|
||||
MyMinUI
|
||||
KNULLI, SD card
|
||||
MinUI, SD card
|
||||
NextUI, SD card
|
||||
MyMinUI, SD card
|
||||
Allium, SD card RetroArch files
|
||||
1-19 of 34
|
||||
A Choose B Back
|
||||
=== folder 40x12
|
||||
RetroBIOS: Which folder?
|
||||
@@ -163,12 +163,12 @@
|
||||
=== folder-card 40x12
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
Type a path
|
||||
Look again
|
||||
@@ -176,9 +176,10 @@
|
||||
=== folder-card 40x15
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
@@ -187,13 +188,12 @@
|
||||
Look again
|
||||
|
||||
|
||||
|
||||
A Browse B Back
|
||||
=== folder-card 80x24
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD card. Choose the card's root folder, the
|
||||
one holding .system.
|
||||
NextUI keeps its BIOS files at the root of its SD card. Choose the card's top
|
||||
folder, the one holding .system.
|
||||
No NextUI card is mounted. Insert it, then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
@@ -1036,7 +1036,7 @@
|
||||
retroarch.json
|
||||
> Choose another setup or folder
|
||||
Quit
|
||||
A Back B Back
|
||||
A Choose B Back
|
||||
=== error 40x15
|
||||
RetroBIOS: Something went wrong
|
||||
|
||||
@@ -1052,7 +1052,7 @@
|
||||
Quit
|
||||
|
||||
|
||||
A Back B Back
|
||||
A Choose B Back
|
||||
=== error 80x24
|
||||
RetroBIOS: Something went wrong
|
||||
|
||||
@@ -1077,7 +1077,7 @@
|
||||
|
||||
|
||||
|
||||
A Back B Back
|
||||
A Choose B Back
|
||||
=== quit 40x12
|
||||
RetroBIOS: Quit?
|
||||
|
||||
|
||||
Vendored
+26
-26
@@ -56,55 +56,55 @@
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (/ to type)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
1-7 of 18
|
||||
1-7 of 34
|
||||
Enter Choose Esc Back / Filter
|
||||
=== platforms 40x15
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (/ to type)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
1-10 of 18
|
||||
1-10 of 34
|
||||
Enter Choose Esc Back / Filter
|
||||
=== platforms 80x24
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Choose the setup that will use the BIOS files.
|
||||
|
||||
Filter (/ to type)
|
||||
> RetroArch muOS, JELOS, KOLOS...nic stock firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
MiSTer FPGA
|
||||
RetroPie
|
||||
AmberELEC PAN4ELEC
|
||||
EmuELEC
|
||||
KNULLI
|
||||
MinUI
|
||||
NextUI
|
||||
MyMinUI
|
||||
KNULLI, SD card
|
||||
MinUI, SD card
|
||||
NextUI, SD card
|
||||
MyMinUI, SD card
|
||||
Allium, SD card RetroArch files
|
||||
1-19 of 34
|
||||
Enter Choose Esc Back / Filter ? Help
|
||||
=== folder 40x12
|
||||
RetroBIOS: Which folder?
|
||||
@@ -163,12 +163,12 @@
|
||||
=== folder-card 40x12
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
Type a path
|
||||
Look again
|
||||
@@ -176,9 +176,10 @@
|
||||
=== folder-card 40x15
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
@@ -187,13 +188,12 @@
|
||||
Look again
|
||||
|
||||
|
||||
|
||||
Enter Browse Esc Back ? Help
|
||||
=== folder-card 80x24
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD card. Choose the card's root folder, the
|
||||
one holding .system.
|
||||
NextUI keeps its BIOS files at the root of its SD card. Choose the card's top
|
||||
folder, the one holding .system.
|
||||
No NextUI card is mounted. Insert it, then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
@@ -982,7 +982,7 @@
|
||||
retroarch.json
|
||||
> Choose another setup or folder
|
||||
Quit
|
||||
Enter Back Esc Back
|
||||
Enter Choose Esc Back
|
||||
=== error 40x15
|
||||
RetroBIOS: Something went wrong
|
||||
|
||||
@@ -998,7 +998,7 @@
|
||||
Quit
|
||||
|
||||
|
||||
Enter Back Esc Back
|
||||
Enter Choose Esc Back
|
||||
=== error 80x24
|
||||
RetroBIOS: Something went wrong
|
||||
|
||||
@@ -1023,7 +1023,7 @@
|
||||
|
||||
|
||||
|
||||
Enter Back Esc Back
|
||||
Enter Choose Esc Back
|
||||
=== quit 40x12
|
||||
RetroBIOS: Quit?
|
||||
|
||||
|
||||
Vendored
+26
-26
@@ -56,55 +56,55 @@
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (with a keyboard)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
1-7 of 18
|
||||
1-7 of 34
|
||||
A Choose R2 Back
|
||||
=== platforms 40x15
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (with a keyboard)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
1-10 of 18
|
||||
1-10 of 34
|
||||
A Choose R2 Back
|
||||
=== platforms 80x24
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Choose the setup that will use the BIOS files.
|
||||
|
||||
Filter (with a keyboard)
|
||||
> RetroArch muOS, JELOS, KOLOS...nic stock firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
MiSTer FPGA
|
||||
RetroPie
|
||||
AmberELEC PAN4ELEC
|
||||
EmuELEC
|
||||
KNULLI
|
||||
MinUI
|
||||
NextUI
|
||||
MyMinUI
|
||||
KNULLI, SD card
|
||||
MinUI, SD card
|
||||
NextUI, SD card
|
||||
MyMinUI, SD card
|
||||
Allium, SD card RetroArch files
|
||||
1-19 of 34
|
||||
A Choose R2 Back
|
||||
=== folder 40x12
|
||||
RetroBIOS: Which folder?
|
||||
@@ -163,12 +163,12 @@
|
||||
=== folder-card 40x12
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
Type a path
|
||||
Look again
|
||||
@@ -176,9 +176,10 @@
|
||||
=== folder-card 40x15
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
@@ -187,13 +188,12 @@
|
||||
Look again
|
||||
|
||||
|
||||
|
||||
A Browse R2 Back
|
||||
=== folder-card 80x24
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD card. Choose the card's root folder, the
|
||||
one holding .system.
|
||||
NextUI keeps its BIOS files at the root of its SD card. Choose the card's top
|
||||
folder, the one holding .system.
|
||||
No NextUI card is mounted. Insert it, then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
@@ -1036,7 +1036,7 @@
|
||||
retroarch.json
|
||||
> Choose another setup or folder
|
||||
Quit
|
||||
A Back R2 Back
|
||||
A Choose R2 Back
|
||||
=== error 40x15
|
||||
RetroBIOS: Something went wrong
|
||||
|
||||
@@ -1052,7 +1052,7 @@
|
||||
Quit
|
||||
|
||||
|
||||
A Back R2 Back
|
||||
A Choose R2 Back
|
||||
=== error 80x24
|
||||
RetroBIOS: Something went wrong
|
||||
|
||||
@@ -1077,7 +1077,7 @@
|
||||
|
||||
|
||||
|
||||
A Back R2 Back
|
||||
A Choose R2 Back
|
||||
=== quit 40x12
|
||||
RetroBIOS: Quit?
|
||||
|
||||
|
||||
Vendored
+26
-26
@@ -56,55 +56,55 @@
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (Select shows a keyboard)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
1-7 of 18
|
||||
1-7 of 34
|
||||
Start Choose B Back
|
||||
=== platforms 40x15
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Filter (Select shows a keyboard)
|
||||
> RetroArch muOS, JE...firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
1-10 of 18
|
||||
1-10 of 34
|
||||
Start Choose B Back
|
||||
=== platforms 80x24
|
||||
RetroBIOS: Which setup?
|
||||
|
||||
Choose the setup that will use the BIOS files.
|
||||
|
||||
Filter (Select shows a keyboard)
|
||||
> RetroArch muOS, JELOS, KOLOS...nic stock firmware
|
||||
> RetroArch
|
||||
Batocera
|
||||
Recalbox
|
||||
RetroBat
|
||||
EmuDeck
|
||||
Lakka
|
||||
RetroDECK
|
||||
ROCKNIX
|
||||
ROCKNIX, SD card
|
||||
RomM
|
||||
BizHawk
|
||||
MiSTer FPGA
|
||||
RetroPie
|
||||
AmberELEC PAN4ELEC
|
||||
EmuELEC
|
||||
KNULLI
|
||||
MinUI
|
||||
NextUI
|
||||
MyMinUI
|
||||
KNULLI, SD card
|
||||
MinUI, SD card
|
||||
NextUI, SD card
|
||||
MyMinUI, SD card
|
||||
Allium, SD card RetroArch files
|
||||
1-19 of 34
|
||||
Start Choose B Back
|
||||
=== folder 40x12
|
||||
RetroBIOS: Which folder?
|
||||
@@ -163,12 +163,12 @@
|
||||
=== folder-card 40x12
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
Type a path
|
||||
Look again
|
||||
@@ -176,9 +176,10 @@
|
||||
=== folder-card 40x15
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD
|
||||
card. Choose the card's root folder,
|
||||
the one holding .system.
|
||||
NextUI keeps its BIOS files at the
|
||||
root of its SD card. Choose the
|
||||
card's top folder, the one holding
|
||||
.system.
|
||||
No NextUI card is mounted. Insert it,
|
||||
then choose Look again.
|
||||
|
||||
@@ -187,13 +188,12 @@
|
||||
Look again
|
||||
|
||||
|
||||
|
||||
Start Browse B Back
|
||||
=== folder-card 80x24
|
||||
RetroBIOS: Where is the SD card?
|
||||
|
||||
NextUI keeps its BIOS files on its SD card. Choose the card's root folder, the
|
||||
one holding .system.
|
||||
NextUI keeps its BIOS files at the root of its SD card. Choose the card's top
|
||||
folder, the one holding .system.
|
||||
No NextUI card is mounted. Insert it, then choose Look again.
|
||||
|
||||
> Browse for a folder
|
||||
@@ -1036,7 +1036,7 @@
|
||||
retroarch.json
|
||||
> Choose another setup or folder
|
||||
Quit
|
||||
Start Back B Back
|
||||
Start Choose B Back
|
||||
=== error 40x15
|
||||
RetroBIOS: Something went wrong
|
||||
|
||||
@@ -1052,7 +1052,7 @@
|
||||
Quit
|
||||
|
||||
|
||||
Start Back B Back
|
||||
Start Choose B Back
|
||||
=== error 80x24
|
||||
RetroBIOS: Something went wrong
|
||||
|
||||
@@ -1077,7 +1077,7 @@
|
||||
|
||||
|
||||
|
||||
Start Back B Back
|
||||
Start Choose B Back
|
||||
=== quit 40x12
|
||||
RetroBIOS: Quit?
|
||||
|
||||
|
||||
+18
-1
@@ -4230,10 +4230,27 @@ class DestAloneFollowsWhatIsFoundHere(unittest.TestCase):
|
||||
unittest.mock.patch("builtins.input", lambda _prompt="": answer), \
|
||||
contextlib.redirect_stdout(out), contextlib.redirect_stderr(out):
|
||||
try:
|
||||
return install._platform_for_dest("linux", Path("/media/card"), interactive), out.getvalue()
|
||||
plat, folder = install._platform_for_dest("linux", Path("/media/card"),
|
||||
interactive)
|
||||
self.assertEqual(folder, Path("/media/card"))
|
||||
return plat, out.getvalue()
|
||||
except SystemExit as exc:
|
||||
return exc, out.getvalue()
|
||||
|
||||
def test_a_card_system_chosen_checks_the_folder(self):
|
||||
"""code_audit_13 P2-3: the menu offered no card system, and one
|
||||
chosen now reads --dest as --platform does."""
|
||||
root = Path(_tempdir(self))
|
||||
answers = iter(["Onion", "retroarch"])
|
||||
out = io.StringIO()
|
||||
with unittest.mock.patch.object(install, "detect_platforms", return_value=[]), \
|
||||
unittest.mock.patch("builtins.input", lambda _prompt="": next(answers)), \
|
||||
contextlib.redirect_stdout(out):
|
||||
plat, folder = install._platform_for_dest("linux", root, True)
|
||||
self.assertEqual((plat, folder), ("retroarch", root))
|
||||
self.assertIn(f"{root} is not an Onion SD card", out.getvalue())
|
||||
self.assertIn("Onion, SD card (RetroArch files)", out.getvalue())
|
||||
|
||||
def test_nothing_found_is_retroarch_said_aloud(self):
|
||||
plat, out = self._pick([])
|
||||
self.assertEqual(plat, "retroarch")
|
||||
|
||||
@@ -379,7 +379,7 @@ class MisplacedInTheBiosFolder(Scratch):
|
||||
for name, data in PAYLOAD.items():
|
||||
self.assertEqual((self.dest / name).read_bytes(), data)
|
||||
self.assertEqual((self.dest / "system" / name).read_bytes(), data)
|
||||
self.assertIn("4 files fixed from copies already in the BIOS folder.", proc.stdout)
|
||||
self.assertIn("4 files copied from the wrong place in the BIOS folder.", proc.stdout)
|
||||
self.assertIn("nested folder: it is at system/system/scph5501.bin", proc.stdout)
|
||||
|
||||
def test_a_pack_extracted_into_a_folder_of_its_own_is_fixed(self):
|
||||
@@ -405,7 +405,7 @@ class MisplacedInTheBiosFolder(Scratch):
|
||||
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
|
||||
self.assertEqual((self.dest / "gba_bios.bin").read_bytes(), GBA)
|
||||
self.assertEqual((self.dest / "GBA_BIOS.BIN").read_bytes(), GBA)
|
||||
self.assertIn("1 file fixed from copies already in the BIOS folder.", proc.stdout)
|
||||
self.assertIn("1 file copied from the wrong place in the BIOS folder.", proc.stdout)
|
||||
|
||||
def test_a_file_left_in_its_zip_is_extracted(self):
|
||||
self.complete("gba_bios.bin")
|
||||
@@ -1008,10 +1008,10 @@ class TheSummaryLine(unittest.TestCase):
|
||||
|
||||
def test_one_file_and_fixes(self):
|
||||
self.assertEqual(install.sources_line([("/old", 1)], fixed=3, downloaded=0, missing=0),
|
||||
"1 file copied from /old, 3 fixed from copies already in the "
|
||||
"1 file copied from /old, 3 copied from the wrong place in the "
|
||||
"BIOS folder.")
|
||||
self.assertEqual(install.sources_line([], fixed=2, downloaded=1, missing=0),
|
||||
"2 files fixed from copies already in the BIOS folder, "
|
||||
"2 files copied from the wrong place in the BIOS folder, "
|
||||
"1 downloaded.")
|
||||
|
||||
def test_nothing_copied_is_no_line(self):
|
||||
|
||||
@@ -779,5 +779,69 @@ class ADryRunOpensOnItsTotals(Scratch):
|
||||
self.assertTrue(any("sys00/file0.bin" in line for line in plan))
|
||||
|
||||
|
||||
|
||||
class OfflineLeavesFilesMissing(Scratch):
|
||||
"""code_audit_13 P1-1, P3-7, P3-8: the files --offline leaves out at a
|
||||
terminal were counted with a "no" to the size question. Once one file
|
||||
came from this machine, 14,696 missing ended on Done and exit 0."""
|
||||
|
||||
def outcome(self, **counts) -> tuple[int, str]:
|
||||
out = io.StringIO()
|
||||
with contextlib.redirect_stdout(out), self.assertRaises(SystemExit) as stop:
|
||||
install._report_outcome([self.dest], counts.get("installed", 0), 0,
|
||||
counts.get("errors", 0), 0, False,
|
||||
sources=counts.get("sources", ""),
|
||||
offline=counts["offline"])
|
||||
return stop.exception.code, out.getvalue()
|
||||
|
||||
def test_some_installed_is_not_done(self):
|
||||
code, text = self.outcome(installed=4, offline=14696,
|
||||
sources="4 files copied from old, 14696 still missing.")
|
||||
self.assertEqual(code, 1)
|
||||
self.assertNotIn("Done", text)
|
||||
self.assertIn("Finished with files missing. 4 files installed, 14696 not fetched "
|
||||
"(--offline).", text)
|
||||
self.assertIn("14696 still missing", text)
|
||||
|
||||
def test_nothing_installed_is_code_2(self):
|
||||
code, text = self.outcome(offline=14700)
|
||||
self.assertEqual(code, 2)
|
||||
self.assertIn("Nothing installed: 14700 files need the internet, which --offline "
|
||||
"does not use.", text)
|
||||
# Nothing was up to date: the line said "0 files already up to date".
|
||||
self.assertNotIn("up to date", text)
|
||||
|
||||
def test_the_folder_given_is_not_suggested_again(self):
|
||||
old = self.root / "old"
|
||||
old.mkdir()
|
||||
install.LOCAL.reset()
|
||||
self.addCleanup(install.LOCAL.reset)
|
||||
install.LOCAL.folders = [install.FolderIndex(old)]
|
||||
_code, text = self.outcome(offline=3)
|
||||
self.assertIn(f"They are not in {old}", text)
|
||||
self.assertNotIn("(--from)", text)
|
||||
|
||||
def test_a_dry_run_offline_says_no_download(self):
|
||||
proc = self.run_installer("--offline", "--dry-run", "--manifest", str(self.list))
|
||||
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
|
||||
self.assertNotIn("Would download", proc.stdout)
|
||||
self.assertIn("4 files (", proc.stdout)
|
||||
self.assertIn("need the internet, which --offline does not use. Without --offline "
|
||||
"they would go to", proc.stdout)
|
||||
|
||||
def test_an_archive_not_read_is_only_its_error(self):
|
||||
listed = manifest()
|
||||
listed["data_directories"] = [{
|
||||
"ref": "bluemsx", "dest": "Machines", "type": "zip",
|
||||
"url": "https://example.invalid/blueMSX.zip", "systems": ["nintendo-gba"],
|
||||
"files": {"a.txt": {"sha1": _sha1(b"a"), "size": 1}},
|
||||
}]
|
||||
self.list.write_text(json.dumps(listed))
|
||||
self.complete()
|
||||
proc = self.run_installer("--offline", "--manifest", str(self.list), "--no-input")
|
||||
self.assertIn("bluemsx: could not read", proc.stderr)
|
||||
self.assertNotIn("no longer in the source", proc.stdout)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+575
-56
@@ -696,7 +696,7 @@ class Flow(unittest.TestCase):
|
||||
self.assertIn("RetroBIOS: No connection", install.tui_view(state, 80, 24)[0])
|
||||
self.assertEqual(state.screen, "error")
|
||||
self.assertEqual([row.action for row in install.tui_rows(state)],
|
||||
["retry", "back", "quit"])
|
||||
["retry", "elsewhere", "quit"])
|
||||
self.assertEqual(press(state, "enter"), [("fetch", "retroarch")])
|
||||
install.tui_receive(state, ("manifest_failed", "retroarch", "No connection", ["no"], 1))
|
||||
press(state, "down", "down", "enter")
|
||||
@@ -1598,8 +1598,9 @@ class AuditRoundTwo(unittest.TestCase):
|
||||
self.assertEqual(state.ticked, ticked)
|
||||
for cols, rows in ((80, 24), (40, 15)):
|
||||
text = "\n".join(install.tui_view(state, cols, rows))
|
||||
self.assertIn("3 files to download, 600 B", text)
|
||||
self.assertIn("For your 1 of 3 systems", text)
|
||||
# tui_audit_6 P3-4: the headline counts the ticked systems.
|
||||
self.assertIn("About 1 file, 16.0 KB, for 1 of 3 systems", " ".join(text.split()))
|
||||
self.assertNotIn("3 files to download", text)
|
||||
|
||||
def test_p2_4_no_network_is_said_at_once(self):
|
||||
import socket
|
||||
@@ -1622,7 +1623,7 @@ class AuditRoundTwo(unittest.TestCase):
|
||||
press(state, "enter")
|
||||
install.tui_receive(state, (kind, plat, title, lines, code))
|
||||
self.assertEqual([row.action for row in install.tui_rows(state)],
|
||||
["retry", "back", "quit"])
|
||||
["retry", "elsewhere", "quit"])
|
||||
|
||||
def test_p2_4_the_clock_says_so(self):
|
||||
import ssl
|
||||
@@ -2043,7 +2044,7 @@ class CopyFromAnOldCard(unittest.TestCase):
|
||||
state.local_dests = {"scph5500.bin": (str(SYSTEM_DIR), "nested folder: bios/a")}
|
||||
state.finished = [("scph5500.bin", True, ""), ("gba_bios.bin", True, "")]
|
||||
text = " ".join(" ".join(install.tui_outcome(state)[1]).split())
|
||||
self.assertIn("1 file fixed from copies already in the BIOS folder, 1 downloaded. "
|
||||
self.assertIn("1 file copied from the wrong place in the BIOS folder, 1 downloaded. "
|
||||
"Your copies in the wrong place were left as they are.", text)
|
||||
|
||||
def test_a_local_copy_is_no_download_speed(self):
|
||||
@@ -2119,12 +2120,12 @@ class AuditRoundThree(unittest.TestCase):
|
||||
rules = {rule.name: rule for rule in install._card_rules()}
|
||||
self.assertLessEqual({"muOS", "Onion", "spruceOS", "CrossMix-OS", "Allium", "Koriki",
|
||||
"KNULLI", "ROCKNIX"}, set(rules))
|
||||
device = {rule.name: rule for rule in install._EMBEDDED_RULES
|
||||
if rule.values and rule.values[0].startswith(install._CARD_MOUNTS)}
|
||||
for name, rule in device.items():
|
||||
if rule.bios and rule.manifest:
|
||||
with self.subTest(system=name):
|
||||
self.assertTrue(rule.bios.endswith("/" + rules[name].bios))
|
||||
# Only a marker on the part its BIOS folder is on names the card:
|
||||
# plumOS's and the Anbernic firmware's are on another part.
|
||||
for setup in install.card_setups():
|
||||
if setup.rules:
|
||||
with self.subTest(system=setup.name):
|
||||
self.assertEqual(rules[setup.name].bios, setup.below)
|
||||
self.assertEqual(install.DEFAULT_DESTS["knulli"], Path("/userdata") / "bios")
|
||||
self.assertEqual(install.DEFAULT_DESTS["rocknix"], Path("/storage") / "roms/bios")
|
||||
|
||||
@@ -2189,7 +2190,8 @@ class AuditRoundThree(unittest.TestCase):
|
||||
root = self.card({"roms/": ""})
|
||||
proc = install_run("--platform", "muos", "--dest", str(root), "--yes")
|
||||
self.assertEqual(proc.returncode, 1)
|
||||
self.assertIn(f"{root} is not a muOS card: it holds no MUOS.", proc.stderr)
|
||||
self.assertIn(f"{root} is not a muOS SD card: no muOS files on it. muOS keeps "
|
||||
"MUOS at the root of its card.", proc.stderr)
|
||||
self.assertIn("--dest <card>/MUOS/bios", proc.stderr)
|
||||
self.assertEqual(list(root.iterdir()), [root / "roms"])
|
||||
# Its BIOS folder named outright is taken as given.
|
||||
@@ -2210,7 +2212,7 @@ class AuditRoundThree(unittest.TestCase):
|
||||
with self.assertRaises(SystemExit), \
|
||||
contextlib.redirect_stderr(io.StringIO()) as err:
|
||||
install.card_dest("muos", "retroarch", stray)
|
||||
self.assertIn("is not a muOS card", err.getvalue())
|
||||
self.assertIn("is not a muOS SD card", err.getvalue())
|
||||
self.assertEqual(install.card_dest("muos", "retroarch", root / "muos" / "BIOS"),
|
||||
("retroarch", root / "muos" / "BIOS"))
|
||||
|
||||
@@ -2385,8 +2387,8 @@ class AuditRoundThree(unittest.TestCase):
|
||||
state.summary = {"installed": 4, "up_to_date": 0, "failed": [
|
||||
{"dest": "fc/disksys.rom", "reason": "HTTP 404"}]}
|
||||
_title, lines = install.tui_outcome(state)
|
||||
self.assertEqual(lines[1], "2 files copied from OLD, 1 fixed from copies "
|
||||
"already in the BIOS folder, 1 downloaded, 1 still missing.")
|
||||
self.assertEqual(lines[1], "2 files copied from OLD, 1 copied from the wrong place "
|
||||
"in the BIOS folder, 1 downloaded, 1 still missing.")
|
||||
# The line mode's own sentence, from the same counts.
|
||||
self.assertEqual(lines[1], install.sources_line([("OLD", 2)], 1, 1, 1))
|
||||
|
||||
@@ -2862,7 +2864,7 @@ class ACardSystemNamedOnAComputer(unittest.TestCase):
|
||||
contextlib.redirect_stdout(io.StringIO()) as out:
|
||||
dest = install.card_install_dest("onion", "retroarch", interactive=True)
|
||||
self.assertEqual(dest, onion / "BIOS")
|
||||
self.assertIn("Mount the card, then type its root folder.", out.getvalue())
|
||||
self.assertIn("Mount the card, then type its top folder.", out.getvalue())
|
||||
ask.assert_called_once()
|
||||
knulli = self.card({"roms/a": ""})
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[]), \
|
||||
@@ -2892,8 +2894,8 @@ class ACardSystemNamedOnAComputer(unittest.TestCase):
|
||||
dest = install.card_install_dest("onion", "retroarch", interactive=True)
|
||||
self.assertEqual(dest, onion / "BIOS")
|
||||
self.assertEqual(len(asked), 3)
|
||||
self.assertIn("8 does not exist, or is not a folder. Type the root of the Onion card.",
|
||||
out.getvalue())
|
||||
self.assertIn("8 does not exist, or is not a folder. Type the top folder of the Onion "
|
||||
"card.", out.getvalue())
|
||||
self.assertFalse((REPO_ROOT / "tmp" / "no-such").exists())
|
||||
|
||||
def test_a_typed_root_that_is_no_card_of_that_system_is_asked_again(self):
|
||||
@@ -2904,7 +2906,8 @@ class ACardSystemNamedOnAComputer(unittest.TestCase):
|
||||
contextlib.redirect_stdout(io.StringIO()) as out:
|
||||
dest = install.card_install_dest("onion", "retroarch", interactive=True)
|
||||
self.assertEqual((dest, len(asked)), (onion / "BIOS", 2))
|
||||
self.assertIn(f"{blank} is not a Onion card: it holds no .tmp_update.", out.getvalue())
|
||||
self.assertIn(f"{blank} is not an Onion SD card: no Onion files on it. Onion keeps "
|
||||
".tmp_update at the root of its card.", out.getvalue())
|
||||
|
||||
def test_a_minui_root_is_a_minui_card(self):
|
||||
blank = self.card({"roms/a": ""})
|
||||
@@ -2915,31 +2918,45 @@ class ACardSystemNamedOnAComputer(unittest.TestCase):
|
||||
dest = install.card_install_dest("nextui", "nextui", interactive=True)
|
||||
self.assertEqual((dest, len(asked)), (minui, 3))
|
||||
self.assertIn(f"is inside a NextUI card, whose root is {minui}", out.getvalue())
|
||||
self.assertIn("holds no .system/version.txt: it is not a NextUI card", out.getvalue())
|
||||
self.assertIn("is not a NextUI SD card: no NextUI files on it. NextUI keeps "
|
||||
".system/version.txt at the root of its card.", out.getvalue())
|
||||
|
||||
def test_the_mounted_drives_are_listed_and_taken_by_number(self):
|
||||
"""tui_audit_5 P3-8.4: the screen lists the mounted cards, the
|
||||
prompt did not."""
|
||||
prompt did not. tui_audit_6 P3-8, code_audit_13 P3-6: it listed
|
||||
every drive, a muOS card beside Onion's question, and the muOS card
|
||||
taken by number made the run a muOS install."""
|
||||
muos, blank = self.card({"MUOS/bios/x": ""}), self.card({"roms/a": ""})
|
||||
patcher, _asked = self.ask("2")
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[muos, blank]), \
|
||||
first, second = (self.card({"system/batocera.conf": "system.hostname=KNULLI\n"})
|
||||
for _card in range(2))
|
||||
patcher, asked = self.ask("3", "2")
|
||||
with mock.patch.object(install, "_mounted_cards",
|
||||
return_value=[muos, first, blank, second]), \
|
||||
patcher, contextlib.redirect_stdout(io.StringIO()) as out:
|
||||
dest = install.card_install_dest("knulli", "knulli", interactive=True)
|
||||
self.assertEqual(dest, blank / "bios")
|
||||
self.assertIn(f"2) {blank} (card or drive)", out.getvalue())
|
||||
self.assertIn(f"1) {muos} (muOS card)", out.getvalue())
|
||||
self.assertEqual((dest, len(asked)), (second / "bios", 2))
|
||||
self.assertIn(f"1) {first.name} (KNULLI card, {first})", out.getvalue())
|
||||
self.assertIn(f"2) {second.name} (KNULLI card, {second})", out.getvalue())
|
||||
self.assertNotIn(str(muos), out.getvalue())
|
||||
self.assertNotIn(str(blank), out.getvalue())
|
||||
self.assertIn("Type 1 to 2, or a folder.", out.getvalue())
|
||||
|
||||
def test_creating_several_folders_on_the_card_is_asked(self):
|
||||
"""tui_audit_6 P3-8: N to the question ended the whole run where it
|
||||
meant "not that card"."""
|
||||
root = self.card({"roms/a.txt": ""})
|
||||
rocknix = root / "R"
|
||||
rocknix.mkdir()
|
||||
patcher, asked = self.ask(str(rocknix), "n")
|
||||
card = self.card({"roms/a": ""})
|
||||
make_card(card, "ROCKNIX")
|
||||
patcher, asked = self.ask(str(rocknix), "n", str(card))
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[]), patcher, \
|
||||
contextlib.redirect_stdout(io.StringIO()), \
|
||||
self.assertRaises(SystemExit) as stop:
|
||||
install.card_install_dest("rocknix", "rocknix", interactive=True)
|
||||
self.assertEqual(stop.exception.code, 2)
|
||||
self.assertIn("[y/N]", asked[-1])
|
||||
contextlib.redirect_stdout(io.StringIO()) as out:
|
||||
dest = install.card_install_dest("rocknix", "rocknix", interactive=True)
|
||||
self.assertEqual(dest, card / "roms" / "bios")
|
||||
self.assertIn("[y/N]", asked[1])
|
||||
self.assertEqual(asked[2], "Card root (Ctrl+C to stop): ")
|
||||
self.assertIn("Not created.", out.getvalue())
|
||||
self.assertFalse((rocknix / "roms").exists())
|
||||
|
||||
def test_the_menu_asks_a_card_system_for_its_card(self):
|
||||
@@ -3018,13 +3035,16 @@ class ACardSystemNamedOnAComputer(unittest.TestCase):
|
||||
install._browse_to(state, blank)
|
||||
effects = press(state, "enter")
|
||||
self.assertEqual((effects, state.screen), ([], "browse"))
|
||||
self.assertIn(f"{blank} is not a Onion card: it holds no .tmp_update.",
|
||||
state.status)
|
||||
self.assertIn("Not an Onion SD card: no Onion files on it.", state.status)
|
||||
self.assertIn(f"{blank} is not an Onion SD card", state.status_more)
|
||||
self.assertIsNone(state.dest)
|
||||
# A muOS card gets the folder muOS reads, as --dest does.
|
||||
# tui_audit_6 P3-8: a muOS card made the run a muOS install
|
||||
# without a word.
|
||||
install._browse_to(state, muos)
|
||||
press(state, "enter")
|
||||
self.assertEqual(state.dest, muos / "MUOS" / "bios")
|
||||
self.assertEqual(state.status, "That is a muOS card, not an Onion card. Choose "
|
||||
"the card's top folder.")
|
||||
self.assertIsNone(state.dest)
|
||||
|
||||
def test_a_typed_card_root_is_checked_on_the_path_screen(self):
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[]), \
|
||||
@@ -3036,8 +3056,8 @@ class ACardSystemNamedOnAComputer(unittest.TestCase):
|
||||
state.path_text = str(REPO_ROOT / "tmp" / "no-such-card")
|
||||
effects = press(state, "enter")
|
||||
self.assertEqual((effects, state.screen), ([], "path"))
|
||||
self.assertIn("does not exist, or is not a folder. Choose the root of the "
|
||||
"ROCKNIX card.", state.status)
|
||||
self.assertEqual("That folder does not exist. Choose the card's top folder.",
|
||||
state.status)
|
||||
|
||||
def test_a_dest_that_is_no_card_of_that_system_is_refused(self):
|
||||
blank = self.card({"roms/a": ""})
|
||||
@@ -3047,7 +3067,7 @@ class ACardSystemNamedOnAComputer(unittest.TestCase):
|
||||
state, effects = install.tui_start(_args(platform="onion", dest=str(blank)),
|
||||
"linux")
|
||||
self.assertEqual((effects, state.screen), ([], "folder"))
|
||||
self.assertIn("is not a Onion card", state.status)
|
||||
self.assertIn("Not an Onion SD card", state.status)
|
||||
|
||||
def test_change_folder_names_the_folder_it_reuses(self):
|
||||
"""code_audit_12 P3-1: Use this folder on the card screen named
|
||||
@@ -3125,14 +3145,22 @@ class TheSetupFilterKnowsDevices(unittest.TestCase):
|
||||
|
||||
def test_the_right_column_names_what_matched(self):
|
||||
rows = self.rows("miyoo")
|
||||
retroarch = {row.value: row for row in rows}["retroarch"]
|
||||
self.assertEqual(retroarch.right, "MiyooCFW")
|
||||
# tui_audit_6 P1-1, code_audit_13 P2-3: MiyooCFW stayed on the
|
||||
# RetroArch row, which opened this computer's folder.
|
||||
self.assertNotIn("retroarch", [row.value for row in rows if row.action == "platform"])
|
||||
self.assertEqual([row.label for row in rows if row.action == "cardsystem"],
|
||||
["spruceOS, SD card", "Onion, SD card", "Allium, SD card",
|
||||
"Koriki, SD card"])
|
||||
["Allium, SD card", "Koriki, SD card", "MiyooCFW, SD card",
|
||||
"Onion, SD card", "spruceOS, SD card"])
|
||||
spruce = {row.label: row for row in rows}["spruceOS, SD card"]
|
||||
self.assertEqual(spruce.right, "Miyoo A30, Miyoo Flip, Miyoo Mini, Miyoo Mini Plus, "
|
||||
"Miyoo Mini Flip")
|
||||
# Cut at a comma, never inside a name ("Miyoo ...s").
|
||||
self.assertIn("Miyoo A30, Miyoo Flip, +3", spruce.narrow)
|
||||
line = str(install._row_line(spruce, False, 60))
|
||||
self.assertTrue(line.rstrip().endswith(("+1", "+2", "+3", "+4")), line)
|
||||
deck = {row.value: row for row in self.rows("steam deck")}
|
||||
self.assertEqual(deck["retroarch"].right, "Steam Deck")
|
||||
self.assertIn("muOS", {row.value: row for row in self.rows("")}["retroarch"].right)
|
||||
self.assertEqual({row.value: row for row in self.rows("")}["retroarch"].right, "")
|
||||
|
||||
def test_the_handheld_lists_are_the_guides(self):
|
||||
try:
|
||||
@@ -3160,16 +3188,17 @@ class ACardSetupIsOneDesign(unittest.TestCase):
|
||||
return state
|
||||
|
||||
def test_a_handheld_typed_in_the_filter_asks_for_its_card(self):
|
||||
for needle in ("onion", "miyoo mini", "rg35xx"):
|
||||
for needle in ("onion", "miyoo mini", "rg35xx", "r36s", "arkos", "anbernic"):
|
||||
with self.subTest(needle=needle):
|
||||
state = self.platforms(needle)
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[]):
|
||||
row = install.tui_rows(state)[1]
|
||||
effects = press(state, "enter")
|
||||
text = " ".join(" ".join(install.tui_view(state, 80, 24)).split())
|
||||
self.assertEqual(row.action, "cardsystem")
|
||||
plat, name = row.value if row.action == "cardsystem" else (row.value,) * 2
|
||||
self.assertEqual((effects, state.screen), ([], "folder"))
|
||||
self.assertEqual(state.card_bound, install.card_bound(row.value[1], "retroarch"))
|
||||
self.assertIsNotNone(state.card_bound)
|
||||
self.assertEqual(state.card_bound, install.card_bound(name, plat))
|
||||
self.assertIn("Where is the SD card?", text)
|
||||
self.assertNotIn("default", [r.action for r in install.tui_rows(state)])
|
||||
self.assertNotIn(str(SYSTEM_DIR), text)
|
||||
@@ -3313,7 +3342,9 @@ class OneSystemInFewPresses(unittest.TestCase):
|
||||
state = self.long_list("keys")
|
||||
state.stack.append("systems")
|
||||
state.focus["systems"] = 5
|
||||
self.assertEqual(press(state, "enter"), [("run", "install")])
|
||||
# tui_audit_6 P2-1: Continue opens Confirm, which waits for A.
|
||||
self.assertEqual(press(state, "enter"), [("run", "confirm")])
|
||||
self.assertEqual((state.screen, state.must_confirm), ("confirm", True))
|
||||
self.assertEqual(len(state.ticked), 66)
|
||||
|
||||
def test_left_and_right_page_inside_muxterm_only(self):
|
||||
@@ -3499,8 +3530,10 @@ class AuditFive(unittest.TestCase):
|
||||
"reason": "misplaced"}]
|
||||
with mock.patch.object(install.LOCAL, "pack", mock.Mock()):
|
||||
text = " ".join(" ".join(install.tui_view(state, 120, 40)).split())
|
||||
self.assertIn("1 copied from this machine,", text)
|
||||
self.assertIn("from the pack", text)
|
||||
# tui_audit_6 P3-3: one count, "4 files to install" above "3 from
|
||||
# the pack", where "3 to install from the pack" sat over "4".
|
||||
self.assertIn("4 files to install, 1.0 MB", text)
|
||||
self.assertIn("3 from the pack, 1 copied from this machine", text)
|
||||
self.assertNotIn("downloaded", text)
|
||||
self.assertNotIn("of them", text)
|
||||
state.finished = [(FILES[0]["dest"], True, ""), (FILES[1]["dest"], True, "")]
|
||||
@@ -3529,7 +3562,7 @@ class AuditFive(unittest.TestCase):
|
||||
state.stack.append("systems")
|
||||
state.focus["systems"] = 3
|
||||
lines = install.tui_view(state, 40, 12)
|
||||
self.assertIn(" +1 shared: counted once", lines)
|
||||
self.assertIn(" Shared, counted once", lines)
|
||||
|
||||
def test_the_save_folder_remedy_is_the_same_on_both_screens(self):
|
||||
summary = {"skipped": [{"reason": "no_save_directory", "files": 1}]}
|
||||
@@ -3550,7 +3583,9 @@ class AuditFive(unittest.TestCase):
|
||||
state.focus["systems"] = 3
|
||||
bar = install.tui_view(state, 40, 15)[-1]
|
||||
self.assertIn("A Tick", bar)
|
||||
self.assertTrue(bar.strip().startswith("Start Only this system"))
|
||||
self.assertTrue(bar.strip().startswith("Start Only this"))
|
||||
# tui_audit_6 P3-9.1: Back was the entry given up at 40 columns.
|
||||
self.assertIn("R2 Back", bar)
|
||||
|
||||
def test_muxterm_help_names_no_home_key(self):
|
||||
state = self.long_list()
|
||||
@@ -3573,14 +3608,20 @@ class LineModeOffline(unittest.TestCase):
|
||||
"--dest", str(repo.dest), "--offline"], env)
|
||||
term.wait("q) quit")
|
||||
term.send("\r")
|
||||
term.close()
|
||||
code = term.close()
|
||||
out = term.raw.decode("utf-8", "replace")
|
||||
self.assertIn("--offline: only the files found on this machine are installed.", out)
|
||||
self.assertIn("--offline: only the files found on this machine are installed, and no "
|
||||
"--from names a folder to copy them from.", out)
|
||||
self.assertIn("Enter) install what is found on this machine", out)
|
||||
self.assertIn("5 files need the internet, which --offline does not use.", out)
|
||||
self.assertNotIn("Downloading", out)
|
||||
self.assertNotIn("failed", out.lower())
|
||||
self.assertIn("Nothing installed: 5 files not downloaded, which --offline does not do.",
|
||||
out.replace("\r\n", " ").replace("\n", " "))
|
||||
# tui_audit_6 P2-3, code_audit_13 P1-1: nothing installed ended on
|
||||
# exit 0, where the screen's run gives 2.
|
||||
self.assertIn("Nothing installed: 5 files need the internet, which --offline does "
|
||||
"not use.", out.replace("\r\n", " ").replace("\n", " "))
|
||||
self.assertNotIn("already up to date", out)
|
||||
self.assertEqual(code, 2)
|
||||
|
||||
def test_the_data_files_are_counted_before_the_question(self):
|
||||
files = [{"dest": "a.bin", "size": 1024}]
|
||||
@@ -5030,5 +5071,483 @@ class AFocusesNoSystemFolder(unittest.TestCase):
|
||||
self.assertEqual(row.action, "dir")
|
||||
|
||||
|
||||
|
||||
def _card_from_rules(root: Path, setup: install.CardSetup) -> Path:
|
||||
"""A card as setup's system leaves it, written from the rules that
|
||||
tell it: a test that names each marker by hand misses the next one."""
|
||||
root.mkdir(parents=True, exist_ok=True)
|
||||
if setup.plat in install.CARD_PLATFORMS:
|
||||
(root / ".system").mkdir(exist_ok=True)
|
||||
prefix = next(prefix for name, _marker, prefix in install._CARD_RULES
|
||||
if name == setup.plat)
|
||||
(root / install.CARD_MARKER).write_text(f"{prefix}20250101\n", encoding="utf-8")
|
||||
for rule in setup.rules[:1]:
|
||||
if rule.method == "file_matches":
|
||||
path, pattern = rule.values
|
||||
text = re.sub(r"\\(.)", r"\1", pattern.strip("^$").replace(r"\s*", ""))
|
||||
(root / path).parent.mkdir(parents=True, exist_ok=True)
|
||||
(root / path).write_text(text + "\n", encoding="utf-8")
|
||||
continue
|
||||
for value in rule.values:
|
||||
(root / value).parent.mkdir(parents=True, exist_ok=True)
|
||||
(root / value).write_text("", encoding="utf-8")
|
||||
return root
|
||||
|
||||
|
||||
def _setup_folder(setup: install.CardSetup, card: Path) -> Path:
|
||||
return card / setup.below if setup.below else card
|
||||
|
||||
|
||||
class EveryCardSetupGoesToItsCard(unittest.TestCase):
|
||||
"""code_audit_13 P2-3, tui_audit_6 P1-1: the card setups were fixed one
|
||||
by one, and UnofficialOS, ArchR, ArkOS, MiyooCFW and the Anbernic
|
||||
firmware stayed on the RetroArch row, which listed them and opened this
|
||||
computer's folder. Each system that runs from its SD card, from every
|
||||
way in, goes to its card."""
|
||||
|
||||
def setUp(self):
|
||||
self.root = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp"))
|
||||
self.addCleanup(shutil.rmtree, self.root, True)
|
||||
self.setups = install.card_setups()
|
||||
|
||||
def test_one_list_holds_every_card_system(self):
|
||||
names = {setup.name for setup in self.setups}
|
||||
self.assertLessEqual({rule.name for rule in install._card_rules()}, names)
|
||||
self.assertLessEqual(set(install._systems_reading()["retroarch"]), names)
|
||||
self.assertLessEqual({install.display_name(plat) for plat in install.CARD_PLATFORMS},
|
||||
names)
|
||||
self.assertLessEqual({"Onion", "spruceOS", "muOS", "JELOS", "ROCKNIX", "KNULLI",
|
||||
"ArkOS", "dArkOS", "UnofficialOS", "ArchR", "MiyooCFW",
|
||||
"Anbernic stock firmware", "Allium", "Koriki", "CrossMix-OS",
|
||||
"MinUI", "NextUI", "MyMinUI"}, names)
|
||||
self.assertEqual(len(names), len(self.setups))
|
||||
# A system the guide writes is one of them.
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
return
|
||||
guides = yaml.safe_load((REPO_ROOT / "platforms" / "_guides.yml").read_text())
|
||||
for system in guides["handheld_guide"]["systems"]:
|
||||
with self.subTest(system=system["name"]):
|
||||
self.assertIn(system["name"], names)
|
||||
|
||||
def test_its_folder_is_the_one_the_guide_names(self):
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
self.skipTest("pyyaml is not installed")
|
||||
guides = yaml.safe_load((REPO_ROOT / "platforms" / "_guides.yml").read_text())
|
||||
below = {setup.name: setup.below for setup in self.setups}
|
||||
for system in guides["handheld_guide"]["systems"]:
|
||||
folder = re.search(r"`([^`]+)`", system.get("folder", ""))
|
||||
if folder:
|
||||
with self.subTest(system=system["name"]):
|
||||
self.assertTrue(folder.group(1).endswith(below[system["name"]]),
|
||||
(folder.group(1), below[system["name"]]))
|
||||
|
||||
def platforms(self, needle: str = "") -> install.TuiState:
|
||||
state = fresh_state()
|
||||
state.stack = ["setup", "platforms"]
|
||||
state.filters["platforms"] = needle
|
||||
return state
|
||||
|
||||
def test_the_setup_list_has_a_row_for_each_without_the_filter(self):
|
||||
state = self.platforms()
|
||||
rows = install.tui_rows(state)
|
||||
self.assertEqual({row.value: row for row in rows if row.action == "platform"}[
|
||||
"retroarch"].right, "")
|
||||
for setup in self.setups:
|
||||
with self.subTest(system=setup.name):
|
||||
state = self.platforms()
|
||||
rows = install.tui_rows(state)
|
||||
index = next(i for i, row in enumerate(rows)
|
||||
if row.label == f"{setup.name}, SD card")
|
||||
state.focus["platforms"] = index
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[]):
|
||||
effects = press(state, "enter")
|
||||
text = " ".join(" ".join(install.tui_view(state, 80, 24)).split())
|
||||
self.assertEqual((effects, state.screen), ([], "folder"))
|
||||
self.assertEqual(state.card_bound, (setup.name, setup.below))
|
||||
self.assertIsNone(state.folder_default)
|
||||
self.assertIn("Where is the SD card?", text)
|
||||
self.assertNotIn(str(SYSTEM_DIR), text)
|
||||
|
||||
def test_its_name_in_the_filter_finds_its_row(self):
|
||||
for setup in self.setups:
|
||||
with self.subTest(system=setup.name):
|
||||
rows = install.tui_rows(self.platforms(setup.name))
|
||||
self.assertIn(f"{setup.name}, SD card", [row.label for row in rows])
|
||||
|
||||
def test_platform_named_on_a_computer_asks_for_the_card(self):
|
||||
for setup in self.setups:
|
||||
with self.subTest(system=setup.name):
|
||||
plat = install.normalize_platform(setup.name, say=False)
|
||||
self.assertEqual(plat, setup.plat)
|
||||
self.assertEqual(install.card_bound(setup.name, plat),
|
||||
(setup.name, setup.below))
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[]), \
|
||||
contextlib.redirect_stderr(io.StringIO()) as err, \
|
||||
self.assertRaises(SystemExit) as stop:
|
||||
install.card_install_dest(setup.name, plat, interactive=False)
|
||||
self.assertEqual(stop.exception.code, 1)
|
||||
self.assertIn(f"{setup.name} keeps its BIOS files on its SD card",
|
||||
err.getvalue())
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[]), \
|
||||
mock.patch.object(install, "detect_platforms", return_value=[
|
||||
("retroarch", SYSTEM_DIR)]), \
|
||||
mock.patch.object(install, "detect_frontends", return_value=[]):
|
||||
state, effects = install.tui_start(_args(platform=setup.name), "linux")
|
||||
self.assertEqual((effects, state.screen), ([], "folder"))
|
||||
self.assertEqual(state.card_bound, (setup.name, setup.below))
|
||||
self.assertIsNone(state.folder_default)
|
||||
|
||||
def test_the_line_menu_offers_it_and_asks_for_its_card(self):
|
||||
offered = [name for name, _label in install._line_setups()]
|
||||
for setup in self.setups:
|
||||
with self.subTest(system=setup.name):
|
||||
key = setup.plat if setup.name == install.display_name(setup.plat) \
|
||||
else setup.name
|
||||
self.assertIn(key, offered)
|
||||
card = _card_from_rules(self.root / f"menu{offered.index(key)}", setup)
|
||||
with mock.patch.object(install, "_choose_platform", return_value=key), \
|
||||
mock.patch.object(install, "_mounted_cards", return_value=[]), \
|
||||
mock.patch.object(install, "_ask", return_value=str(card)), \
|
||||
contextlib.redirect_stdout(io.StringIO()):
|
||||
chosen = install._prompt_manual_platform("linux", ask=False)
|
||||
self.assertEqual(chosen, [(setup.plat, _setup_folder(setup, card))])
|
||||
|
||||
def test_its_card_gives_one_folder_whichever_way_it_is_named(self):
|
||||
for index, setup in enumerate(self.setups):
|
||||
with self.subTest(system=setup.name):
|
||||
card = _card_from_rules(self.root / f"card{index}", setup)
|
||||
want = (_setup_folder(setup, card) if setup.known() or not setup.below
|
||||
else card)
|
||||
with contextlib.redirect_stdout(io.StringIO()):
|
||||
by_dest = install.card_dest(setup.name, setup.plat, card)
|
||||
self.assertEqual(by_dest, (setup.plat, want))
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[]), \
|
||||
mock.patch.object(install, "detect_platforms", return_value=[]), \
|
||||
mock.patch.object(install, "detect_frontends", return_value=[]):
|
||||
state, _effects = install.tui_start(
|
||||
_args(platform=setup.name, dest=str(card)), "linux")
|
||||
self.assertEqual(state.dest, want)
|
||||
# --dest alone, then the setup's row: the folder of the
|
||||
# same --dest (code_audit_13 P2-2).
|
||||
state, _effects = install.tui_start(_args(dest=str(card)), "linux")
|
||||
if state.screen == "platforms":
|
||||
rows = install.tui_rows(state)
|
||||
label = (f"{setup.name}, SD card")
|
||||
state.focus["platforms"] = [row.label for row in rows].index(label)
|
||||
press(state, "enter")
|
||||
self.assertEqual(state.dest, want)
|
||||
# Its card chosen as a card's root: its BIOS folder below it.
|
||||
if setup.known():
|
||||
choice = install.card_root_folder(setup.name, setup.plat, card)
|
||||
self.assertEqual((choice.refused, choice.folder),
|
||||
("", _setup_folder(setup, card)))
|
||||
|
||||
def test_another_systems_card_is_refused_for_each(self):
|
||||
"""code_audit_13 P2-1, tui_audit_6 P2-5: KNULLI and ROCKNIX took a
|
||||
muOS or an Onion card, and wrote their layout into it."""
|
||||
cards = {}
|
||||
for name in ("muOS", "Onion", "MinUI"):
|
||||
setup = next(item for item in self.setups if item.name == name)
|
||||
cards[name] = _card_from_rules(self.root / name, setup)
|
||||
for setup in self.setups:
|
||||
for name, card in cards.items():
|
||||
if name == setup.name or (name == "MinUI"
|
||||
and setup.plat in install.CARD_PLATFORMS):
|
||||
continue
|
||||
with self.subTest(system=setup.name, card=name):
|
||||
choice = install.card_root_folder(setup.name, setup.plat, card)
|
||||
self.assertIn(f"is {install._a(name)} card, not "
|
||||
f"{install._a(setup.name)} card", choice.refused)
|
||||
self.assertTrue(install.card_choice(setup.name, setup.plat,
|
||||
card).refused)
|
||||
with mock.patch.object(install, "_mounted_cards",
|
||||
return_value=list(cards.values())):
|
||||
self.assertNotIn(card, install.mounted_cards_of(setup.name,
|
||||
setup.plat))
|
||||
|
||||
def test_a_blank_drive_is_refused_where_the_card_always_names_its_system(self):
|
||||
blank = self.root / "BLANK"
|
||||
blank.mkdir()
|
||||
for setup in self.setups:
|
||||
with self.subTest(system=setup.name):
|
||||
choice = install.card_root_folder(setup.name, setup.plat, blank)
|
||||
if setup.known() and not setup.fresh:
|
||||
self.assertIn(f"is not {install._a(setup.name)} SD card", choice.refused)
|
||||
else:
|
||||
self.assertEqual((choice.refused, choice.folder),
|
||||
("", _setup_folder(setup, blank)))
|
||||
self.assertTrue(choice.note)
|
||||
|
||||
|
||||
class AuditSix(unittest.TestCase):
|
||||
"""tui_audit_6 and code_audit_13: what remains of each finding."""
|
||||
|
||||
def setUp(self):
|
||||
self.root = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp"))
|
||||
self.addCleanup(shutil.rmtree, self.root, True)
|
||||
|
||||
def onion(self, name: str = "ONION") -> Path:
|
||||
card = self.root / name
|
||||
make_card(card, "Onion")
|
||||
return card
|
||||
|
||||
def test_continue_never_installs_without_confirm(self):
|
||||
"""P2-1: A on a system, the ticks unchanged, installed at once,
|
||||
offline too where the plan had no Install."""
|
||||
state = checked_state()
|
||||
press(state, "down", "enter")
|
||||
self.assertEqual(state.screen, "systems")
|
||||
state.focus["systems"] = 3
|
||||
self.assertEqual(install._primary(state), "A/Enter Continue")
|
||||
self.assertEqual(press(state, "enter"), [("run", "confirm")])
|
||||
self.assertEqual(state.screen, "confirm")
|
||||
# The confirm run's plan is the same: it still waits for A.
|
||||
install.tui_receive(state, ("event", state.run_id, dict(CHECK)))
|
||||
self.assertEqual(install.tui_receive(state, ("ended", state.run_id, 0, [])), [])
|
||||
self.assertEqual(state.screen, "confirm")
|
||||
|
||||
def test_offline_with_nothing_on_hand_runs_nothing_from_the_list(self):
|
||||
state = checked_state()
|
||||
with mock.patch.dict(os.environ, {install.OFFLINE_VARIABLE: "1"}):
|
||||
state.focus["plan"] = [row.action for row in install.tui_rows(state)].index(
|
||||
"systems")
|
||||
press(state, "enter")
|
||||
state.focus["systems"] = 3
|
||||
effects = press(state, "enter")
|
||||
self.assertEqual(effects, [("run", "confirm")])
|
||||
install.tui_receive(state, ("event", state.run_id, dict(CHECK)))
|
||||
for event in FILES:
|
||||
install.tui_receive(state, ("event", state.run_id, dict(event)))
|
||||
install.tui_receive(state, ("ended", state.run_id, 0, []))
|
||||
self.assertEqual([row.action for row in install.tui_rows(state)], ["back"])
|
||||
view = install.tui_view(state, 40, 12)
|
||||
text = " ".join(" ".join(view).split())
|
||||
self.assertEqual(state.screen, "confirm")
|
||||
# code_audit_13 P3-3: Back alone, no word of an Install.
|
||||
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")
|
||||
|
||||
def test_a_refusal_shows_at_40x12_on_type_a_path(self):
|
||||
"""P2-2: Enter seemed to do nothing, the refusal drawn below the
|
||||
last line."""
|
||||
blank = self.root / "USBSTICK"
|
||||
blank.mkdir()
|
||||
state = fresh_state()
|
||||
state.stack = ["setup", "folder", "path"]
|
||||
state.platform, state.card_bound = "retroarch", ("Onion", "BIOS")
|
||||
state.path_text = str(blank)
|
||||
press(state, "enter")
|
||||
self.assertEqual(state.screen, "path")
|
||||
text = " ".join(" ".join(install.tui_view(state, 40, 12)).split())
|
||||
self.assertIn("Not an Onion SD card: no Onion files on it.", text)
|
||||
self.assertNotIn("Ctrl-U clears", text)
|
||||
# P3-1: no hidden folder named in the short form, the detail after.
|
||||
self.assertNotIn(".tmp_update", state.status)
|
||||
self.assertIn(".tmp_update", state.status_more)
|
||||
# code_audit_13 P3-5: the prompt asks for the card.
|
||||
self.assertIn("The top folder of the Onion SD card:", text)
|
||||
|
||||
def test_the_help_says_the_refusal_in_full(self):
|
||||
state = fresh_state()
|
||||
state.stack = ["setup", "folder"]
|
||||
state.platform, state.card_bound = "retroarch", ("Onion", "BIOS")
|
||||
blank = self.root / "STICK"
|
||||
blank.mkdir()
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[]):
|
||||
install._choose_card(state, blank)
|
||||
press(state, "?")
|
||||
text = " ".join(" ".join(install.tui_view(state, 80, 24)).split())
|
||||
self.assertIn("STICK is not an Onion SD card: no Onion files on it. Onion keeps "
|
||||
".tmp_update at the root of its card.", text)
|
||||
|
||||
def test_wsl_drive_letters_are_taken_as_typed(self):
|
||||
"""P2-4: the screen says D:, and D: typed was refused."""
|
||||
with mock.patch.dict(install._WSL, {"active": True}):
|
||||
for typed in ("D:", "D:\\", "d:\\", "\"D:\\\""):
|
||||
with self.subTest(typed=typed):
|
||||
self.assertEqual(install._typed_folder(typed), Path("/mnt/d"))
|
||||
self.assertEqual(install.typed_path(typed), Path("/mnt/d"))
|
||||
self.assertEqual(install._typed_folder("E:\\bios"), Path("/mnt/e/bios"))
|
||||
args = _args(dest=Path("D:\\"))
|
||||
install._wsl_dest(args)
|
||||
self.assertEqual(args.dest, Path("/mnt/d"))
|
||||
card = Path("/mnt/d")
|
||||
with mock.patch.object(install, "_card_what", return_value="Onion card"):
|
||||
self.assertEqual(install.card_line(card), "D: (Onion card, /mnt/d)")
|
||||
self.assertEqual(install._typed_folder("D:"), Path("D:"))
|
||||
|
||||
def test_a_dest_refused_on_the_setup_list_names_dest(self):
|
||||
"""code_audit_13 P3-2: "Choose the root of the Onion card", where
|
||||
--dest fixes the folder, and the refused system stayed chosen."""
|
||||
blank = self.root / "USBSTICK"
|
||||
blank.mkdir()
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[]), \
|
||||
mock.patch.object(install, "detect_platforms", return_value=[]), \
|
||||
mock.patch.object(install, "detect_frontends", return_value=[]):
|
||||
state, _effects = install.tui_start(_args(dest=str(blank)), "linux")
|
||||
state.filters["platforms"] = "onion"
|
||||
state.focus["platforms"] = 1
|
||||
self.assertEqual(install.tui_rows(state)[1].label, "Onion, SD card")
|
||||
self.assertEqual(press(state, "enter"), [])
|
||||
self.assertEqual(state.screen, "platforms")
|
||||
self.assertIn("--dest names it: choose another setup.", state.status)
|
||||
self.assertNotIn("Choose the card's top folder", state.status)
|
||||
self.assertEqual((state.platform, state.card_bound), ("", None))
|
||||
|
||||
def test_on_the_device_a_folder_typed_is_taken_as_typed(self):
|
||||
"""code_audit_13 P3-1: a KNULLI got bios added to what was typed."""
|
||||
share = self.root / "userdata" / "share"
|
||||
share.mkdir(parents=True)
|
||||
state = fresh_state()
|
||||
state.stack = ["setup", "platforms"]
|
||||
state.platform, state.card_bound = "knulli", ("KNULLI", "bios")
|
||||
install._open_folder_screen(state, Path("/userdata/bios"), "found")
|
||||
state.stack.append("path")
|
||||
state.path_text = str(share)
|
||||
text = " ".join(install.tui_view(state, 80, 24))
|
||||
self.assertIn("The folder for KNULLI:", text)
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[]):
|
||||
press(state, "enter")
|
||||
self.assertEqual(state.dest, share)
|
||||
|
||||
def test_a_card_in_a_reader_asks_for_its_card_once(self):
|
||||
"""code_audit_13 P3-9, tui_audit_6 P3-7: "Which folder? Onion reads
|
||||
its BIOS files from" on a computer, the same card listed twice."""
|
||||
first, second = self.onion("D"), self.onion("E")
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[first, second]), \
|
||||
mock.patch.object(install, "detect_platforms",
|
||||
return_value=[("retroarch", SYSTEM_DIR)]), \
|
||||
mock.patch.object(install, "detect_frontends", return_value=[]):
|
||||
state, _effects = install.tui_start(_args(), "linux")
|
||||
self.assertEqual(len(state.setups), 3)
|
||||
state.focus["setup"] = len(state.setups)
|
||||
press(state, "enter")
|
||||
state.filters["platforms"] = "onion"
|
||||
state.focus["platforms"] = 1
|
||||
press(state, "enter")
|
||||
rows = install.tui_rows(state)
|
||||
title = install.tui_view(state, 80, 24)[0]
|
||||
self.assertIn("Where is the SD card?", title)
|
||||
self.assertEqual([(row.action, row.value) for row in rows][:2],
|
||||
[("card", first), ("card", second)])
|
||||
self.assertNotIn("default", [row.action for row in rows])
|
||||
# The RetroArch row stays this computer's, never the card's folder.
|
||||
state.stack = ["setup", "platforms"]
|
||||
state.filters["platforms"] = ""
|
||||
state.focus["platforms"] = install._platform_focus(state, "retroarch")
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[first, second]):
|
||||
press(state, "enter")
|
||||
self.assertEqual(state.folder_default, SYSTEM_DIR)
|
||||
|
||||
def test_browsing_for_a_card_starts_on_the_drives(self):
|
||||
"""tui_audit_6 P3-2: the browser opened on the home folder, Use this
|
||||
folder focused, saying to go back, the cards listed under it."""
|
||||
card = self.onion()
|
||||
state = fresh_state()
|
||||
state.stack = ["setup", "platforms"]
|
||||
state.platform, state.card_bound = "retroarch", ("Onion", "BIOS")
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[card]):
|
||||
install._open_folder_screen(state, None)
|
||||
state.focus["folder"] = [row.action for row in install.tui_rows(state)].index(
|
||||
"browse")
|
||||
press(state, "enter")
|
||||
rows = install.tui_rows(state)
|
||||
self.assertEqual(state.screen, "browse")
|
||||
self.assertEqual(rows[state.focus["browse"]].value, card)
|
||||
self.assertEqual(state.status, "Choose the card below, or open the folder that holds it.")
|
||||
|
||||
def test_a_number_outside_the_list_is_said(self):
|
||||
"""tui_audit_6 P3-1: 9 was read as a folder."""
|
||||
card, other = self.onion(), self.onion("SECOND")
|
||||
answers = iter(["9", "0", "2"])
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[card, other]), \
|
||||
mock.patch.object(install, "_ask", side_effect=lambda _p: next(answers)), \
|
||||
contextlib.redirect_stdout(io.StringIO()) as out:
|
||||
dest = install.card_install_dest("onion", "retroarch", True)
|
||||
self.assertEqual(dest, other / "BIOS")
|
||||
self.assertEqual(out.getvalue().count("Type 1 to 2, or a folder."), 2)
|
||||
|
||||
def test_the_articles_read(self):
|
||||
self.assertEqual([install._a(name) for name in ("Onion", "Allium", "ArkOS", "muOS",
|
||||
"KNULLI")],
|
||||
["an Onion", "an Allium", "an ArkOS", "a muOS", "a KNULLI"])
|
||||
|
||||
def test_every_card_row_reads_the_same(self):
|
||||
"""tui_audit_6 P3-6: KNULLI, ROCKNIX and the MinUI family asked for
|
||||
their card without saying so."""
|
||||
state = fresh_state()
|
||||
state.stack = ["setup", "platforms"]
|
||||
labels = {row.value: row.label for row in install.tui_rows(state)
|
||||
if row.action == "platform"}
|
||||
for plat in ("knulli", "rocknix", "minui", "nextui", "myminui"):
|
||||
self.assertEqual(labels[plat], f"{install.display_name(plat)}, SD card")
|
||||
self.assertEqual(labels["retroarch"], "RetroArch")
|
||||
# On the device itself it is that device's setup, not a card.
|
||||
share = Path("/userdata/bios")
|
||||
state.setups.append(("knulli", share, "KNULLI"))
|
||||
with mock.patch.dict(install._DETECTED_OS, {("knulli", share): "KNULLI"}):
|
||||
labels = {row.value: row.label for row in install.tui_rows(state)
|
||||
if row.action == "platform"}
|
||||
self.assertEqual(labels["knulli"], "KNULLI")
|
||||
|
||||
def test_offline_plan_counts_agree(self):
|
||||
"""code_audit_13 P3-4: "3 downloaded" under "3 need the internet";
|
||||
tui_audit_6 P3-9.2: the data files read as if on hand."""
|
||||
state = checked_state()
|
||||
state.found = [{"event": "found", "platform": "retroarch", "dest": FILES[0]["dest"],
|
||||
"folder": "/media/old", "path": "/media/old/x", "member": "",
|
||||
"reason": ""}]
|
||||
with mock.patch.dict(os.environ, {install.OFFLINE_VARIABLE: "1"}):
|
||||
text = " ".join(" ".join(install.tui_view(state, 120, 40)).split())
|
||||
self.assertNotIn("downloaded", text)
|
||||
state.found = []
|
||||
state.check = dict(state.check, data_missing=2636, data_bytes=40 * 1024 * 1024)
|
||||
text = " ".join(" ".join(install.tui_view(state, 120, 40)).split())
|
||||
self.assertIn("4 files and 2636 data files (40.0 MB) need the internet, which "
|
||||
"--offline does not use", text)
|
||||
|
||||
def test_the_error_row_and_the_bar_agree(self):
|
||||
"""tui_audit_6 P3-9.3: "Choose another setup or folder" over
|
||||
"A/Enter Back"."""
|
||||
state = checked_state()
|
||||
state.run = "check"
|
||||
install._fail(state, ["went wrong"], 1)
|
||||
state.focus["error"] = 0
|
||||
self.assertEqual(install.tui_rows(state)[0].label, "Choose another setup or folder")
|
||||
self.assertEqual(install._primary(state), "A/Enter Choose")
|
||||
press(state, "enter")
|
||||
self.assertNotEqual(state.screen, "error")
|
||||
|
||||
def test_a_long_name_keeps_a_size_at_40_columns(self):
|
||||
"""tui_audit_6 P3-5: Nintendo Game Boy Advance lost its size."""
|
||||
row = install.TuiRow("system", "[x] Nintendo Game Boy Advance", "1 file, 16.0 KB",
|
||||
"nintendo-gba", narrow=("16.0 KB", install._compact_size(16384)))
|
||||
self.assertTrue(str(install._row_line(row, False, 38)).rstrip().endswith("16 KB"))
|
||||
|
||||
def test_the_shared_note_keeps_its_line(self):
|
||||
"""tui_audit_6 P3-5: the page held 4, 3 and 5 systems as the note
|
||||
came and went, and "+19" read as 19 more."""
|
||||
state = OneSystemInFewPresses().long_list("keys")
|
||||
state.files = [{"event": "file", "dest": "mame.zip", "size": 10,
|
||||
"systems": ["sys-00", "sys-01"]},
|
||||
{"event": "file", "dest": "two.zip", "size": 10,
|
||||
"systems": ["sys-00", "sys-01"]}]
|
||||
state.stack.append("systems")
|
||||
footers = set()
|
||||
for focus in range(3, 12):
|
||||
state.focus["systems"] = focus
|
||||
lines = install.tui_view(state, 40, 12)
|
||||
footers.add(next(i for i, line in enumerate(lines) if "of 66 systems:" in line))
|
||||
self.assertEqual(len(footers), 1, footers)
|
||||
state.focus["systems"] = 3
|
||||
self.assertIn(" +2 shared: counted once", install.tui_view(state, 40, 12))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -81,8 +81,8 @@ It opens a menu:
|
||||
|
||||
- **Right folder?** Press Enter.
|
||||
- **Wrong folder?** Choose **Another setup or folder**, then browse to yours.
|
||||
- **A handheld's SD card?** Choose it, or its system under **Another setup
|
||||
or folder**: **Where is the SD card?**
|
||||
- **A handheld's SD card?** Under **Another setup or folder**, choose its
|
||||
system: **Onion, SD card**.
|
||||
|
||||
Arrows move, Enter chooses, Esc goes back, as A and B on a handheld.
|
||||
|
||||
|
||||
+43
-23
@@ -120,7 +120,10 @@ they do online, and a file of the list the pack does not hold fails as
|
||||
|
||||
`--offline` forbids every request, for a device with no Wi-Fi: `--check`
|
||||
still names the platform and its folder, then stops at the file list unless
|
||||
`--manifest` or `--from-pack` gives it.
|
||||
`--manifest` or `--from-pack` gives it. At a terminal the run installs the
|
||||
copies found on this machine and downloads nothing. The files left out are
|
||||
missing, not declined: it ends `Finished with files missing` (code 1), or
|
||||
`Nothing installed` (code 2) when none was found, as the full screen does.
|
||||
|
||||
## The full-screen interface { #the-full-screen-interface }
|
||||
|
||||
@@ -132,8 +135,10 @@ much space is free, before anything is written.
|
||||
|
||||
The other choices sit one press away. **Choose systems** ticks the consoles you
|
||||
play, with the total to download under the list. A long list opens on **None**:
|
||||
A or Enter there unticks every system, and A on a system then installs that one alone. Back
|
||||
with nothing ticked keeps the ticks the list opened with. **Options** sets the
|
||||
A or Enter there unticks every system, and A on a system then takes that one alone. A
|
||||
on a system (**Continue**) always opens the confirm screen, which counts the choice
|
||||
before **Install**: it never installs by itself. Back with nothing ticked keeps the ticks
|
||||
the list opened with. **Options** sets the
|
||||
preferred regions, game data, the installed cores only, the cores, the parallel
|
||||
downloads, the folder and, for a list with files read from the frontend's save
|
||||
directory, that directory. Each row names the option it sets, and **Show the
|
||||
@@ -367,8 +372,8 @@ would save, once that saving is over half:
|
||||
`--dry-run` prints the same line under its plan.
|
||||
|
||||
When some files came from this machine rather than the network, a line under
|
||||
`Done` says where each came from (`38 files copied from E:\, 3 fixed from
|
||||
copies already in the BIOS folder, 4 downloaded.`). See
|
||||
`Done` says where each came from (`38 files copied from E:\, 3 copied from
|
||||
the wrong place in the BIOS folder, 4 downloaded.`). See
|
||||
[Copy from an old card](#copy-from-an-old-card).
|
||||
|
||||
The word `Done` and a location are the confirmation. Any other ending
|
||||
@@ -554,7 +559,7 @@ misplaced in it, in a `bios/bios/` folder, a pack extracted into a folder of
|
||||
its own, a name in capitals on a system where case counts, a ZIP never
|
||||
extracted, or one folder above, is copied where the cores open it, with no
|
||||
`--from` needed. The misplaced copy is left as it is, and the end of the run
|
||||
counts them (`3 fixed from copies already in the BIOS folder`).
|
||||
counts them (`3 copied from the wrong place in the BIOS folder`).
|
||||
|
||||
## Choosing what to install
|
||||
|
||||
@@ -831,9 +836,10 @@ gives for the device, below the card's root instead of its mount point:
|
||||
| `.config/system/configs/system.cfg` with `root.password=rocknix`, as ROCKNIX's first boot writes its storage | ROCKNIX | `roms/bios`, ROCKNIX's list |
|
||||
|
||||
The full screen lists such a card on its first screen ("muOS SD card (E:\)").
|
||||
Named by its system (`--platform muos`, `--platform onion`), a `--dest` that
|
||||
is neither such a card nor its BIOS folder is refused, with the folder that
|
||||
system reads.
|
||||
Named by its system (`--platform muos`, `--platform knulli`), a `--dest` that
|
||||
is another system's card is refused. One that holds none of the system's
|
||||
files is refused where the card always carries them, and is taken as named
|
||||
for KNULLI, ROCKNIX and the systems no file on the card names.
|
||||
|
||||
Desktop installs are read from their own configuration, and several can be
|
||||
found on one machine.
|
||||
@@ -910,18 +916,32 @@ EmuELEC, `/media/fat/games` for MiSTer,
|
||||
`C:\RetroBat\bios` for RetroBat, and RetroArch's own default system
|
||||
directory for RetroArch. BizHawk has no such folder: it reads `Firmware`
|
||||
beside its executable wherever the archive was extracted, so a forced
|
||||
`--platform bizhawk` that finds no install stops and asks for `--dest`. MinUI,
|
||||
NextUI and MyMinUI keep their files on the SD card. Run on the device, the
|
||||
installer finds the card root. From a computer the card is mounted on, a
|
||||
forced `--platform minui` uses the one MinUI card mounted. Otherwise the screen
|
||||
opens **Where is the SD card?**, which lists only the cards of that system and
|
||||
offers **Look again**, and `--plain` asks `Card root`, listing the mounted
|
||||
drives by number. A root that does not exist is asked again, and so is a
|
||||
folder without the card's own files for MinUI, NextUI, MyMinUI, Onion, muOS
|
||||
and spruceOS. Without questions (`--no-input`) the run stops with a `--dest`
|
||||
example. The same holds for Onion, muOS, spruceOS, KNULLI and ROCKNIX, also
|
||||
when chosen from the setup list or its filter. A `--dest` that is a folder
|
||||
inside such a card (its `Bios/`) is refused with the root to name instead. On Android a forced `--platform retroarch` falls back to
|
||||
`--platform bizhawk` that finds no install stops and asks for `--dest`.
|
||||
|
||||
The systems that run from an SD card keep their files there: MinUI, NextUI,
|
||||
MyMinUI, KNULLI, ROCKNIX, and each system of the
|
||||
[Linux handhelds](../platforms/linux-handhelds.md) that gets RetroArch's list
|
||||
(Onion, muOS, spruceOS, ArkOS, UnofficialOS and the others). Run on the
|
||||
device, the installer finds its folder. From a computer, each has a row of its
|
||||
own in the setup list (**Onion, SD card**), without the filter, and in the
|
||||
`--plain` menu. That row, `--platform onion` and the menu all ask for the
|
||||
card: one card of that system mounted is taken, otherwise the screen opens
|
||||
**Where is the SD card?**, which lists only that system's cards and offers
|
||||
**Look again**, and `--plain` asks `Card root`, listing the same cards by
|
||||
number. The RetroArch row is this computer's RetroArch.
|
||||
|
||||
The card's top folder is checked the same way wherever it is chosen, listed,
|
||||
browsed, typed or named with `--dest`, and gives the same folder. A folder
|
||||
that does not exist, or that is another system's card, is refused for every
|
||||
system. One without the system's own files is refused for the MinUI family,
|
||||
Onion, muOS, spruceOS, CrossMix-OS, Allium and Koriki. KNULLI and ROCKNIX
|
||||
fill their card when they first start, and no file on the card names ArkOS,
|
||||
dArkOS, JELOS, KOLOS, UnofficialOS, ArchR, RetroOZ, plumOS, MiyooCFW or the
|
||||
Anbernic firmware: such a folder is taken, and a note says so. No to
|
||||
creating its folders asks for the card again. Under WSL a drive letter
|
||||
typed (`D:`, `D:\`) is that Windows drive. Without questions (`--no-input`)
|
||||
the run stops with a `--dest` example. A `--dest` that is a folder inside a
|
||||
MinUI card (its `Bios/`) is refused with the root to name instead. On Android a forced `--platform retroarch` falls back to
|
||||
`<shared storage>/RetroArch/system` instead, a home directory there belonging
|
||||
to Termux rather than to the frontend. Pass `--dest` to say where instead of
|
||||
relying on that. When detection met a folder this user cannot open, under the
|
||||
@@ -1291,8 +1311,8 @@ fields, the installer refuses to narrow rather than install everything.
|
||||
| Code | Meaning |
|
||||
|------|---------|
|
||||
| `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 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, `--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), 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` |
|
||||
| `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, `--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 |
|
||||
| `141` | the output was piped to a reader that closed early (`--list-platforms \| head`) |
|
||||
|
||||
|
||||
Reference in new issue
Block a user