Add purge and an uninstaller, and move to the stores org

`purge` is what `remove` does for one game, for all of them at once, plus the
directories the store made: the shell script that wraps it has no way of knowing
which ROMs, box art, Ports payloads and gamelist entries were ours, and
state.json does. uninstall.sh runs it first and only then removes the Ports
entry, the launcher and the store home; if the engine cannot finish, nothing
else is touched.

The gamelists are merged rather than deleted — they belong to the box, and the
user's own games, play counts and favourites stay in them. Two things the tests
caught:

- The backup was being made on the *uninstall's* first touch of a gamelist we
  had created ourselves, so a purge produced a backup of our own file. It is now
  skipped when purging: by then any copy worth having was made on the first sync.
- With that fixed, "no backup next to it" means we created the file, so a
  gamelist that is left empty is deleted too. The box ends up as it was.
- The Ports entry cannot be derived from the config: a store repository sets
  BATOCERA_PORT_NAME to whatever it likes (ours is "Teletype Games Store" while
  store.name is "Teletype Games"), so the uninstaller looked for a file that was
  never there. It now finds the entry by looking inside the Ports scripts for
  this store's home — which also works for boxes installed before this existed,
  and picks up entries left over from an earlier name.

install.sh and uninstall.sh are POSIX sh now, checked with dash, so `curl … | sh`
works where /bin/sh is not bash. The repository moved from the tools org to
stores; the old raw URLs still redirect, but every reference is updated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-18 08:32:12 +02:00
co-authored by Claude Opus 5
parent 0f1045b59e
commit e2551d5fd3
4 changed files with 285 additions and 16 deletions
+4 -4
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh
# Install a WarpEngine store on a Batocera box.
#
# This installer belongs to the engine, so it takes the store as a parameter:
@@ -8,13 +8,13 @@
#
# STORE_CONFIG=./config.json ./install.sh
# STORE_CONFIG=https://git.example.org/tools/my-store/raw/branch/master/config.json \
# bash <(curl -fsSL https://git.teletypegames.org/tools/warp-engine-batocera-store/raw/branch/master/install.sh)
# curl -fsSL https://git.teletypegames.org/stores/warp-engine-batocera-store/raw/branch/master/install.sh | sh
#
set -euo pipefail
set -eu
STORE_ROOT="${BATOCERA_STORE_ROOT:-/userdata/system/batocera-store}"
PORTS_DIR="${BATOCERA_PORTS_DIR:-/userdata/roms/ports}"
ENGINE_RAW_BASE="${ENGINE_RAW_BASE:-https://git.teletypegames.org/tools/warp-engine-batocera-store/raw/branch/master}"
ENGINE_RAW_BASE="${ENGINE_RAW_BASE:-https://git.teletypegames.org/stores/warp-engine-batocera-store/raw/branch/master}"
# The shared core lives in its own repository, because both store engines use it.
WARPSTORE_RAW_BASE="${WARPSTORE_RAW_BASE:-https://git.teletypegames.org/engines/warpstore/raw/branch/master}"
STORE_CONFIG="${STORE_CONFIG:-}"