ES-DE: its first start on a fresh install writes the library

ES-DE's library adapter writes custom_systems/es_systems.xml and the game
lists under /app0/es-de/ES-DE before ES-DE runs, but ES-DE makes that folder
itself only once it starts. On a fresh install's first start every mkdir
below it failed, all 29 writes failed (28 game lists and the systems file)
and ES-DE showed no games; from the second start on it worked. The earlier
ES-DE evidence never met this: those consoles had ES-DE's folder already.
The adapter makes the folder first.

Evidence: tests/esde_library_test.cpp's first start now begins without the
folder and checks 0 failures and a written systems file (it fails without
this change): python3 -m unittest tests.test_esde_library OK. On the
console, evidence/esde-folder-names: the first start before the change,
'28 systems, 255 games ... 29 failures', 'systems written -1'; the second,
0 failures; the first start after it (ES-DE's folder moved aside), '34
systems, 317 games ... 0 failures', 'systems written 34', every system's
path /app0/content/<name>; a home launch of a fresh install started the
picker (picker 1, es-de 1, remembered ask -> picker). python3
tools/evidence.py compare evidence: 131 replayed, 0 failed. tools/verify.sh:
all five gates PASS.
This commit is contained in:
Mihawk committed 2026-10-17 19:36:17 -04:00
1 parent a9cf1fbcc1
commit 0ebf7c7af5
4 files changed
+57 -3

No files matched your search

+32
View File
@@ -0,0 +1,32 @@
{
"step": "esde-folder-names",
"recorded": "2026-10-17T23:18:12Z",
"console_run": "",
"revision": "the commits this record lands with (content folders as ES-DE names them; a cartridge system's archives; ES-DE's first start)",
"command": "tools/run-title.sh --no-build --no-deploy --home-launch --watch 30; tools/run-title.sh --no-build --no-deploy --picker-test=300:es-de --frontend-capture=25,40 --watch 60; FTP reads of content/, playlists/, config/ and es-de/ES-DE/custom_systems/es_systems.xml",
"raw_capture": "klog/esde-folder-names/record.txt",
"raw_lines": 20,
"raw_bytes": 2224,
"lines": [
"Console: the owner's base PS5 (1440p, 120 Hz, VRR), a fresh install (no config/frontend.cfg), 325 of the owner's game backups in 34 ES-DE folders, 2026-10-17.",
"Seeded as an earlier build left it: content/Sega - Dreamcast (a placeholder; no dreamcast folder), content/Nintendo - Game Boy (a placeholder; gb held 10 backups), content/Sony - PlayStation (a placeholder; psx held 10), playlists/Nintendo - Game Boy.lpl naming the placeholder, config/mGBA/Nintendo - Game Boy.opt.",
"Home-screen launch, build identity 02db7d47f5efd5e42dc17f121cd19125fa99a09ed80aeaae5786494d68b8f54e:",
" startup: system folders renamed as ES-DE names them = 3",
" startup: system folders made in content = 12",
" frontend: mode '', test run 0, picker test 0, picker 1, es-de 1, remembered ask, L1 0 -> picker",
" EXEC /app0/picker/picker.bin; [Frontend Picker] starts",
"After: no Sega - Dreamcast, Nintendo - Game Boy or Sony - PlayStation folder; dreamcast 1 file, gb 11, psx 11.",
" playlist: \"scan_content_dir\": \"/app0/content/gb\", \"path\": \"/app0/content/gb/placeholder-a.gb\"",
" config/mGBA/gb.opt",
"ES-DE's first start on that build (its folder not made yet):",
" start: library from RetroArch's playlists: 28 systems, 255 games (0 with ES-DE's details kept), 33 cores, 0 favourites, 0 played, 29 failures",
" start: systems written -1",
"ES-DE's second start (ES-DE had made its folder by then): 28 systems, 255 games, 0 failures; systems written 28.",
"ES-DE's first start after the fixes (build identity 22b5d1229342dc01e94a5b023dd9534b17836c1b70f038246a92ed5f811a9c61, ES-DE's folder moved aside):",
" start: library from RetroArch's playlists: 34 systems, 317 games (0 with ES-DE's details kept), 33 cores, 0 favourites, 0 played, 0 failures",
" start: systems written 34",
"es_systems.xml: 34 systems, every path /app0/content/<name>: amiga atari2600 atari5200 atari7800 atarijaguar atarilynx c64 dreamcast fds gamegear gb gba gbc gc genesis mastersystem n3ds n64 nds nes ngp ngpc pcengine pokemini psp psx sega32x sg-1000 snes supergrafx virtualboy wii wonderswan wonderswancolor",
"Host: python3 -m unittest tests.test_ps5_library tests.test_esde_library: OK; each new case fails without its fix.",
"Test files removed from the console afterwards; the owner's backups kept."
]
}
@@ -0,0 +1,16 @@
{
"step": "esde-folder-names",
"note": "Content folders take ES-DE's system names; folders earlier builds named as RetroArch does are renamed or merged with their playlists and per-folder settings; a fresh install starts in the picker; ES-DE's first start writes its library (it wrote nothing before: its own folder did not exist yet) and finds archived games of systems whose cores also take discs.",
"must_contain": [
"startup: system folders renamed as ES-DE names them = 3",
"picker 1, es-de 1, remembered ask, L1 0 -> picker",
"\"path\": \"/app0/content/gb/placeholder-a.gb\"",
"config/mGBA/gb.opt",
"29 failures",
"34 systems, 317 games (0 with ES-DE's details kept), 33 cores, 0 favourites, 0 played, 0 failures",
"start: systems written 34",
"every path /app0/content/<name>"
],
"must_not_contain": [],
"human_check": ""
}
+5 -1
View File
@@ -306,7 +306,11 @@ extern "C" int ps5_esde_write_library_to(const struct ps5_esde_library_paths *pa
}
const std::map<std::string, Reference> reference = read_reference(paths->reference);
const std::string data = paths->data;
/* Folders 0777 whatever the umask, for FTP's reach (src/permissions_ps5.cpp). */
/* Folders 0777 whatever the umask, for FTP's reach (src/permissions_ps5.cpp). ES-DE makes
* its own folder only once it runs, after this: on a fresh install's first start every
* write below failed and ES-DE showed no games, so the folder is made here first. */
mkdir(data.c_str(), 0777);
chmod(data.c_str(), 0777);
for (const char *folder : {"/custom_systems", "/gamelists"})
{
mkdir((data + folder).c_str(), 0777);
+4 -2
View File
@@ -216,10 +216,10 @@ int main(int argc, char **argv)
.value())
.empty());
/* Issue 33: ES-DE's ROM folder is the title's content folder, from the very first
* start (no settings file yet), not its own ~/ROMs (/app0/es-de/ROMs). */
* start (no settings file yet), not its own ~/ROMs (/app0/es-de/ROMs). On a fresh
* install ES-DE's own folder does not exist yet either: the library makes it. */
{
const std::string first = dir + "/first", rom = dir + "/content-first";
mkdir(first.c_str(), 0755);
mkdir(rom.c_str(), 0755);
const char *const roots[] = {rom.c_str(), nullptr};
const struct ps5_esde_library_paths fresh = {
@@ -233,6 +233,8 @@ int main(int argc, char **argv)
file.find_child_by_attribute("string", "name", name).attribute("value").value());
};
ps5_esde_write_library_to(&fresh, summary, sizeof(summary));
assert(std::string(summary).find(", 0 failures") != std::string::npos);
assert(pugi::xml_document().load_file((first + "/custom_systems/es_systems.xml").c_str()));
assert(value("ROMDirectory") == rom && value("MediaDirectory") == media);
/* ES-DE's own default, as an older start left it: replaced. */
write_text(first + "/settings/es_settings.xml",