From a6a43a17ac322cbc3c5fada975cccbf5dcbeaf26 Mon Sep 17 00:00:00 2001 From: Oier Bravo Urtasun Date: Sun, 24 May 2026 04:44:27 +0200 Subject: [PATCH] feat(tooling): add fetch-launcher.sh (all platforms + stable symlinks) Co-Authored-By: Claude Opus 4.7 (1M context) --- tooling/fetch-launcher.sh | 91 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100755 tooling/fetch-launcher.sh diff --git a/tooling/fetch-launcher.sh b/tooling/fetch-launcher.sh new file mode 100755 index 0000000..76460f6 --- /dev/null +++ b/tooling/fetch-launcher.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +# fetch-launcher.sh — download all FjordLauncherUnlocked release assets for +# offline LAN hosting, then create stable-name symlinks for the landing page. +# +# Guests use FjordLauncherUnlocked (Prism/PolyMC fork with authlib-injector +# built in). We mirror every release asset under mirror/launcher// and +# maintain a `latest` symlink → . Caddy serves this at /launcher/latest/… +# +# The landing page (landing/src/data/site.ts) links to FIXED filenames so the +# links survive launcher version bumps. After download this script resolves and +# symlinks those stable names to the real versioned assets: +# fjord-windows-setup.exe → Windows Setup .exe (x64) +# fjord-macos.dmg → macOS .dmg +# fjord-linux-x86_64.AppImage → Linux x86_64 .AppImage +# +# Cautious by design: halts on any error, and if a stable-name category matches +# 0 or >1 candidate it prints the candidates and exits non-zero rather than +# guessing. Idempotent — re-runs overwrite symlinks and re-download safely. +# mirror/ is gitignored — only this script is tracked. +set -euo pipefail + +REPO="hero-persson/FjordLauncherUnlocked" +DEST_ROOT="$(dirname "$0")/../mirror/launcher" +API="https://api.github.com/repos/${REPO}/releases/latest" + +command -v curl >/dev/null || { echo "curl required" >&2; exit 1; } +command -v jq >/dev/null || { echo "jq required" >&2; exit 1; } + +meta="$(curl -fsSL "$API")" +tag="$(jq -r '.tag_name' <<<"$meta")" +[ -n "$tag" ] && [ "$tag" != "null" ] || { echo "no tag_name resolved" >&2; exit 1; } + +dest="${DEST_ROOT}/${tag}" +mkdir -p "$dest" +echo "Fetching FjordLauncher ${tag} → ${dest}" + +mapfile -t urls < <(jq -r '.assets[].browser_download_url' <<<"$meta") +[ "${#urls[@]}" -gt 0 ] || { echo "no assets found" >&2; exit 1; } + +for url in "${urls[@]}"; do + fname="$(basename "$url")" + echo " ↓ ${fname}" + curl -fSL --retry 3 -o "${dest}/${fname}" "$url" +done + +# stable symlink for the landing page to reference +ln -sfn "$tag" "${DEST_ROOT}/latest" + +# --- stable-name symlinks -------------------------------------------------- +# Resolve exactly one asset filename per category from the downloaded set. +# Halt (print candidates, exit 1) on 0 or >1 matches — never guess. +# +# $1 = human label, $2 = stable link name, then patterns: +# $3 = include regex (must match), $4 = exclude regex ("" = none) +# Matching is case-insensitive against the basenames in $dest. +link_stable() { + local label="$1" link="$2" include="$3" exclude="${4:-}" + local -a names candidates=() + mapfile -t names < <(cd "$dest" && ls -1) + local n + for n in "${names[@]}"; do + shopt -s nocasematch + if [[ "$n" =~ $include ]] && { [ -z "$exclude" ] || ! [[ "$n" =~ $exclude ]]; }; then + candidates+=("$n") + fi + shopt -u nocasematch + done + + if [ "${#candidates[@]}" -ne 1 ]; then + echo "error: ${label}: expected exactly 1 candidate, found ${#candidates[@]}" >&2 + printf ' candidate: %s\n' "${candidates[@]}" >&2 + echo " (include=/${include}/ exclude=/${exclude}/) — refusing to guess" >&2 + exit 1 + fi + + ln -sfn "${candidates[0]}" "${dest}/${link}" + echo " ${link} → ${candidates[0]}" +} + +echo "Resolving stable-name symlinks:" +# Windows Setup .exe, x64 only (exclude arm64/aarch64). +link_stable "Windows Setup .exe (x64)" "fjord-windows-setup.exe" \ + 'setup.*\.exe$' '(arm64|aarch64)' +# macOS .dmg. +link_stable "macOS .dmg" "fjord-macos.dmg" \ + '\.dmg$' '' +# Linux x86_64 .AppImage (exclude .zsync sidecar and aarch64 build). +link_stable "Linux x86_64 .AppImage" "fjord-linux-x86_64.AppImage" \ + 'x86_64.*\.appimage$' '(\.zsync$|aarch64)' + +echo "Done. ${#urls[@]} assets in ${dest}; stable symlinks in ${dest} (via latest/)."