refactor(pack): template custom mod metadata so BASE_DOMAIN isn't frozen
The download URL is the only domain-dependent field in the external-file
metadata. Make mods/*.pw.toml build output rendered from committed
mods/*.pw.toml.tmpl (url uses ${BASE_DOMAIN}); render-config.sh and
add-custom-mod.sh render them + packwiz refresh at deploy/add time.
- pack/.packwizignore: keep *.pw.toml.tmpl out of the index
- gitignore rendered pack/mods/*.pw.toml + pack/index.toml (build output)
- seed a minimal index.toml before refresh (packwiz won't bootstrap one)
- add-custom-mod renders inline (BASE_DOMAIN only) — no coupling to
dnsmasq's HOST_LAN_IP
Domain changes now just need a re-render, not a metadata rewrite.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,8 +2,10 @@
|
||||
# add-custom-mod.sh — add LOCAL jar(s) to the packwiz pack as "external files".
|
||||
#
|
||||
# Implements the "Other external files" flow from
|
||||
# https://packwiz.infra.link/tutorials/creating/adding-mods/ : a hand-written
|
||||
# <slug>.pw.toml that points at a stable download URL + sha256, then refresh.
|
||||
# https://packwiz.infra.link/tutorials/creating/adding-mods/ : a <slug>.pw.toml
|
||||
# that points at a stable download URL + sha256, then refresh. Here the metadata
|
||||
# is written as a TEMPLATE (<slug>.pw.toml.tmpl) with a ${BASE_DOMAIN}
|
||||
# placeholder and rendered by render-config.sh, so the domain is never frozen.
|
||||
#
|
||||
# Since the jars are local (no public URL), we HOST them on the caddy pack
|
||||
# server: each jar is copied to the top-level ./custom/ dir (OUTSIDE ./pack, so
|
||||
@@ -56,6 +58,7 @@ case "$SIDE" in both|client|server) ;; *) die "invalid --side '$SIDE' (both|clie
|
||||
# ---- preflight -------------------------------------------------------------
|
||||
command -v packwiz >/dev/null 2>&1 || die "missing required tool: packwiz (https://packwiz.infra.link)"
|
||||
command -v sha256sum >/dev/null 2>&1 || die "missing required tool: sha256sum"
|
||||
command -v envsubst >/dev/null 2>&1 || die "missing required tool: envsubst (gettext)"
|
||||
[ -f .env ] || die ".env not found (copy .env.example and fill it)"
|
||||
# shellcheck disable=SC1091
|
||||
set -a; . ./.env; set +a
|
||||
@@ -88,9 +91,12 @@ add_one() { # $1 = jar path. Uses NAME (single-jar only), SIDE, FORCE, BASE_DOM
|
||||
slug="$(slugify "$name")"
|
||||
[ -n "$slug" ] || die "could not derive a slug from name '$name'"
|
||||
|
||||
meta="pack/mods/${slug}.pw.toml"
|
||||
# Metadata is a TEMPLATE: the download URL keeps a literal ${BASE_DOMAIN}
|
||||
# placeholder, rendered to the real .pw.toml by render-config.sh at deploy so
|
||||
# the domain is never frozen into a committed file.
|
||||
meta="pack/mods/${slug}.pw.toml.tmpl"
|
||||
dest="custom/${filename}"
|
||||
url="http://pack.${BASE_DOMAIN}/custom/${filename}"
|
||||
url_tmpl='http://pack.${BASE_DOMAIN}/custom/'"${filename}"
|
||||
|
||||
if [ "$FORCE" -ne 1 ]; then
|
||||
[ -e "$meta" ] && die "metadata exists: $meta (use --force to overwrite)"
|
||||
@@ -99,7 +105,7 @@ add_one() { # $1 = jar path. Uses NAME (single-jar only), SIDE, FORCE, BASE_DOM
|
||||
|
||||
hash="$(sha256sum -- "$jar" | cut -d' ' -f1)"
|
||||
# Skip the copy when the source already IS the hosted file (regen-in-place,
|
||||
# e.g. `add-custom-mod.sh custom --force` to refresh URLs after a domain change).
|
||||
# e.g. `add-custom-mod.sh custom --force` to rewrite metadata).
|
||||
[ "$dest" -ef "$jar" ] || cp -- "$jar" "$dest"
|
||||
cat > "$meta" <<EOF
|
||||
name = "${name}"
|
||||
@@ -107,19 +113,28 @@ filename = "${filename}"
|
||||
side = "${SIDE}"
|
||||
|
||||
[download]
|
||||
url = "${url}"
|
||||
url = "${url_tmpl}"
|
||||
hash-format = "sha256"
|
||||
hash = "${hash}"
|
||||
EOF
|
||||
echo " + ${filename} -> ${url} (${SIDE}, sha256 ${hash:0:12}…)"
|
||||
echo " + ${filename} -> http://pack.${BASE_DOMAIN}/custom/${filename} (${SIDE}, sha256 ${hash:0:12}…)"
|
||||
}
|
||||
|
||||
log "adding ${#JARS[@]} jar(s), side=${SIDE}"
|
||||
for j in "${JARS[@]}"; do add_one "$j"; done
|
||||
|
||||
# ---- refresh once ----------------------------------------------------------
|
||||
# packwiz refresh rebuilds index.toml (and pack.toml's index hash) so the new
|
||||
# .pw.toml files are picked up. Must run inside the pack dir.
|
||||
# ---- render + refresh once -------------------------------------------------
|
||||
# Render every metadata template -> .pw.toml (inject ${BASE_DOMAIN} only — no
|
||||
# coupling to dnsmasq's HOST_LAN_IP), then rebuild the packwiz index. This is
|
||||
# the same render render-config.sh does at deploy; kept inline so adding a mod
|
||||
# works with just BASE_DOMAIN set.
|
||||
log "rendering metadata + refreshing index"
|
||||
for t in pack/mods/*.pw.toml.tmpl; do
|
||||
envsubst '${BASE_DOMAIN}' < "$t" > "${t%.tmpl}"
|
||||
done
|
||||
# index.toml is gitignored build output; seed a minimal one so packwiz refresh
|
||||
# (which won't bootstrap a missing index) has something to populate.
|
||||
[ -f pack/index.toml ] || printf 'hash-format = "sha256"\n' > pack/index.toml
|
||||
( cd pack && packwiz refresh )
|
||||
log "packwiz refresh done — ${#JARS[@]} mod(s) added to the pack"
|
||||
echo " commit custom/*.jar, pack/mods/*.pw.toml, pack/index.toml, pack/pack.toml"
|
||||
log "done — ${#JARS[@]} mod(s) added to the pack"
|
||||
echo " commit: custom/*.jar + pack/mods/*.pw.toml.tmpl (rendered .pw.toml/index are gitignored)"
|
||||
|
||||
@@ -19,3 +19,19 @@ render() { # $1=template $2=output
|
||||
|
||||
render drasl/config/config.toml.tmpl drasl/config/config.toml
|
||||
render dnsmasq/dnsmasq.conf.tmpl dnsmasq/dnsmasq.conf
|
||||
|
||||
# packwiz external-file metadata: render every pack/mods/*.pw.toml.tmpl into its
|
||||
# .pw.toml (injects ${BASE_DOMAIN} into the download URL), then rebuild the
|
||||
# packwiz index. .packwizignore keeps the .tmpl out of the index.
|
||||
shopt -s nullglob
|
||||
tmpls=(pack/mods/*.pw.toml.tmpl)
|
||||
shopt -u nullglob
|
||||
if [ "${#tmpls[@]}" -gt 0 ]; then
|
||||
for t in "${tmpls[@]}"; do render "$t" "${t%.tmpl}"; done
|
||||
command -v packwiz >/dev/null 2>&1 || { echo "packwiz not found — cannot refresh index" >&2; exit 1; }
|
||||
# index.toml is gitignored build output; seed a minimal one so packwiz refresh
|
||||
# (which won't bootstrap a missing index) has something to populate.
|
||||
[ -f pack/index.toml ] || printf 'hash-format = "sha256"\n' > pack/index.toml
|
||||
( cd pack && packwiz refresh )
|
||||
echo "refreshed packwiz index (${#tmpls[@]} external metafiles)"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user