bundle-puzzles.sh (2093B)
1 #!/bin/bash 2 set -euo pipefail 3 4 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 REPO_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" 6 7 if (($# < 2)) || [[ -z "$1" || -z "$2" ]]; then 8 echo "Usage: $0 <bundle-id> <title-prefix> [output-dir]" >&2 9 exit 1 10 fi 11 12 BUNDLE_ID="$1" 13 TITLE_PREFIX="$2" 14 # The directory is named by bundle id; the title prefix is the display name, 15 # carried into the manifest (and into each puzzle's Title) below. 16 DEST_DIR="${3:-./Puzzles}/${BUNDLE_ID}" 17 18 SOURCE_DIR="${REPO_DIR}/Crossmake/Picked" 19 20 if [[ ! -d "$SOURCE_DIR" ]]; then 21 echo "Source directory not found: $SOURCE_DIR" >&2 22 exit 1 23 fi 24 25 source_files=("$SOURCE_DIR"/*.xd) 26 if [[ ! -e "${source_files[0]}" ]]; then 27 echo "No .xd puzzles found in $SOURCE_DIR" >&2 28 exit 1 29 fi 30 31 mkdir -p "$DEST_DIR" 32 33 next=1 34 first="$next" 35 36 for src in "${source_files[@]}"; do 37 printf -v dest_name "%s-%04d.xd" "$BUNDLE_ID" "$next" 38 dest="${DEST_DIR}/${dest_name}" 39 # Rewrite the XD frontmatter block (everything before the first blank line), 40 # leaving the grid and clue text untouched. 41 awk -v title="Title: ${TITLE_PREFIX} #${next}" -v bundle="Bundle: ${BUNDLE_ID}" ' 42 BEGIN { frontmatter = 1 } 43 frontmatter && /^[[:space:]]*$/ { frontmatter = 0 } 44 frontmatter && /^Title:/ { print title; next } 45 frontmatter && /^Bundle:/ { print bundle; next } 46 frontmatter && /^Author:/ { next } 47 frontmatter && /^Copyright:/ { next } 48 frontmatter && /^Publisher:/ { print "Publisher: Michael Camilleri"; next } 49 { print } 50 ' "$src" >"$dest" 51 echo "Bundled ${src##*/} -> ${dest_name} (Title: ${TITLE_PREFIX} #${next})" 52 next=$((next + 1)) 53 done 54 55 echo "Bundled $((next - first)) puzzle(s) into ${DEST_DIR}; numbers ${first}-$((next - 1))." >&2 56 57 # Write manifest.json — the puzzle index the app reads to draw grid 58 # thumbnails without parsing every .xd file. Built by the Bundlemake tool in 59 # the Crossmake package so it always reflects the bundle's final contents. 60 echo "Generating manifest for ${DEST_DIR}..." >&2 61 swift run --package-path "${REPO_DIR}/Crossmake" Bundlemake --name "${TITLE_PREFIX}" "${DEST_DIR}"