mirror of
https://github.com/ALLFATHER-BV/wadamesh.git
synced 2026-08-14 11:39:56 +00:00
Community submission, reviewed before publishing rather than taken on trust. The whole API surface it touches is ui.label / ui.canvas / ui.colors, sys.random, timer.every(100) and two store keys for the high score. No network, no mesh transmit, no filesystem, no dynamic code loading (load/loadstring/require/dofile), no _G, metatable, debug or coroutine tricks, and no long-string or numeric-escape obfuscation. Persistence is one bounded value. Nothing in it can reach past its own window, so it needs no permission grant. It also uses the real lifecycle contract — an app table with on_open/on_tick/ on_input/on_close, returned from the chunk — which is worth noting because the published SDK page told people to do it a different way until today. He got it right by reading the shipped apps. Parse-checked against the firmware's own vendored Lua 5.4.7 rather than a system interpreter, so the syntax is verified by the same parser the device runs. Not run on hardware here; pisti87 reports it working on a T-Deck Plus. deploy-apps.sh now also verifies that every apps.json entry has its <id>/<ver>/<id>.lua and .json on disk. An entry pointing at a missing file lists in the Store and then fails to install with nothing on screen to explain why — the same failure the language check already prevents. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
74 lines
3.3 KiB
Bash
Executable File
74 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# wadamesh app+language store deploy: publish deploy/apps/ to the firmware VPS.
|
|
#
|
|
# The device reads BOTH catalogs from the firmware host, NOT the site host:
|
|
# http://firmware.wadamesh.com/apps/apps.json <- Store > Apps
|
|
# http://firmware.wadamesh.com/apps/langs.json <- Store > Languages
|
|
# http://firmware.wadamesh.com/apps/lang/<ver>/<code>.lang
|
|
# so this tree lives under the FIRMWARE web root, alongside releases/ and latest*/.
|
|
#
|
|
# WHY THIS SCRIPT EXISTS: there wasn't one. release.sh rsyncs out/firmware/ (which
|
|
# does not contain apps/) and deploy-site.sh rsyncs deploy/site/ — so the store was
|
|
# only ever updated by someone remembering to rsync it by hand, and twice they did
|
|
# not. Translations sat at v8 on the server while the repo had v9/v10/v11, and a
|
|
# published app never appeared at all. Editing deploy/apps/ is not publishing it;
|
|
# running this is.
|
|
#
|
|
# Usage:
|
|
# WADAMESH_VPS=user@your-vps scripts/deploy-apps.sh # deploy
|
|
# WADAMESH_VPS=user@your-vps scripts/deploy-apps.sh --dry-run # preview only
|
|
#
|
|
# Optional:
|
|
# WADAMESH_FW_PATH=/srv/wadamesh/firmware # override the firmware web root
|
|
#
|
|
# The VPS target comes from the environment — never commit it.
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
SRC="$ROOT/deploy/apps/"
|
|
DEST="${WADAMESH_VPS:?set WADAMESH_VPS=user@host}"
|
|
DEST_PATH="${WADAMESH_FW_PATH:-/srv/wadamesh/firmware}/apps"
|
|
|
|
DRY=""
|
|
[ "${1:-}" = "--dry-run" ] && DRY="--dry-run"
|
|
|
|
# Sanity-check the catalogs before shipping them: a device that gets malformed JSON
|
|
# shows an empty store with no clue why, and the versioned .lang dir each catalog
|
|
# entry points at has to actually exist or the download 404s on the device.
|
|
python3 - "$ROOT" <<'PY'
|
|
import json, os, sys
|
|
root = sys.argv[1]
|
|
apps_dir = os.path.join(root, "deploy", "apps")
|
|
langs = json.load(open(os.path.join(apps_dir, "langs.json")))["langs"]
|
|
missing = [f"{l['code']} v{l['ver']}" for l in langs
|
|
if not os.path.isfile(os.path.join(apps_dir, "lang", str(l["ver"]), l["code"] + ".lang"))]
|
|
if missing:
|
|
sys.exit("ABORT: langs.json points at files that do not exist: " + ", ".join(missing))
|
|
|
|
# Same check for apps: an entry whose <id>/<ver>/<id>.lua is absent shows up in the
|
|
# Store and then fails to install, with nothing on screen to say why.
|
|
apps = json.load(open(os.path.join(apps_dir, "apps.json")))["apps"]
|
|
bad = []
|
|
for a in apps:
|
|
base = os.path.join(apps_dir, a["id"], a["ver"])
|
|
for f in (a["id"] + ".lua", a["id"] + ".json"):
|
|
if not os.path.isfile(os.path.join(base, f)):
|
|
bad.append(f'{a["id"]} v{a["ver"]}: {f}')
|
|
if bad:
|
|
sys.exit("ABORT: apps.json points at files that do not exist: " + ", ".join(bad))
|
|
print(f"catalogs ok: {len(langs)} languages and {len(apps)} apps, every referenced file present")
|
|
PY
|
|
|
|
# --delete mirrors the repo: the store is generated content, the repo is the source
|
|
# of truth, and stale versioned dirs left on the server are how a device ends up
|
|
# offered a language file nothing points at any more.
|
|
rsync -avz $DRY --delete "$SRC" "$DEST:$DEST_PATH/"
|
|
|
|
if [ -z "$DRY" ]; then
|
|
echo
|
|
echo "deployed deploy/apps/ -> $DEST:$DEST_PATH"
|
|
echo "verify:"
|
|
echo " curl -s http://firmware.wadamesh.com/apps/langs.json"
|
|
echo " curl -s http://firmware.wadamesh.com/apps/apps.json"
|
|
fi
|