From 2405eee57d549755e597f20e50aff6a70dcdcb0b Mon Sep 17 00:00:00 2001 From: Oier Bravo Urtasun Date: Sun, 7 Jun 2026 18:51:56 +0200 Subject: [PATCH] feat(tooling): add-custom-mod.sh folder mode Accept a directory: process every *.jar inside and run packwiz refresh once at the end. --name rejected with a folder (names derived per-jar); halts on an empty folder. Single-jar path unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) --- tooling/add-custom-mod.sh | 109 ++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 46 deletions(-) diff --git a/tooling/add-custom-mod.sh b/tooling/add-custom-mod.sh index fedd4ca..42d0504 100755 --- a/tooling/add-custom-mod.sh +++ b/tooling/add-custom-mod.sh @@ -1,23 +1,26 @@ #!/usr/bin/env bash -# add-custom-mod.sh — add a LOCAL jar to the packwiz pack as an "external file". +# 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 # .pw.toml that points at a stable download URL + sha256, then refresh. # -# Since the jar is local (no public URL), we HOST it on the caddy pack server: -# the jar is copied under pack/custom/ — caddy serves pack/ at +# Since the jars are local (no public URL), we HOST them on the caddy pack +# server: each jar is copied under pack/custom/ — caddy serves pack/ at # http://pack.${BASE_DOMAIN}/ — so the metadata's download url is # http://pack.${BASE_DOMAIN}/custom/ # which is exactly what minecraft fetches via PACKWIZ_URL on install. # # Usage: -# tooling/add-custom-mod.sh [--name "Nice Name"] -# [--side both|client|server] [--force] +# tooling/add-custom-mod.sh [--name "Nice Name"] [--side S] [--force] +# tooling/add-custom-mod.sh [--side S] [--force] # all *.jar in dir +# # (--name not allowed) +# S = both|client|server (default both) # -# Defaults: name = jar filename without .jar, side = both. -# Cautious: halts on missing tool/var, bad side, whitespace in filename, or an -# existing metadata/custom jar (unless --force). +# Single-jar name defaults to the filename without .jar; folder mode derives +# each name from its filename. packwiz refresh runs ONCE at the end. +# Cautious: halts on missing tool/var, bad side, whitespace in a filename, an +# empty folder, or an existing metadata/custom jar (unless --force). set -euo pipefail cd "$(dirname "$0")/.." # repo root @@ -33,24 +36,24 @@ slugify() { # lowercase, non-alnum -> hyphen, squeeze + trim hyphens } # ---- args ------------------------------------------------------------------ -JAR=""; NAME=""; SIDE="both"; FORCE=0 +TARGET=""; NAME=""; SIDE="both"; FORCE=0 while [ $# -gt 0 ]; do case "$1" in --name) NAME="${2:?--name needs a value}"; shift 2 ;; --side) SIDE="${2:?--side needs a value}"; shift 2 ;; --force) FORCE=1; shift ;; - -h|--help) sed -n '2,18p' "$0"; exit 0 ;; + -h|--help) sed -n '2,24p' "$0"; exit 0 ;; -*) die "unknown flag: $1" ;; - *) [ -z "$JAR" ] || die "only one jar at a time (got extra: $1)"; JAR="$1"; shift ;; + *) [ -z "$TARGET" ] || die "only one jar or dir at a time (got extra: $1)"; TARGET="$1"; shift ;; esac done -[ -n "$JAR" ] || die "no jar given. usage: tooling/add-custom-mod.sh [--name N] [--side both|client|server]" -[ -f "$JAR" ] || die "jar not found: $JAR" +[ -n "$TARGET" ] || die "no jar/dir given. usage: tooling/add-custom-mod.sh [--side both|client|server]" +[ -e "$TARGET" ] || die "path not found: $TARGET" case "$SIDE" in both|client|server) ;; *) die "invalid --side '$SIDE' (both|client|server)" ;; esac # ---- preflight ------------------------------------------------------------- -command -v packwiz >/dev/null 2>&1 || die "missing required tool: packwiz (https://packwiz.infra.link)" +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" [ -f .env ] || die ".env not found (copy .env.example and fill it)" # shellcheck disable=SC1091 @@ -58,48 +61,62 @@ set -a; . ./.env; set +a : "${BASE_DOMAIN:?BASE_DOMAIN unset in .env}" [ -f pack/pack.toml ] || die "pack/pack.toml not found — run from a packwiz pack (see plan/04-packwiz.md)" -FILENAME="$(basename -- "$JAR")" -case "$FILENAME" in *.jar) ;; *) die "not a .jar: $FILENAME" ;; esac -case "$FILENAME" in *[[:space:]]*) die "filename has whitespace: '$FILENAME' — rename it (URL-unsafe)" ;; esac - -[ -n "$NAME" ] || NAME="${FILENAME%.jar}" -SLUG="$(slugify "$NAME")" -[ -n "$SLUG" ] || die "could not derive a slug from name '$NAME'" - -META="pack/mods/${SLUG}.pw.toml" -DEST="pack/custom/${FILENAME}" -URL="http://pack.${BASE_DOMAIN}/custom/${FILENAME}" - -if [ "$FORCE" -ne 1 ]; then - [ -e "$META" ] && die "metadata exists: $META (use --force to overwrite)" - [ -e "$DEST" ] && die "hosted jar exists: $DEST (use --force to overwrite)" +# ---- collect jars ---------------------------------------------------------- +declare -a JARS=() +if [ -d "$TARGET" ]; then + [ -z "$NAME" ] || die "--name not allowed with a folder (names are derived per-jar)" + shopt -s nullglob + for f in "$TARGET"/*.jar; do JARS+=("$f"); done + shopt -u nullglob + [ "${#JARS[@]}" -gt 0 ] || die "no .jar files in folder: $TARGET" +else + JARS=("$TARGET") fi -# ---- write ----------------------------------------------------------------- -HASH="$(sha256sum -- "$JAR" | cut -d' ' -f1)" - mkdir -p pack/custom pack/mods -cp -- "$JAR" "$DEST" -cat > "$META" < "$meta" < ${url} (${SIDE}, sha256 ${hash:0:12}…)" +} -log "wrote $META" -echo " hosted jar : $DEST -> $URL" -echo " side : $SIDE" -echo " sha256 : $HASH" +log "adding ${#JARS[@]} jar(s), side=${SIDE}" +for j in "${JARS[@]}"; do add_one "$j"; done -# ---- refresh --------------------------------------------------------------- +# ---- refresh once ---------------------------------------------------------- # packwiz refresh rebuilds index.toml (and pack.toml's index hash) so the new -# .pw.toml is picked up. Must run inside the pack dir. +# .pw.toml files are picked up. Must run inside the pack dir. ( cd pack && packwiz refresh ) -log "packwiz refresh done — '${NAME}' added to the pack" -echo " commit pack/custom/${FILENAME}, ${META}, pack/index.toml, pack/pack.toml" +log "packwiz refresh done — ${#JARS[@]} mod(s) added to the pack" +echo " commit pack/custom/*.jar, pack/mods/*.pw.toml, pack/index.toml, pack/pack.toml"