#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Bake the catalog's Lua apps into the firmware as seeded built-ins. The Lua host already supports this: luaAppLaunchFile(id, title, embedded, len) tries /apps/.lua first and falls back to an embedded source when the file is not there. That file-first order is what makes a seeded app updatable — download a newer version from the Store and the file simply wins. This generates src/ui-touch/lua_builtin.h from out/firmware/apps/, i.e. exactly the sources the Store serves, so a board that cannot reach the Store still ships with the apps rather than an empty drawer. Run from the repo root: python3 scripts/build/gen-lua-builtin.py """ import json, os, re, sys ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) APPS = os.path.join(ROOT, 'out/firmware/apps') OUT = os.path.join(ROOT, 'src/ui-touch/lua_builtin.h') DELIM = 'WADALUA' # raw-string delimiter: keeps Lua source verbatim def main(): cat_path = os.path.join(APPS, 'apps.json') if not os.path.exists(cat_path): sys.exit('no catalog at ' + cat_path) cat = json.load(open(cat_path, encoding='utf-8'))['apps'] entries = [] for app in cat: aid, ver, name = app['id'], app['ver'], app['name'] src = os.path.join(APPS, aid, ver, aid + '.lua') if not os.path.exists(src): print(' skip %s: no %s' % (aid, os.path.relpath(src, ROOT))) continue code = open(src, encoding='utf-8').read() if (')' + DELIM + '"') in code: sys.exit('%s contains the raw-string delimiter' % aid) entries.append((aid, name, ver, code)) if not entries: sys.exit('no app sources found under ' + APPS) w = ['// Generated by scripts/build/gen-lua-builtin.py — DO NOT EDIT.', '// Source: out/firmware/apps/ (the same .lua the Lua Store serves).', '// Seeded built-ins: a downloaded /apps/.lua always wins.', '#pragma once', '', 'struct LuaBuiltinApp { const char* id; const char* name; const char* ver; const char* src; };', ''] for aid, name, ver, code in entries: w.append('static const char kLuaSrc_%s[] = R"%s(%s)%s";' % (aid, DELIM, code, DELIM)) w.append('') w.append('static const LuaBuiltinApp kLuaBuiltin[] = {') for aid, name, ver, _ in entries: w.append(' { "%s", "%s", "%s", kLuaSrc_%s },' % (aid, name, ver, aid)) w.append('};') w.append('static const int kLuaBuiltinCount = (int)(sizeof(kLuaBuiltin)/sizeof(kLuaBuiltin[0]));') w.append('') open(OUT, 'w', encoding='utf-8').write('\n'.join(w)) total = sum(len(c) for _, _, _, c in entries) print('%s: %d apps, %d bytes of Lua' % (os.path.relpath(OUT, ROOT), len(entries), total)) for aid, _, ver, code in entries: print(' %-10s v%-4s %6d B' % (aid, ver, len(code))) if __name__ == '__main__': main()