wolf: fix ES-DE ROMDirectory staying blank despite the self-healing patch

Root-caused against the user's own live output: the settings file had
<string name="ROMDirectory" value="" /> — the key was present, just
empty. The self-healing check only tested whether the string
"ROMDirectory" appeared anywhere in the file, so a key that exists with
a blank value (ES-DE can write this itself if its own first-run "select
ROM directory" step goes unanswered in a headless Moonlight session,
saving an empty path back over GOW's template) looked "already
populated" and got skipped — leaving ROM discovery broken even after
the fix had run.

Now ROMDirectory is independently forced to /ROMs whenever its value is
blank, on top of (not instead of) the existing RunInBackground patch —
no longer gated on the key's mere presence. Verified against the exact
reported bug (ROMDirectory present but blank) plus the existing missing-
file, already-correct, and idempotent-rerun scenarios in isolated /tmp
harnesses before touching the real script.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
This commit is contained in:
Claude
2026-09-03 18:57:29 +00:00
parent a212be09c3
commit cbfc28c2dd
+35 -15
View File
@@ -1604,13 +1604,28 @@ GOW_ESDE_SETTINGS_TEMPLATE = """<?xml version="1.0"?>
<string name="UserThemeDirectory" value="" />
"""
if 'ROMDirectory' not in content:
if not content.strip():
content = GOW_ESDE_SETTINGS_TEMPLATE
else:
content = re.sub(r'[ \t]*<bool name="RunInBackground" value="[^"]*"[ \t]*/>[ \t]*\n?', '', content)
line = '<bool name="RunInBackground" value="false" />\n'
content = content.rstrip('\n') + '\n' + line
# CONFIRMED LIVE: a file can already contain a ROMDirectory *key* while
# its value is blank (e.g. ES-DE's own first-run "select ROM directory"
# step got skipped/cancelled in a headless Moonlight session and ES-DE
# saved that empty value back over GOW's own template) — checking only
# whether the key exists, as an earlier version of this fix did, treated
# that as "already populated" and left the blank path in place, so ES-DE
# kept finding zero games even though the fix had technically "run".
# Force it to /ROMs (the one true value in this container — see the
# 'roms:/ROMs' mount on every app that reads ROMs) whenever it's missing
# or empty, independent of whether RunInBackground needed touching.
m = re.search(r'<string name="ROMDirectory" value="([^"]*)"', content)
if not m or not m.group(1).strip():
content = re.sub(r'[ \t]*<string name="ROMDirectory" value="[^"]*"[ \t]*/>[ \t]*\n?', '', content)
content = content.rstrip('\n') + '\n' + '<string name="ROMDirectory" value="/ROMs" />\n'
with open(path, 'w') as f:
f.write(content)
ESDESETTINGSPY
@@ -4790,21 +4805,26 @@ default behavior here.
It writes \`esde-settings/es_settings.xml\` directly from GOW's own real
template (100+ settings, fetched from GOW's own repo, byte-for-byte
identical except \`RunInBackground\` flipped to off) whenever that file is
either missing or still the old broken placeholder — detected by checking
for \`ROMDirectory\`, a key only GOW's own bootstrap or ES-DE itself ever
writes. If the file already has a real, fully-populated value (because
EmulationStation has already launched at least once and GOW wrote its own
copy), only the one \`RunInBackground\` line is patched, leaving every
other setting (theme, scraper prefs, etc.) untouched. Either way, one
missing or empty. If the file already has real content, only the one
\`RunInBackground\` line is patched, leaving every other setting (theme,
scraper prefs, etc.) untouched — **except \`ROMDirectory\`, which is always
independently forced to \`/ROMs\` whenever its value is blank**, regardless
of whether the rest of the file looks populated. Either way, one
\`sudo ./setup.sh wolf\` run is enough — no need to connect via Moonlight
first. **Confirmed live, the hard way, twice:** earlier versions of this
fix either pre-created a minimal stub that made GOW skip writing its own
template (breaking ROM discovery on every system, since the ROM path fell
back to something other than \`/ROMs\`), or only patched an already-existing
file and left a genuinely missing/broken one alone, requiring exactly the
manual Moonlight-connect step this version removes. Setting it by hand
still works too, any time: **Main Menu → Other Settings → Run in
background (while game is launched) → off**.
first. **Confirmed live, the hard way, three times:** earlier versions of
this fix (1) pre-created a minimal stub that made GOW skip writing its own
template, breaking ROM discovery on every system since the ROM path fell
back to something other than \`/ROMs\`; (2) only patched an already-existing
file and left a genuinely missing/broken one alone, requiring a manual
Moonlight-connect step; and (3) treated the mere *presence* of the
\`ROMDirectory\` key as proof the file was already correctly populated —
but ES-DE can write that key with a **blank value** (its own first-run
"select ROM directory" step going unanswered in a headless Moonlight
session saves an empty path back over GOW's template), which the presence
check alone couldn't tell apart from a real one. Setting it by hand still
works too, any time: **Main Menu → Other Settings → Run in background
(while game is launched) → off**, and the ROM directory under **Main Menu
→ Other Settings → ROM directory → \`/ROMs\`** if it's ever blank again.
**Why this needed its own mount, not just a one-time write:** \`~/ES-DE\`
(settings, gamelists, scraped artwork, logs) had no bind mount onto the