feat: remove installed files and list backups

--remove deletes for good, or moves into a backup with --backup, only what the install record proves the installer placed: unchanged bytes, a regular file below the BIOS folder reached through no link, a SHA-1 the list still serves. Shared, changed, hand-added and unservable files stay and are named. --backups lists, --delete-backup deletes, --restore now updates the record. The full screen gains More, Remove files, the removal plan, Backups and their confirms. Events removal_plan, removed, restored and backup.
This commit is contained in:
Abdessamad Derraz committed 2026-11-11 13:20:42 +01:00
1 parent 0addf9055e
commit e38764627b
47 files changed
+5334 -99

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 = "67036bbe4db401de213d9a8ab44161b8b64bfde91834b438fff47802b5a461aa"
$defaultInstallSha256 = "ce18b5e213fde35341231cd79a9c9205f57f3f096827dc50e26db9487d1b5349"
# The pin above refuses any changed byte: this cap only stops a body that
# cannot be the installer (a sign-in portal's page) before it is hashed.
$maximumInstallerBytes = 8MB
+1340 -50
View File
File diff suppressed because it is too large. Load diff
+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="67036bbe4db401de213d9a8ab44161b8b64bfde91834b438fff47802b5a461aa"
DEFAULT_INSTALL_SHA256="ce18b5e213fde35341231cd79a9c9205f57f3f096827dc50e26db9487d1b5349"
# The pin above refuses any changed byte: this cap only stops a body that
# cannot be the installer (a sign-in portal's page) before it is hashed.
MAX_INSTALLER_BYTES=8388608
+8 -8
View File
@@ -27,8 +27,8 @@
{
"dest": "roms/ports/retrobios/install.py",
"repo_path": "install.py",
"size": 1220974,
"sha256": "67036bbe4db401de213d9a8ab44161b8b64bfde91834b438fff47802b5a461aa",
"size": 1280415,
"sha256": "ce18b5e213fde35341231cd79a9c9205f57f3f096827dc50e26db9487d1b5349",
"executable": false
},
{
@@ -71,8 +71,8 @@
"muos": {
"archive": {
"dest": "ARCHIVE/RetroBIOS.muxapp",
"size": 1274599,
"sha256": "8ea3d79c9bbcec747555c3970edef0692db5a00ada0ff45892aaf68dcfc38eb6"
"size": 1334040,
"sha256": "5f526e2d068764c5a178eccaf82f97012ac8bda61a0db251501580a8efd698eb"
},
"members": [
{
@@ -92,8 +92,8 @@
{
"name": "RetroBIOS/install.py",
"repo_path": "install.py",
"size": 1220974,
"sha256": "67036bbe4db401de213d9a8ab44161b8b64bfde91834b438fff47802b5a461aa",
"size": 1280415,
"sha256": "ce18b5e213fde35341231cd79a9c9205f57f3f096827dc50e26db9487d1b5349",
"executable": false
},
{
@@ -166,8 +166,8 @@
{
"dest": ".config/modules/retrobios/install.py",
"repo_path": "install.py",
"size": 1220974,
"sha256": "67036bbe4db401de213d9a8ab44161b8b64bfde91834b438fff47802b5a461aa",
"size": 1280415,
"sha256": "ce18b5e213fde35341231cd79a9c9205f57f3f096827dc50e26db9487d1b5349",
"executable": false
},
{
+215 -3
View File
@@ -39,6 +39,10 @@
"summary",
"app",
"record",
"removal_plan",
"removed",
"restored",
"backup",
"end"
]
}
@@ -131,6 +135,18 @@
{
"$ref": "#/$defs/record"
},
{
"$ref": "#/$defs/removal_plan"
},
{
"$ref": "#/$defs/removed"
},
{
"$ref": "#/$defs/restored"
},
{
"$ref": "#/$defs/backup"
},
{
"$ref": "#/$defs/end"
}
@@ -160,7 +176,9 @@
"install",
"check",
"dry-run",
"list"
"list",
"remove",
"restore"
]
}
}
@@ -1002,7 +1020,9 @@
"install",
"check",
"dry-run",
"list"
"list",
"remove",
"restore"
]
},
"installed": {
@@ -1127,7 +1147,11 @@
"applied",
"written",
"unreadable",
"not_written"
"not_written",
"listed",
"made",
"deleted",
"not_deleted"
]
},
"choice": {
@@ -1148,6 +1172,194 @@
}
}
},
"removal_plan": {
"type": "object",
"additionalProperties": false,
"required": [
"event",
"platform",
"folder",
"files",
"bytes",
"systems",
"dests",
"kept",
"gone",
"backup",
"message"
],
"properties": {
"event": {
"const": "removal_plan"
},
"platform": {
"type": "string"
},
"folder": {
"type": "string"
},
"files": {
"type": "integer",
"minimum": 0
},
"bytes": {
"type": "integer",
"minimum": 0
},
"systems": {
"type": "array",
"items": {
"type": "string"
}
},
"dests": {
"type": "array",
"items": {
"type": "string"
}
},
"kept": {
"type": "array",
"items": {
"type": "object"
}
},
"gone": {
"type": "integer",
"minimum": 0
},
"backup": {
"type": "boolean"
},
"message": {
"type": "string"
}
}
},
"removed": {
"type": "object",
"additionalProperties": false,
"required": [
"event",
"platform",
"dest",
"size",
"ok",
"reason",
"moved_to"
],
"properties": {
"event": {
"const": "removed"
},
"platform": {
"type": "string"
},
"dest": {
"type": "string"
},
"size": {
"type": "integer",
"minimum": 0
},
"ok": {
"type": "boolean"
},
"reason": {
"type": "string"
},
"moved_to": {
"type": "string"
}
}
},
"restored": {
"type": "object",
"additionalProperties": false,
"required": [
"event",
"folder",
"path",
"size",
"ok",
"reason"
],
"properties": {
"event": {
"const": "restored"
},
"folder": {
"type": "string"
},
"path": {
"type": "string"
},
"size": {
"type": "integer",
"minimum": 0
},
"ok": {
"type": "boolean"
},
"reason": {
"type": "string"
}
}
},
"backup": {
"type": "object",
"additionalProperties": false,
"required": [
"event",
"folder",
"date",
"files",
"bytes",
"source",
"status",
"message"
],
"properties": {
"event": {
"const": "backup"
},
"folder": {
"type": "string"
},
"date": {
"type": "string"
},
"files": {
"type": "integer",
"minimum": 0
},
"bytes": {
"type": "integer",
"minimum": 0
},
"source": {
"enum": [
"remove",
"install"
]
},
"status": {
"enum": [
"applied",
"written",
"unreadable",
"not_written",
"listed",
"made",
"deleted",
"not_deleted"
]
},
"message": {
"type": "string"
}
}
},
"end": {
"type": "object",
"additionalProperties": false,
+8 -5
View File
@@ -37,18 +37,21 @@ KEY_TYPES: dict[str, dict] = {
**dict.fromkeys((
"installer", "os", "os_name", "stage", "reason", "platform", "message",
"folder", "dest", "system", "name", "bios_dir", "path", "member",
"list_version", "installed_version", "board", "core", "date",
"list_version", "installed_version", "board", "core", "date", "moved_to",
), _TEXT),
"mode": {"enum": ["install", "check", "dry-run", "list"]},
"mode": {"enum": ["install", "check", "dry-run", "list", "remove", "restore"]},
"source": {"enum": ["remove", "install"]},
"state": {"enum": ["present", "wrong_hash", "missing"]},
"status": {"enum": ["applied", "written", "unreadable", "not_written"]},
"status": {"enum": ["applied", "written", "unreadable", "not_written", "listed", "made",
"deleted", "not_deleted"]},
**dict.fromkeys((
"files", "files_done", "files_total", "bytes", "bytes_done", "bytes_total",
"bytes_local", "bytes_network", "size", "present", "missing", "wrong_hash",
"bytes_needed", "data_missing", "not_installable", "installed", "up_to_date",
"pending", "code", "games", "recognised", "not_games",
"pending", "code", "games", "recognised", "not_games", "gone",
), _COUNT),
**dict.fromkeys(("truncated", "ok", "interrupted", "required_only", "applied", "info"), _FLAG),
**dict.fromkeys(("truncated", "ok", "interrupted", "required_only", "applied", "info",
"backup"), _FLAG),
**dict.fromkeys(("systems", "other_drives", "dests", "written", "choice"), _NAMES),
**dict.fromkeys(("platforms", "failed", "skipped", "left_out", "kept", "found",
"fallback"), _RECORDS),
+40
View File
@@ -0,0 +1,40 @@
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A/Enter Choose B/Esc Back ? Help
+12
View File
@@ -0,0 +1,12 @@
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose B Back ? Help
+15
View File
@@ -0,0 +1,15 @@
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose B Back ? Help
+24
View File
@@ -0,0 +1,24 @@
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A/Enter Choose B/Esc Back ? Help
+247 -1
View File
@@ -1160,6 +1160,7 @@
Change where
Details
Change
More
Quit
@@ -1183,7 +1184,252 @@
^[[0;1;35mA/Enter^[[0m Install ^[[0;2mB/Esc^[[0m Back ^[[0;2mY/o^[[0m Change ^[[0;2m?^[[0m Help
=== more
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: More^[[0m
^[[0;7;35m > Remove files^[[0m
Backups
Put back a backup
Delete a backup
^[[0;1;35mA/Enter^[[0m Open ^[[0;2mB/Esc^[[0m Back ^[[0;2m?^[[0m Help
=== remove
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Remove files^[[0m
Choose what to remove. A file changed or added by hand stays.
^[[0;7;35m > All RetroBIOS files 528.0 KB^[[0m
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
^[[0;1;35mA/Enter^[[0m Choose ^[[0;2mB/Esc^[[0m Back ^[[0;2m?^[[0m Help
=== removal
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Remove files^[[0m
2 files go, 512.0 KB freed.
BIOS folder: ^[[0;1m~/.config/retroarch/system^[[0m
1 file stays: 1 changed since it was installed.
^[[0;7;35m > Remove 512.0 KB^[[0m
Keep a backup: no --backup
Details
^[[0;1;35mA/Enter^[[0m Remove ^[[0;2mB/Esc^[[0m Back ^[[0;2m?^[[0m Help
=== removal-confirm
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Confirm^[[0m
Remove 2 files for good? 512.0 KB is freed.
^[[0;7;35m > Remove^[[0m
Back
^[[0;1;35mA/Enter^[[0m Confirm ^[[0;2mB/Esc^[[0m Back ^[[0;2m?^[[0m Help
=== removal-done
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: ^[[0;1;32mDone^[[0m
^[[0;1m Removed ^[[0;1;35m2^[[0;1m files, ^[[0;1;35m512.0 KB^[[0;1m freed.^[[0m
BIOS folder: ^[[0;1m~/.config/retroarch/system^[[0m
^[[0;7;35m > Close^[[0m
Check again
^[[0;1;35mA/Enter^[[0m Close ^[[0;2mB/Esc^[[0m Back ^[[0;2m?^[[0m Help
=== backups
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Backups^[[0m
Newest first.
^[[0;7;35m > 3 Nov 12:00 2 files, 512.0 KB^[[0m
20 Oct 09:30 1 file, 16.0 KB
Back
^[[0;1;35mA/Enter^[[0m Choose ^[[0;2mB/Esc^[[0m Back ^[[0;2m?^[[0m Help
+79 -1
View File
@@ -373,5 +373,83 @@
Same choice as on 3 Nov: yes
Choose systems
Copy from an old card or a folder
^[[0;2m 1-4 of 8^[[0m
^[[0;2m 1-4 of 9^[[0m
^[[0;1;35mA^[[0m Install ^[[0;2mB^[[0m Back ^[[0;2mY^[[0m Change ^[[0;2m?^[[0m Help
=== more
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: More^[[0m
^[[0;7;35m > Remove files^[[0m
Backups
Put back a backup
Delete a backup
^[[0;1;35mA^[[0m Open ^[[0;2mB^[[0m Back ^[[0;2m?^[[0m Help
=== remove
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Remove files^[[0m
Choose what to remove. A file changed
or added by hand stays.
^[[0;7;35m > All RetroBIOS files 528.0 KB^[[0m
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
^[[0;1;35mA^[[0m Choose ^[[0;2mB^[[0m Back ^[[0;2m?^[[0m Help
=== removal
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Remove files^[[0m
2 files go, 512.0 KB freed.
BIOS folder:
^[[0;1m~/.config/retroarch/system^[[0m
1 file stays: 1 changed since it was
installed.
^[[0;7;35m > Remove 512.0 KB^[[0m
Keep a backup: no --backup
Details
^[[0;1;35mA^[[0m Remove ^[[0;2mB^[[0m Back ^[[0;2m?^[[0m Help
=== removal-confirm
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Confirm^[[0m
Remove 2 files for good? 512.0 KB is
freed.
^[[0;7;35m > Remove^[[0m
Back
^[[0;1;35mA^[[0m Confirm ^[[0;2mB^[[0m Back ^[[0;2m?^[[0m Help
=== removal-done
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: ^[[0;1;32mDone^[[0m
^[[0;1m Removed ^[[0;1;35m2^[[0;1m files, ^[[0;1;35m512.0 KB^[[0;1m freed.^[[0m
BIOS folder: ^[[0;1m~/.co.../retroarch/system^[[0m
^[[0;7;35m > Close^[[0m
Check again
^[[0;1;35mA^[[0m Close ^[[0;2mB^[[0m Back ^[[0;2m?^[[0m Help
=== backups
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Backups^[[0m
Newest first.
^[[0;7;35m > 3 Nov 12:00 2 files, 512.0 KB^[[0m
20 Oct 09:30 1 file, 16.0 KB
Back
^[[0;1;35mA^[[0m Choose ^[[0;2mB^[[0m Back ^[[0;2m?^[[0m Help
+97 -1
View File
@@ -452,7 +452,6 @@
^[[0;1m ^[[0;1;35m1^[[0;1m file to download, ^[[0;1;35m16.0 KB^[[0m
BIOS folder:
^[[0;1m~/.config/retroarch/system^[[0m
For nintendo-gba.
^[[0;7;35m > Install^[[0m
Same choice as on 3 Nov: yes
Choose systems
@@ -460,5 +459,102 @@
Change where
Details
Change
More
Quit
^[[0;1;35mA^[[0m Install ^[[0;2mB^[[0m Back ^[[0;2mY^[[0m Change ^[[0;2m?^[[0m Help
=== more
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: More^[[0m
^[[0;7;35m > Remove files^[[0m
Backups
Put back a backup
Delete a backup
^[[0;1;35mA^[[0m Open ^[[0;2mB^[[0m Back ^[[0;2m?^[[0m Help
=== remove
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Remove files^[[0m
Choose what to remove. A file changed
or added by hand stays.
^[[0;7;35m > All RetroBIOS files 528.0 KB^[[0m
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
^[[0;1;35mA^[[0m Choose ^[[0;2mB^[[0m Back ^[[0;2m?^[[0m Help
=== removal
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Remove files^[[0m
2 files go, 512.0 KB freed.
BIOS folder:
^[[0;1m~/.config/retroarch/system^[[0m
1 file stays: 1 changed since it was
installed.
^[[0;7;35m > Remove 512.0 KB^[[0m
Keep a backup: no --backup
Details
^[[0;1;35mA^[[0m Remove ^[[0;2mB^[[0m Back ^[[0;2m?^[[0m Help
=== removal-confirm
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Confirm^[[0m
Remove 2 files for good? 512.0 KB is
freed.
^[[0;7;35m > Remove^[[0m
Back
^[[0;1;35mA^[[0m Confirm ^[[0;2mB^[[0m Back ^[[0;2m?^[[0m Help
=== removal-done
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: ^[[0;1;32mDone^[[0m
^[[0;1m Removed ^[[0;1;35m2^[[0;1m files, ^[[0;1;35m512.0 KB^[[0;1m freed.^[[0m
BIOS folder: ^[[0;1m~/.co.../retroarch/system^[[0m
^[[0;7;35m > Close^[[0m
Check again
^[[0;1;35mA^[[0m Close ^[[0;2mB^[[0m Back ^[[0;2m?^[[0m Help
=== backups
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Backups^[[0m
Newest first.
^[[0;7;35m > 3 Nov 12:00 2 files, 512.0 KB^[[0m
20 Oct 09:30 1 file, 16.0 KB
Back
^[[0;1;35mA^[[0m Choose ^[[0;2mB^[[0m Back ^[[0;2m?^[[0m Help
+151 -1
View File
@@ -712,6 +712,7 @@
Change where
Details
Change
More
Quit
@@ -721,5 +722,154 @@
^[[0;1;35mA/Enter^[[0m Install ^[[0;2mB/Esc^[[0m Back ^[[0;2mY/o^[[0m Change ^[[0;2m?^[[0m Help
=== more
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: More^[[0m
^[[0;7;35m > Remove files^[[0m
Backups
Put back a backup
Delete a backup
^[[0;1;35mA/Enter^[[0m Open ^[[0;2mB/Esc^[[0m Back ^[[0;2m?^[[0m Help
=== remove
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Remove files^[[0m
Choose what to remove. A file changed or added by hand stays.
^[[0;7;35m > All RetroBIOS files 528.0 KB^[[0m
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
^[[0;1;35mA/Enter^[[0m Choose ^[[0;2mB/Esc^[[0m Back ^[[0;2m?^[[0m Help
=== removal
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Remove files^[[0m
2 files go, 512.0 KB freed.
BIOS folder: ^[[0;1m~/.config/retroarch/system^[[0m
1 file stays: 1 changed since it was installed.
^[[0;7;35m > Remove 512.0 KB^[[0m
Keep a backup: no --backup
Details
^[[0;1;35mA/Enter^[[0m Remove ^[[0;2mB/Esc^[[0m Back ^[[0;2m?^[[0m Help
=== removal-confirm
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Confirm^[[0m
Remove 2 files for good? 512.0 KB is freed.
^[[0;7;35m > Remove^[[0m
Back
^[[0;1;35mA/Enter^[[0m Confirm ^[[0;2mB/Esc^[[0m Back ^[[0;2m?^[[0m Help
=== removal-done
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: ^[[0;1;32mDone^[[0m
^[[0;1m Removed ^[[0;1;35m2^[[0;1m files, ^[[0;1;35m512.0 KB^[[0;1m freed.^[[0m
BIOS folder: ^[[0;1m~/.config/retroarch/system^[[0m
^[[0;7;35m > Close^[[0m
Check again
^[[0;1;35mA/Enter^[[0m Close ^[[0;2mB/Esc^[[0m Back ^[[0;2m?^[[0m Help
=== backups
^[[0;1m ^[[0;1;35mRetroBIOS^[[0;1m: Backups^[[0m
Newest first.
^[[0;7;35m > 3 Nov 12:00 2 files, 512.0 KB^[[0m
20 Oct 09:30 1 file, 16.0 KB
Back
^[[0;1;35mA/Enter^[[0m Choose ^[[0;2mB/Esc^[[0m Back ^[[0;2m?^[[0m Help
+40
View File
@@ -0,0 +1,40 @@
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A/Enter Open B/Esc Back ? Help
+12
View File
@@ -0,0 +1,12 @@
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open B Back ? Help
+15
View File
@@ -0,0 +1,15 @@
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open B Back ? Help
+24
View File
@@ -0,0 +1,24 @@
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A/Enter Open B/Esc Back ? Help
+1 -1
View File
@@ -11,6 +11,7 @@
Change where
Details
Change
More
Quit
@@ -34,7 +35,6 @@
A/Enter Install B/Esc Back Y/o Change ? Help
+1 -1
View File
@@ -8,5 +8,5 @@
Same choice as on 3 Nov: yes
Choose systems
Copy from an old card or a folder
1-4 of 8
1-4 of 9
A Install B Back Y Change ? Help
+1 -1
View File
@@ -3,7 +3,6 @@
1 file to download, 16.0 KB
BIOS folder:
~/.config/retroarch/system
For nintendo-gba.
> Install
Same choice as on 3 Nov: yes
Choose systems
@@ -11,5 +10,6 @@
Change where
Details
Change
More
Quit
A Install B Back Y Change ? Help
+1 -1
View File
@@ -11,6 +11,7 @@
Change where
Details
Change
More
Quit
@@ -20,5 +21,4 @@
A/Enter Install B/Esc Back Y/o Change ? Help
+40
View File
@@ -0,0 +1,40 @@
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
1 file stays: 1 changed since it was installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A/Enter Remove B/Esc Back ? Help
+12
View File
@@ -0,0 +1,12 @@
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove B Back ? Help
+15
View File
@@ -0,0 +1,15 @@
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove B Back ? Help
+24
View File
@@ -0,0 +1,24 @@
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
1 file stays: 1 changed since it was installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A/Enter Remove B/Esc Back ? Help
+40
View File
@@ -0,0 +1,40 @@
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is freed.
> Remove
Back
A/Enter Confirm B/Esc Back ? Help
+12
View File
@@ -0,0 +1,12 @@
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
A Confirm B Back ? Help
+15
View File
@@ -0,0 +1,15 @@
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
A Confirm B Back ? Help
+24
View File
@@ -0,0 +1,24 @@
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is freed.
> Remove
Back
A/Enter Confirm B/Esc Back ? Help
+40
View File
@@ -0,0 +1,40 @@
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
> Close
Check again
A/Enter Close B/Esc Back ? Help
+12
View File
@@ -0,0 +1,12 @@
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
A Close B Back ? Help
+15
View File
@@ -0,0 +1,15 @@
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
A Close B Back ? Help
+24
View File
@@ -0,0 +1,24 @@
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
> Close
Check again
A/Enter Close B/Esc Back ? Help
+40
View File
@@ -0,0 +1,40 @@
RetroBIOS: Remove files
Choose what to remove. A file changed or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A/Enter Choose B/Esc Back ? Help
+12
View File
@@ -0,0 +1,12 @@
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose B Back ? Help
+15
View File
@@ -0,0 +1,15 @@
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose B Back ? Help
+24
View File
@@ -0,0 +1,24 @@
RetroBIOS: Remove files
Choose what to remove. A file changed or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A/Enter Choose B/Esc Back ? Help
+327 -3
View File
@@ -1302,7 +1302,7 @@
Same choice as on 3 Nov: yes
Choose systems
Copy from an old card or a folder
1-4 of 8
1-4 of 9
A Install B Back Y Change
=== plan-record 40x15
RetroBIOS: RetroArch
@@ -1310,7 +1310,6 @@
1 file to download, 16.0 KB
BIOS folder:
~/.config/retroarch/system
For nintendo-gba.
> Install
Same choice as on 3 Nov: yes
Choose systems
@@ -1318,6 +1317,7 @@
Change where
Details
Change
More
Quit
A Install B Back Y Change
=== plan-record 80x24
@@ -1334,6 +1334,7 @@
Change where
Details
Change
More
Quit
@@ -1343,5 +1344,328 @@
A Install B Back Y Change
=== more 40x12
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open B Back
=== more 40x15
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open B Back
=== more 80x24
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open B Back
=== remove 40x12
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose B Back
=== remove 40x15
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose B Back
=== remove 80x24
RetroBIOS: Remove files
Choose what to remove. A file changed or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose B Back
=== removal 40x12
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove B Back
=== removal 40x15
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove B Back
=== removal 80x24
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
1 file stays: 1 changed since it was installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove B Back
=== removal-confirm 40x12
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
A Confirm B Back
=== removal-confirm 40x15
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
A Confirm B Back
=== removal-confirm 80x24
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is freed.
> Remove
Back
A Confirm B Back
=== removal-done 40x12
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
A Close B Back
=== removal-done 40x15
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
A Close B Back
=== removal-done 80x24
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
> Close
Check again
A Close B Back
=== backups 40x12
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose B Back
=== backups 40x15
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose B Back
=== backups 80x24
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose B Back
+327 -3
View File
@@ -1302,7 +1302,7 @@
Same choice as on 3 Nov: yes
Choose systems
Copy from an old card or a folder
1-4 of 8
1-4 of 9
A Install B Back Y Change
=== plan-record 40x15
RetroBIOS: RetroArch
@@ -1310,7 +1310,6 @@
1 file to download, 16.0 KB
BIOS folder:
~/.config/retroarch/system
For nintendo-gba.
> Install
Same choice as on 3 Nov: yes
Choose systems
@@ -1318,6 +1317,7 @@
Change where
Details
Change
More
Quit
A Install B Back Y Change
=== plan-record 80x24
@@ -1334,6 +1334,7 @@
Change where
Details
Change
More
Quit
@@ -1343,5 +1344,328 @@
A Install B Back Y Change
=== more 40x12
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open B Back
=== more 40x15
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open B Back
=== more 80x24
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open B Back
=== remove 40x12
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose B Back
=== remove 40x15
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose B Back
=== remove 80x24
RetroBIOS: Remove files
Choose what to remove. A file changed or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose B Back
=== removal 40x12
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove B Back
=== removal 40x15
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove B Back
=== removal 80x24
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
1 file stays: 1 changed since it was installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove B Back
=== removal-confirm 40x12
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
A Confirm B Back
=== removal-confirm 40x15
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
A Confirm B Back
=== removal-confirm 80x24
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is freed.
> Remove
Back
A Confirm B Back
=== removal-done 40x12
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
A Close B Back
=== removal-done 40x15
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
A Close B Back
=== removal-done 80x24
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
> Close
Check again
A Close B Back
=== backups 40x12
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose B Back
=== backups 40x15
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose B Back
=== backups 80x24
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose B Back
+327 -3
View File
@@ -1302,7 +1302,7 @@
Same choice as on 3 Nov: yes
Choose systems
Copy from an old card or a folder
1-4 of 8
1-4 of 9
A Install B Back Y Change
=== plan-record 40x15
RetroBIOS: RetroArch
@@ -1310,7 +1310,6 @@
1 file to download, 16.0 KB
BIOS folder:
~/.config/retroarch/system
For nintendo-gba.
> Install
Same choice as on 3 Nov: yes
Choose systems
@@ -1318,6 +1317,7 @@
Change where
Details
Change
More
Quit
A Install B Back Y Change
=== plan-record 80x24
@@ -1334,6 +1334,7 @@
Change where
Details
Change
More
Quit
@@ -1343,5 +1344,328 @@
A Install B Back Y Change
=== more 40x12
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open B Back
=== more 40x15
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open B Back
=== more 80x24
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open B Back
=== remove 40x12
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose B Back
=== remove 40x15
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose B Back
=== remove 80x24
RetroBIOS: Remove files
Choose what to remove. A file changed or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose B Back
=== removal 40x12
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove B Back
=== removal 40x15
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove B Back
=== removal 80x24
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
1 file stays: 1 changed since it was installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove B Back
=== removal-confirm 40x12
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
A Confirm B Back
=== removal-confirm 40x15
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
A Confirm B Back
=== removal-confirm 80x24
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is freed.
> Remove
Back
A Confirm B Back
=== removal-done 40x12
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
A Close B Back
=== removal-done 40x15
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
A Close B Back
=== removal-done 80x24
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
> Close
Check again
A Close B Back
=== backups 40x12
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose B Back
=== backups 40x15
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose B Back
=== backups 80x24
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose B Back
+327 -3
View File
@@ -1467,7 +1467,7 @@
Same choice as on 3 Nov: yes
Choose systems
Copy from an old card or a folder
1-4 of 8
1-4 of 9
Enter Install Esc Back o Change
=== plan-record 40x15
RetroBIOS: RetroArch
@@ -1475,7 +1475,6 @@
1 file to download, 16.0 KB
BIOS folder:
~/.config/retroarch/system
For nintendo-gba.
> Install
Same choice as on 3 Nov: yes
Choose systems
@@ -1483,6 +1482,7 @@
Change where
Details
Change
More
Quit
Enter Install Esc Back o Change
=== plan-record 80x24
@@ -1499,6 +1499,7 @@
Change where
Details
Change
More
Quit
@@ -1508,5 +1509,328 @@
Enter Install Esc Back o Change ? Help
=== more 40x12
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
Enter Open Esc Back ? Help
=== more 40x15
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
Enter Open Esc Back ? Help
=== more 80x24
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
Enter Open Esc Back ? Help
=== remove 40x12
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
Enter Choose Esc Back ? Help
=== remove 40x15
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
Enter Choose Esc Back ? Help
=== remove 80x24
RetroBIOS: Remove files
Choose what to remove. A file changed or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
Enter Choose Esc Back ? Help
=== removal 40x12
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
Enter Remove Esc Back ? Help
=== removal 40x15
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
Enter Remove Esc Back ? Help
=== removal 80x24
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
1 file stays: 1 changed since it was installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
Enter Remove Esc Back ? Help
=== removal-confirm 40x12
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
Enter Confirm Esc Back ? Help
=== removal-confirm 40x15
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
Enter Confirm Esc Back ? Help
=== removal-confirm 80x24
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is freed.
> Remove
Back
Enter Confirm Esc Back ? Help
=== removal-done 40x12
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
Enter Close Esc Back ? Help
=== removal-done 40x15
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
Enter Close Esc Back ? Help
=== removal-done 80x24
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
> Close
Check again
Enter Close Esc Back ? Help
=== backups 40x12
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
Enter Choose Esc Back ? Help
=== backups 40x15
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
Enter Choose Esc Back ? Help
=== backups 80x24
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
Enter Choose Esc Back ? Help
+327 -3
View File
@@ -1405,7 +1405,7 @@
Same choice as on 3 Nov: yes
Choose systems
Copy from an old card or a folder
1-4 of 8
1-4 of 9
A Install R2 Back L2 Change
=== plan-record 40x15
RetroBIOS: RetroArch
@@ -1413,7 +1413,6 @@
1 file to download, 16.0 KB
BIOS folder:
~/.config/retroarch/system
For nintendo-gba.
> Install
Same choice as on 3 Nov: yes
Choose systems
@@ -1421,6 +1420,7 @@
Change where
Details
Change
More
Quit
A Install R2 Back L2 Change
=== plan-record 80x24
@@ -1437,6 +1437,7 @@
Change where
Details
Change
More
Quit
@@ -1446,5 +1447,328 @@
A Install R2 Back L2 Change
=== more 40x12
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open R2 Back
=== more 40x15
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open R2 Back
=== more 80x24
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
A Open R2 Back
=== remove 40x12
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose R2 Back
=== remove 40x15
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose R2 Back
=== remove 80x24
RetroBIOS: Remove files
Choose what to remove. A file changed or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
A Choose R2 Back
=== removal 40x12
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove R2 Back
=== removal 40x15
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove R2 Back
=== removal 80x24
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
1 file stays: 1 changed since it was installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
A Remove R2 Back
=== removal-confirm 40x12
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
A Confirm R2 Back
=== removal-confirm 40x15
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
A Confirm R2 Back
=== removal-confirm 80x24
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is freed.
> Remove
Back
A Confirm R2 Back
=== removal-done 40x12
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
A Close R2 Back
=== removal-done 40x15
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
A Close R2 Back
=== removal-done 80x24
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
> Close
Check again
A Close R2 Back
=== backups 40x12
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose R2 Back
=== backups 40x15
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose R2 Back
=== backups 80x24
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
A Choose R2 Back
+327 -3
View File
@@ -1521,7 +1521,7 @@
Same choice as on 3 Nov: yes
Choose systems
Copy from an old card or a folder
1-4 of 8
1-4 of 9
Start Install B Back
=== plan-record 40x15
RetroBIOS: RetroArch
@@ -1529,7 +1529,6 @@
1 file to download, 16.0 KB
BIOS folder:
~/.config/retroarch/system
For nintendo-gba.
> Install
Same choice as on 3 Nov: yes
Choose systems
@@ -1537,6 +1536,7 @@
Change where
Details
Change
More
Quit
Start Install B Back
=== plan-record 80x24
@@ -1553,6 +1553,7 @@
Change where
Details
Change
More
Quit
@@ -1562,5 +1563,328 @@
Start Install B Back
=== more 40x12
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
Start Open B Back
=== more 40x15
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
Start Open B Back
=== more 80x24
RetroBIOS: More
> Remove files
Backups
Put back a backup
Delete a backup
Start Open B Back
=== remove 40x12
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
Start Choose B Back
=== remove 40x15
RetroBIOS: Remove files
Choose what to remove. A file changed
or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
Start Choose B Back
=== remove 80x24
RetroBIOS: Remove files
Choose what to remove. A file changed or added by hand stays.
> All RetroBIOS files 528.0 KB
nintendo-gba 16.0 KB
sony-playstation 512.0 KB
Start Choose B Back
=== removal 40x12
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
Start Remove B Back
=== removal 40x15
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder:
~/.config/retroarch/system
1 file stays: 1 changed since it was
installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
Start Remove B Back
=== removal 80x24
RetroBIOS: Remove files
2 files go, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
1 file stays: 1 changed since it was installed.
> Remove 512.0 KB
Keep a backup: no --backup
Details
Start Remove B Back
=== removal-confirm 40x12
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
Start Confirm B Back
=== removal-confirm 40x15
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is
freed.
> Remove
Back
Start Confirm B Back
=== removal-confirm 80x24
RetroBIOS: Confirm
Remove 2 files for good? 512.0 KB is freed.
> Remove
Back
Start Confirm B Back
=== removal-done 40x12
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
Start Close B Back
=== removal-done 40x15
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.co.../retroarch/system
> Close
Check again
Start Close B Back
=== removal-done 80x24
RetroBIOS: Done
Removed 2 files, 512.0 KB freed.
BIOS folder: ~/.config/retroarch/system
> Close
Check again
Start Close B Back
=== backups 40x12
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
Start Choose B Back
=== backups 40x15
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
Start Choose B Back
=== backups 80x24
RetroBIOS: Backups
Newest first.
> 3 Nov 12:00 2 files, 512.0 KB
20 Oct 09:30 1 file, 16.0 KB
Back
Start Choose B Back
+4 -2
View File
@@ -63,9 +63,11 @@ JOURNEY_KEYS = {
JOURNEY_WORDS = {
"first_install": 47,
"card_with_games": 87,
"update": 70,
# A plan whose folder has a record names More (one word): an update
# and a second run of one system.
"update": 71,
"one_system": 179,
"one_system_again": 67,
"one_system_again": 68,
# Change holds every option one level down now (design 4.4): its
# headings and the rows for Emulators, a pack, the device and the
# internet, the intro sentence dropped, 10 words on each of its two
+470
View File
@@ -0,0 +1,470 @@
"""Removing what the installer placed, and putting a backup back.
Removal deletes for good by default, or moves into a backup with --backup.
Only the install record says what may go: a file it lists, still its
recorded bytes, that the collection can serve again. Each test drives the
real install.py against a loopback repository, or the planner directly for
records no install writes (a crafted one, a drive that folds case).
"""
from __future__ import annotations
import tests # noqa: F401 offline, scratch under tmp/, the suite's own cache
import contextlib
import hashlib
import io
import json
import os
import shutil
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
from unittest import mock
REPO_ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(REPO_ROOT))
sys.path.insert(0, str(REPO_ROOT / "tests"))
import install # noqa: E402
from test_install_selection import FakeRepository # noqa: E402
try:
import pty
except ImportError: # Windows has no pseudo-terminal module.
pty = None
class SharedRepository(FakeRepository):
"""The loopback repository with a file two systems read."""
PAYLOADS = {**FakeRepository.PAYLOADS,
"shared.bin": (b"shared", ["sony-playstation", "nintendo-gba"], None, None)}
def run(self, *options: str, stdin: str | None = None) -> subprocess.CompletedProcess:
# --restore and --delete-backup name their folder alone.
command = self.command(*options)
if options[0] in ("--restore", "--delete-backup"):
command = [*command[:2], *options]
return subprocess.run(
command, env=self.env(), capture_output=True, text=True,
timeout=60, check=False, input=stdin,
stdin=None if stdin is not None else subprocess.DEVNULL,
)
def answer(self, reply: str, *options: str) -> tuple[int, str]:
"""A run at a terminal that answers reply to its question: (code, text)."""
main, other = pty.openpty()
try:
proc = subprocess.Popen(self.command(*options), env=self.env(), stdin=other,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
os.write(main, reply.encode() + b"\n")
out, _err = proc.communicate(timeout=60)
finally:
os.close(main)
os.close(other)
return proc.returncode, out.decode()
@property
def record(self) -> Path:
return self.dest.parent / install.BACKUP_DIR / f"{self.dest.name}.install.json"
def snapshot(self) -> dict[str, bytes]:
return {path.relative_to(self.dest).as_posix(): path.read_bytes()
for path in sorted(self.dest.rglob("*")) if path.is_file()}
def events(self, proc: subprocess.CompletedProcess) -> list[dict]:
return [json.loads(line) for line in proc.stdout.splitlines() if line.startswith("{")]
def setup(self) -> dict:
return json.loads(self.record.read_text())["setups"]["retroarch"]
def install_both(self) -> None:
proc = self.run("--system", "sony-playstation", "--system", "nintendo-gba", "--yes")
assert proc.returncode == 0, proc.stdout + proc.stderr
GBA_ONLY = ["gba_bios.bin", "mgba/extra.bin"]
PSX = ["pcsx/extra.bin", "scph5500.bin", "scph5501.bin"]
class RemoveOneOfTwoSystems(unittest.TestCase):
def test_the_shared_file_stays_and_a_backup_puts_the_folder_back(self):
with SharedRepository() as repo:
repo.install_both()
before = repo.snapshot()
self.assertEqual(sorted(before), sorted(GBA_ONLY + PSX + ["shared.bin"]))
proc = repo.run("--remove", "--system", "nintendo-gba", "--backup", "--yes")
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
self.assertEqual(sorted(repo.snapshot()), sorted(PSX + ["shared.bin"]))
self.assertIn("shared.bin: still needed by sony-playstation", proc.stdout)
setup = repo.setup()
self.assertEqual(setup["choice"], ["--system", "sony-playstation"])
self.assertEqual(sorted(item["dest"] for item in setup["files"]),
sorted(PSX + ["shared.bin"]))
[backup] = install.list_backups(repo.dest)
self.assertEqual((backup["files"], backup["source"]), (2, "remove"))
proc = repo.run("--restore", str(backup["folder"]))
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
self.assertEqual(repo.snapshot(), before)
setup = repo.setup()
self.assertEqual(sorted(item["dest"] for item in setup["files"]), sorted(before))
self.assertEqual(install.record_options(setup["choice"]),
[("--system", "sony-playstation"), ("--system", "nintendo-gba")])
def test_everything_into_a_backup_and_back_with_its_record(self):
with SharedRepository() as repo:
repo.install_both()
before, setup = repo.snapshot(), repo.setup()
proc = repo.run("--remove", "--backup", "--yes")
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
self.assertEqual((repo.snapshot(), repo.record.exists()), ({}, False))
[backup] = install.list_backups(repo.dest)
self.assertEqual(repo.run("--restore", str(backup["folder"])).returncode, 0)
self.assertEqual(repo.snapshot(), before)
self.assertEqual((repo.setup()["choice"], repo.setup()["files"]),
(setup["choice"], setup["files"]))
def test_removal_deletes_for_good_by_default(self):
with SharedRepository() as repo:
repo.install_both()
proc = repo.run("--remove", "--system", "nintendo-gba", "--yes")
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
self.assertIn("Removed 2 files, 12 B freed.", proc.stdout)
self.assertEqual(install.list_backups(repo.dest), [])
holder = repo.dest.parent / install.BACKUP_DIR
self.assertEqual(sorted(path.name for path in holder.iterdir()),
[f"{repo.dest.name}.install.json"])
def test_removing_everything_leaves_no_record(self):
with SharedRepository() as repo:
repo.install_both()
proc = repo.run("--remove", "--yes")
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
self.assertEqual(repo.snapshot(), {})
self.assertFalse(repo.record.exists())
def test_dry_run_lists_and_removes_nothing(self):
with SharedRepository() as repo:
repo.install_both()
before = repo.snapshot()
proc = repo.run("--remove", "--system", "nintendo-gba", "--dry-run")
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
for dest in GBA_ONLY:
self.assertIn(f" {dest}\n", proc.stdout)
self.assertIn("Nothing was removed (--dry-run).", proc.stdout)
self.assertEqual(repo.snapshot(), before)
def test_one_file(self):
with SharedRepository() as repo:
repo.install_both()
proc = repo.run("--remove", "--file", "gba_bios.bin", "--file",
str(repo.dest / "not-ours.bin"), "--yes")
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
self.assertNotIn("gba_bios.bin", repo.snapshot())
self.assertIn("not-ours.bin: not installed by RetroBIOS", proc.stdout)
outside = repo.run("--remove", "--file", str(repo.root / "x.bin"), "--yes")
self.assertEqual(outside.returncode, 2)
self.assertIn("is not inside", outside.stderr)
def test_a_core(self):
with SharedRepository() as repo:
repo.install_both()
proc = repo.run("--remove", "--core", "mgba", "--yes")
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
self.assertEqual(sorted(repo.snapshot()),
sorted(["gba_bios.bin", "shared.bin"] + PSX))
self.assertIn(("--core", "pcsx_rearmed"),
install.record_options(repo.setup()["choice"]))
class NeverTouched(unittest.TestCase):
def test_a_changed_file_and_one_added_by_hand_stay(self):
with SharedRepository() as repo:
repo.install_both()
(repo.dest / "scph5501.bin").write_bytes(b"the user's own")
(repo.dest / "mine.bin").write_bytes(b"added by hand")
proc = repo.run("--remove", "--yes")
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
self.assertEqual(repo.snapshot(), {"scph5501.bin": b"the user's own",
"mine.bin": b"added by hand"})
self.assertIn("1 file stays: 1 changed since it was installed.", proc.stdout)
self.assertIn("scph5501.bin: changed since it was installed", proc.stdout)
self.assertIn("1 other file stays, not installed by RetroBIOS.", proc.stdout)
def test_a_link_in_place_of_a_file_stays_and_its_target_too(self):
with SharedRepository() as repo:
repo.install_both()
target = repo.root / "elsewhere.bin"
shutil.copy(repo.dest / "gba_bios.bin", target)
(repo.dest / "gba_bios.bin").unlink()
(repo.dest / "gba_bios.bin").symlink_to(target)
proc = repo.run("--remove", "--system", "nintendo-gba", "--yes")
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
self.assertTrue((repo.dest / "gba_bios.bin").is_symlink())
self.assertTrue(target.is_file())
self.assertIn("gba_bios.bin: a link, never followed", proc.stdout)
class ExitCodes(unittest.TestCase):
@unittest.skipIf(pty is None, "a question needs a pseudo-terminal")
def test_zero_one_and_two(self):
with SharedRepository() as repo:
no_record = repo.run("--remove", "--yes")
self.assertEqual(no_record.returncode, 2)
repo.install_both()
asked = repo.run("--remove")
self.assertEqual(asked.returncode, 2)
self.assertIn("add --yes", asked.stderr)
declined, said = repo.answer("n", "--remove")
self.assertEqual(declined, 2, said)
self.assertIn("Remove them for good? [y/N]", said)
self.assertIn("Nothing was removed.", said)
self.assertEqual(len(repo.installed()), 6)
if not (hasattr(os, "geteuid") and os.geteuid() == 0):
(repo.dest / "pcsx").chmod(0o555)
try:
failed = repo.run("--remove", "--system", "sony-playstation", "--yes")
finally:
(repo.dest / "pcsx").chmod(0o755)
self.assertEqual(failed.returncode, 1, failed.stdout + failed.stderr)
self.assertIn("failed: pcsx/extra.bin", failed.stderr)
# The record keeps what is still there.
self.assertIn("pcsx/extra.bin",
[item["dest"] for item in repo.setup()["files"]])
done = repo.run("--remove", "--yes")
self.assertEqual(done.returncode, 0, done.stdout + done.stderr)
nothing = repo.run("--remove", "--yes")
self.assertEqual(nothing.returncode, 2)
def test_options_an_action_does_not_read_are_refused(self):
with SharedRepository() as repo:
for argv, words in (
(("--file", "a.bin"), "--file applies to --remove"),
(("--backup",), "--backup applies to --remove"),
(("--remove", "--region", "us"), "--remove takes no --region"),
(("--remove", "--system", "nintendo-gba", "--core", "mgba"),
"not --system and --core"),
(("--remove", "--backups"), "two actions"),
(("--backups", "--yes"), "--backups takes no --yes"),
):
with self.subTest(argv=argv):
proc = repo.run(*argv)
self.assertEqual(proc.returncode, 2)
self.assertIn(words, proc.stderr)
class WithoutARecord(unittest.TestCase):
def test_a_missing_or_damaged_record_removes_nothing_in_one_line(self):
with SharedRepository() as repo:
repo.install_both()
before = repo.snapshot()
repo.record.write_text("{not json")
proc = repo.run("--remove", "--yes")
self.assertEqual(proc.returncode, 2)
self.assertEqual(repo.snapshot(), before)
self.assertEqual(proc.stderr.strip().count("\n"), 0, proc.stderr)
self.assertIn("Nothing was removed", proc.stderr)
self.assertIn("is damaged", proc.stderr)
repo.record.unlink()
proc = repo.run("--remove", "--yes")
self.assertEqual(proc.returncode, 2)
self.assertEqual(proc.stderr.strip().count("\n"), 0, proc.stderr)
self.assertIn("no install record", proc.stderr)
self.assertEqual(repo.snapshot(), before)
class Events(unittest.TestCase):
def test_every_new_kind(self):
with SharedRepository() as repo:
repo.install_both()
plan = repo.events(repo.run("--remove", "--system", "nintendo-gba", "--dry-run",
"--events"))
self.assertEqual([event["event"] for event in plan],
["start", "removal_plan", "end"])
self.assertEqual(plan[0]["mode"], "remove")
self.assertEqual((plan[1]["files"], plan[1]["bytes"], plan[1]["dests"]),
(2, 12, GBA_ONLY))
self.assertEqual(plan[1]["kept"], [{"dest": "shared.bin", "reason": "shared"}])
run = repo.events(repo.run("--remove", "--system", "nintendo-gba", "--backup",
"--events", "--yes"))
kinds = [event["event"] for event in run]
self.assertEqual(kinds, ["start", "removal_plan", "removed", "removed", "backup",
"end"])
self.assertTrue(all(event["ok"] and event["moved_to"]
for event in run if event["event"] == "removed"))
self.assertEqual(run[4]["status"], "made")
listed = repo.events(repo.run("--backups", "--events"))
self.assertEqual([event["event"] for event in listed], ["start", "backup", "end"])
self.assertEqual((listed[0]["mode"], listed[1]["status"], listed[1]["files"]),
("list", "listed", 2))
folder = listed[1]["folder"]
back = repo.events(repo.run("--restore", folder, "--events"))
self.assertEqual([event["event"] for event in back],
["start", "restored", "restored", "end"])
self.assertEqual(back[0]["mode"], "restore")
gone = repo.events(repo.run("--delete-backup", folder, "--events", "--yes"))
self.assertEqual([event["event"] for event in gone], ["start", "backup", "end"])
self.assertEqual((gone[1]["status"], gone[2]["code"]), ("deleted", 0))
self.assertFalse(Path(folder).exists())
for event in plan + run + listed + back + gone:
self.assertEqual(sorted(event), sorted(
["event", *install.EVENT_KEYS[event["event"]]]))
class DeleteABackup(unittest.TestCase):
def test_only_a_backup_folder_and_only_with_a_yes(self):
with SharedRepository() as repo:
repo.install_both()
repo.run("--remove", "--system", "nintendo-gba", "--backup", "--yes")
[backup] = install.list_backups(repo.dest)
asked = repo.run("--delete-backup", str(backup["folder"]))
self.assertEqual(asked.returncode, 2)
self.assertTrue(backup["folder"].is_dir())
refused = repo.run("--delete-backup", str(repo.dest), "--yes")
self.assertEqual(refused.returncode, 2)
self.assertTrue((repo.dest / "shared.bin").is_file())
done = repo.run("--delete-backup", str(backup["folder"]), "--yes")
self.assertEqual(done.returncode, 0, done.stdout + done.stderr)
self.assertFalse(backup["folder"].exists())
def _record(folder: Path, files: list[dict], others: dict | None = None,
choice: list[str] | None = None) -> dict:
setup = {"written": "2026-11-03T12:00:00Z", "list": {"version": "v1", "generated": ""},
"choice": choice or ["--all-files"], "files": files}
return {"schema": 1, "folder": str(folder), "setups": {"retroarch": setup, **(others or {})}}
def _item(dest: str, payload: bytes, root: str = "") -> dict:
return {"dest": dest, "root": root, "sha1": hashlib.sha1(payload).hexdigest(),
"size": len(payload), "from": "download"}
def _served(*dests_payloads: tuple[str, bytes]) -> dict:
return {"files": [{"dest": dest, "sha1": hashlib.sha1(payload).hexdigest(),
"size": len(payload), "cores": None, "systems": ["nintendo-gba"]}
for dest, payload in dests_payloads]}
class ACraftedRecord(unittest.TestCase):
"""A record anyone could write never makes the installer delete outside
the BIOS folder, through a link, or anything but a regular file."""
def setUp(self):
self.root = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp"))
self.addCleanup(shutil.rmtree, self.root, True)
self.folder = self.root / "bios"
self.folder.mkdir()
@unittest.skipUnless(hasattr(os, "mkfifo"), "a FIFO is POSIX")
def test_nothing_outside_or_through_a_link_is_removed(self):
payload = b"precious"
(self.root / "outside.bin").write_bytes(payload)
elsewhere = self.root / "elsewhere"
elsewhere.mkdir()
(elsewhere / "deep.bin").write_bytes(payload)
(self.folder / "linked").symlink_to(elsewhere)
(self.folder / "link.bin").symlink_to(self.root / "outside.bin")
os.mkfifo(self.folder / "pipe.bin")
dests = ["../outside.bin", str(self.root / "outside.bin"), "linked/deep.bin",
"link.bin", "pipe.bin", "a/../../outside.bin", "C:/outside.bin"]
record = _record(self.folder, [_item(dest, payload) for dest in dests]
+ [_item("saved.bin", payload, "save")])
manifest = _served(*[(dest, payload) for dest in [*dests, "saved.bin"]])
removal = install.plan_removal("retroarch", self.folder, record, manifest)
self.assertEqual(removal.remove, [])
reasons = {item["dest"]: item["reason"] for item in removal.kept}
self.assertEqual(reasons, {
"../outside.bin": "outside", str(self.root / "outside.bin"): "outside",
"linked/deep.bin": "link", "link.bin": "link", "pipe.bin": "not_a_file",
"a/../../outside.bin": "outside", "C:/outside.bin": "outside",
"saved.bin": "outside"})
install.remove_files(removal, record["setups"]["retroarch"], False)
self.assertEqual((self.root / "outside.bin").read_bytes(), payload)
self.assertEqual((elsewhere / "deep.bin").read_bytes(), payload)
def test_a_file_swapped_after_the_plan_stays(self):
payload = b"ours"
(self.folder / "a.bin").write_bytes(payload)
record = _record(self.folder, [_item("a.bin", payload)])
removal = install.plan_removal("retroarch", self.folder, record,
_served(("a.bin", payload)))
self.assertEqual(len(removal.remove), 1)
(self.folder / "a.bin").unlink()
(self.folder / "a.bin").symlink_to(self.root / "nowhere")
removed, failed, _run = install.remove_files(removal, record["setups"]["retroarch"],
False)
self.assertEqual((removed, [item["dest"] for item in failed]), ([], ["a.bin"]))
self.assertTrue((self.folder / "a.bin").is_symlink())
def test_a_file_the_list_no_longer_serves_stays(self):
payload = b"a key the user supplied"
(self.folder / "keys.bin").write_bytes(payload)
record = _record(self.folder, [_item("keys.bin", payload)])
removal = install.plan_removal("retroarch", self.folder, record, {"files": []})
self.assertEqual([item["reason"] for item in removal.kept], ["not_servable"])
other = install.plan_removal("retroarch", self.folder, record,
_served(("keys.bin", b"another release")))
self.assertEqual([item["reason"] for item in other.kept], ["not_servable"])
class AFoldingDrive(unittest.TestCase):
"""FAT and exFAT open a name whatever its case: the record, the list and
another setup are compared folded there."""
def setUp(self):
self.root = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp"))
self.addCleanup(shutil.rmtree, self.root, True)
self.folder = self.root / "bios"
self.folder.mkdir()
self.payload = b"bios"
(self.folder / "SCPH5501.BIN").write_bytes(self.payload)
def plan(self, keeps_case: bool, others: dict | None = None) -> install.Removal:
record = _record(self.folder, [_item("SCPH5501.BIN", self.payload)], others)
with mock.patch.object(install, "keeps_case", return_value=keeps_case):
return install.plan_removal("retroarch", self.folder, record,
_served(("scph5501.bin", self.payload)))
def test_the_list_s_name_in_another_case_is_the_same_file(self):
self.assertEqual([entry["dest"] for entry in self.plan(False).remove],
["SCPH5501.BIN"])
self.assertEqual([item["reason"] for item in self.plan(True).kept], ["not_servable"])
def test_another_setup_s_file_in_another_case_stays(self):
other = {"lakka": {"written": "", "choice": ["--all-files"],
"files": [_item("scph5501.bin", self.payload)]}}
removal = self.plan(False, other)
self.assertEqual([(item["reason"], item["what"]) for item in removal.kept],
[("shared", "Lakka")])
def test_the_removal_runs_on_a_folding_drive(self):
removal = self.plan(False)
record = _record(self.folder, [_item("SCPH5501.BIN", self.payload)])
with contextlib.redirect_stdout(io.StringIO()):
removed, failed, _run = install.remove_files(
removal, record["setups"]["retroarch"], False)
self.assertEqual((len(removed), failed), (1, []))
self.assertFalse((self.folder / "SCPH5501.BIN").exists())
class RestoreAnInstallBackup(unittest.TestCase):
def test_the_record_lets_go_of_the_user_s_files_put_back(self):
with SharedRepository() as repo:
repo.dest.mkdir(parents=True)
(repo.dest / "gba_bios.bin").write_bytes(b"the user's own")
repo.install_both()
[backup] = install.list_backups(repo.dest)
self.assertEqual(backup["source"], "install")
self.assertIn("gba_bios.bin", [item["dest"] for item in repo.setup()["files"]])
proc = repo.run("--restore", str(backup["folder"]))
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
self.assertEqual((repo.dest / "gba_bios.bin").read_bytes(), b"the user's own")
self.assertNotIn("gba_bios.bin", [item["dest"] for item in repo.setup()["files"]])
if __name__ == "__main__":
unittest.main()
+201 -3
View File
@@ -1063,9 +1063,83 @@ def golden_states() -> dict:
told.stack.append("details")
states["result-details"] = told
states["plan-record"] = record_state()
states["more"] = more_state("more")
states["remove"] = more_state("more", "remove")
states["removal"] = removal_state()
states["removal-confirm"] = removal_state()
install.tui_update(states["removal-confirm"], Key("enter"))
states["removal-done"] = removal_done_state()
states["backups"] = backups_state()
return states
# What an install of the PlayStation and the Game Boy Advance recorded.
MORE_RECORD = {"written": "2026-11-03T12:00:00Z", "list": {"version": "v1", "generated": ""},
"choice": ["--all-files"],
"files": [{"dest": dest, "root": "", "sha1": "0" * 40, "size": size,
"from": "download"}
for dest, size in (("gba_bios.bin", 16384), ("pcsx/extra.bin", 4),
("scph5500.bin", 524288))]}
REMOVAL_PLAN = {"event": "removal_plan", "platform": "retroarch", "folder": str(SYSTEM_DIR),
"files": 2, "bytes": 524292, "systems": ["sony-playstation"],
"dests": ["pcsx/extra.bin", "scph5500.bin"],
"kept": [{"dest": "scph5501.bin", "reason": "changed"}], "gone": 0,
"backup": False, "message": ""}
BACKUPS = [{"event": "backup", "folder": str(HOME / ".config" / "retroarch" / "retrobios-backup"
/ name), "date": date, "files": files,
"bytes": size, "source": source, "status": "listed", "message": ""}
for name, date, files, size, source in (
("20261103-120000", "2026-11-03 12:00:00", 2, 524292, "remove"),
("20261020-093000", "2026-10-20 09:30:00", 1, 16384, "install"))]
def more_state(*screens: str) -> install.TuiState:
"""The plan of a folder whose record holds three files, More opened."""
state = checked_state()
state.record = json.loads(json.dumps(MORE_RECORD))
for screen in screens:
rows = install.tui_rows(state)
state.focus[state.screen] = [row.action for row in rows].index(screen)
assert install.tui_update(state, Key("enter")) == [], screen
return state
def removal_state(system: bool = True) -> install.TuiState:
"""The removal plan of the PlayStation, read by its dry run."""
state = more_state("more", "remove")
values = [row.value for row in install.tui_rows(state)]
state.focus["remove"] = values.index("sony-playstation") if system else 0
effects = install.tui_update(state, Key("enter"))
assert effects == [("run", "removal_plan")], effects
install.tui_receive(state, ("event", state.run_id, REMOVAL_PLAN))
install.tui_receive(state, ("ended", state.run_id, 0, []))
return state
def removal_done_state() -> install.TuiState:
state = removal_state()
install.tui_update(state, Key("enter"))
effects = install.tui_update(state, Key("enter"))
assert effects == [("run", "remove")], effects
for dest, size in (("pcsx/extra.bin", 4), ("scph5500.bin", 524288)):
install.tui_receive(state, ("event", state.run_id, {
"event": "removed", "platform": "retroarch", "dest": dest, "size": size,
"ok": True, "reason": "", "moved_to": ""}))
install.tui_receive(state, ("ended", state.run_id, 0, []))
return state
def backups_state(purpose: str = "backups") -> install.TuiState:
state = more_state("more")
state.focus["more"] = [row.action for row in install.tui_rows(state)].index(purpose)
effects = install.tui_update(state, Key("enter"))
assert effects == [("run", "backups")], effects
for event in BACKUPS:
install.tui_receive(state, ("event", state.run_id, event))
install.tui_receive(state, ("ended", state.run_id, 0, []))
return state
# A board list as install/targets/ publishes it, read by Device: the boards
# by the names the list gives them, the device images each one runs.
TARGETS = {"bcm2711": {"cores": ["pcsx_rearmed"], "images": ["rpi4"]},
@@ -1187,7 +1261,7 @@ class RecordedPlan(unittest.TestCase):
self.assertTrue(state.opened_on_plan)
self.assertEqual(state.stack, ["setup", "plan"])
self.assertEqual(install.tui_rows(state)[0].action, "install")
press(state, "end", "up", "up", "up")
press(state, "end", "up", "up", "up", "up")
self.assertEqual(install.tui_rows(state)[state.focus["plan"]].label, "Change where")
press(state, "enter")
self.assertEqual(state.screen, "setup")
@@ -15182,8 +15256,9 @@ SCREEN_WORDS = {
"result-details": (30, 30, 19, 19),
# The plan's words, plus the recorded choice by name, its row (the one
# press back to the whole list) and Change where (back to the setups,
# the plan having opened on the one found).
"plan-record": (38, 42, 42, 42),
# the plan having opened on the one found), and More, the record being
# what a removal reads.
"plan-record": (38, 42, 43, 43),
# Change holds every option one level below the plan (design 4.4): the
# rows for Emulators, a pack, the device and the internet, and the five
# headings that group them, the intro sentence they replace dropped.
@@ -15191,6 +15266,14 @@ SCREEN_WORDS = {
# A list of boards and one of emulators, each with the line that says
# what the choice does and the gloss of "board".
"device": (35, 35, 33, 33), "emulators": (29, 29, 27, 27),
# A plan names More (one word) where the folder has a record or a
# backup (design 4.3), the first install's plan unchanged. More's
# four rows, Remove files with each system the record holds and its
# size, the removal plan (what goes, the space freed, the folder, what
# stays and why), its confirm and result, and the backups newest first.
"more": (17, 17, 15, 15), "remove": (31, 31, 29, 29), "removal": (34, 34, 32, 32),
"removal-confirm": (18, 18, 16, 16), "removal-done": (18, 18, 16, 16),
"backups": (24, 24, 22, 22),
}
@@ -15200,6 +15283,121 @@ def screen_words(lines: list) -> int:
if re.search(r"[A-Za-z0-9]", token) and "/" not in token)
class MoreScreens(unittest.TestCase):
"""More: removal, the backups, putting one back and deleting one, each
a child run with its own options and none of the plan's."""
def setUp(self):
patcher = mock.patch.object(install, "_mounted_cards", return_value=[])
patcher.start()
self.addCleanup(patcher.stop)
def test_a_plan_names_more_where_it_has_something_to_act_on(self):
self.assertNotIn("more", [row.action for row in install.tui_rows(checked_state())])
self.assertEqual([row.action for row in install.tui_rows(more_state())][-2:],
["more", "quit"])
done = golden_states()["plan-in-place"]
done.has_backups = True
self.assertEqual(install.tui_rows(done)[-1].action, "more")
def test_the_removal_plan_asks_its_own_child(self):
state = removal_state()
state.regions = ["japan"]
argv = install.tui_argv(state, "removal_plan", "python", "install.py")
self.assertEqual(argv[-4:], ["--remove", "--system=sony-playstation", "--dry-run",
"--events"])
self.assertNotIn("--region=japan", argv)
self.assertIn(f"--dest={SYSTEM_DIR}", argv)
self.assertEqual(state.screen, "removal")
self.assertEqual(install.tui_rows(state)[0].label, "Remove 512.0 KB")
def test_everything_removes_with_no_system(self):
state = removal_state(system=False)
argv = install.tui_argv(state, "removal_plan", "python", "install.py")
self.assertEqual(argv[-3:], ["--remove", "--dry-run", "--events"])
def test_a_backup_is_one_row_away_and_the_removal_says_so(self):
state = removal_state()
state.focus["removal"] = 1
press(state, "enter")
self.assertTrue(state.removal_backup)
self.assertEqual(install.tui_rows(state)[0].label, "Move 512.0 KB to a backup")
state.focus["removal"] = 0
press(state, "enter")
self.assertEqual(state.screen, "actconfirm")
effects = press(state, "enter")
self.assertEqual(effects, [("run", "remove")])
argv = install.tui_argv(state, "remove", "python", "install.py")
self.assertEqual(argv[-4:], ["--system=sony-playstation", "--backup", "--events",
"--yes"])
def test_close_ends_with_the_removal_s_code_and_back_counts_again(self):
state = removal_done_state()
self.assertEqual(state.screen, "actdone")
self.assertIn("Removed 2 files, 512.0 KB freed.",
screen_text(install.tui_view(state, 80, 24)))
press(state, "enter")
self.assertEqual(state.exit_code, 0)
state = removal_done_state()
with mock.patch.object(install, "setup_record", return_value=(None, None, "")):
effects = press(state, "esc")
self.assertEqual(effects, [("run", "check")])
self.assertEqual(state.screen, "checking")
# The record is read again: the removal changed it.
self.assertIsNone(state.record)
def test_a_failure_is_said_and_ends_on_one(self):
state = removal_state()
press(state, "enter", "enter")
install.tui_receive(state, ("event", state.run_id, {
"event": "removed", "platform": "retroarch", "dest": "scph5500.bin",
"size": 524288, "ok": False, "reason": "Permission denied", "moved_to": ""}))
install.tui_receive(state, ("ended", state.run_id, 1, []))
self.assertIn("1 file failed.", screen_text(install.tui_view(state, 80, 24)))
press(state, "enter")
self.assertEqual(state.exit_code, 1)
def test_put_back_and_delete_name_the_backup_alone(self):
folder = BACKUPS[0]["folder"]
for purpose, run, argv in (
("putback", "restore", [f"--restore={folder}", "--events"]),
("dropbackup", "delete_backup",
[f"--delete-backup={folder}", "--events", "--yes"])):
with self.subTest(purpose=purpose):
state = backups_state(purpose)
press(state, "enter")
self.assertEqual(state.screen, "actconfirm")
self.assertEqual(press(state, "enter"), [("run", run)])
self.assertEqual(install.tui_argv(state, run, "python", "install.py"),
["python", "install.py", *argv])
def test_a_backup_looked_at_offers_both(self):
state = backups_state()
press(state, "down", "enter")
self.assertEqual(state.screen, "backup")
self.assertEqual(state.backup_chosen["date"], BACKUPS[1]["date"])
self.assertEqual([row.action for row in install.tui_rows(state)],
["bkrestore", "bkdelete", "back"])
argv = install.tui_argv(state, "backups", "python", "install.py")
self.assertEqual(argv[-2:], ["--backups", "--events"])
def test_without_a_record_nothing_is_offered_to_remove(self):
state = checked_state()
state.record = None
state.stack += ["more", "remove"]
self.assertEqual([row.action for row in install.tui_rows(state)], ["back"])
self.assertIn("No install record here", screen_text(install.tui_view(state, 80, 24)))
def test_the_files_and_what_stays_are_on_details(self):
state = removal_state()
state.focus["removal"] = [row.action for row in install.tui_rows(state)].index(
"details")
press(state, "enter")
text = screen_text(install.tui_view(state, 80, 24))
self.assertIn("pcsx/extra.bin", text)
self.assertIn("scph5501.bin: changed since it was installed", text)
class ScreenWordBudgets(unittest.TestCase):
def setUp(self):
patcher = mock.patch.object(install, "_mounted_cards", return_value=[])