crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

nyt-to-xd.sh (2825B)


      1 #!/usr/bin/env bash
      2 #
      3 # Convert a NYT puzzle JSON to XD using the app's NYTToXDConverter.
      4 #
      5 # Usage:
      6 #   Scripts/nyt-to-xd.sh --json <path>            # convert an existing file
      7 #   Scripts/nyt-to-xd.sh --date YYYY-MM-DD        # fetch then convert
      8 #   [--output <path>]                              # default: stdout
      9 
     10 set -euo pipefail
     11 
     12 repo_root="$(cd "$(dirname "$0")/.." && pwd)"
     13 converter="${repo_root}/Crossmate/Services/NYTToXDConverter.swift"
     14 xd_source="${repo_root}/Crossmate/Models/XD.swift"
     15 fetch_script="${repo_root}/Scripts/fetch-nyt.sh"
     16 
     17 # The converter pulls XD.currentCmVersion from the app target. Mirror just
     18 # that constant from XD.swift so we don't need to compile the full app.
     19 # Reading from source keeps the stub in lockstep with the real value.
     20 cm_version="$(sed -n 's/^[[:space:]]*static let currentCmVersion = \([0-9][0-9]*\).*/\1/p' "$xd_source" | head -n1)"
     21 if [[ -z "$cm_version" ]]; then
     22     echo "error: could not read currentCmVersion from $xd_source" >&2
     23     exit 1
     24 fi
     25 
     26 json_path=""
     27 date_arg=""
     28 output_path=""
     29 
     30 while [[ $# -gt 0 ]]; do
     31     case "$1" in
     32         --json)  json_path="$2"; shift 2 ;;
     33         --date)  date_arg="$2"; shift 2 ;;
     34         --output) output_path="$2"; shift 2 ;;
     35         -h|--help)
     36             sed -n '2,8p' "$0" | sed 's/^# \{0,1\}//'
     37             exit 0
     38             ;;
     39         *) echo "error: unknown arg '$1'" >&2; exit 2 ;;
     40     esac
     41 done
     42 
     43 if [[ -z "$json_path" && -z "$date_arg" ]]; then
     44     echo "error: pass --json <path> or --date YYYY-MM-DD" >&2
     45     exit 2
     46 fi
     47 if [[ -n "$json_path" && -n "$date_arg" ]]; then
     48     echo "error: --json and --date are mutually exclusive" >&2
     49     exit 2
     50 fi
     51 
     52 tmp_dir="$(mktemp -d)"
     53 trap 'rm -rf "$tmp_dir"' EXIT
     54 
     55 if [[ -n "$date_arg" ]]; then
     56     json_path="${tmp_dir}/nyt-${date_arg}.json"
     57     bash "$fetch_script" "$date_arg" "$json_path" >/dev/null
     58 fi
     59 
     60 if [[ ! -f "$json_path" ]]; then
     61     echo "error: JSON file not found: $json_path" >&2
     62     exit 1
     63 fi
     64 
     65 driver="${tmp_dir}/main.swift"
     66 cat > "$driver" <<SWIFT
     67 import Foundation
     68 
     69 // Stub for the one symbol the converter pulls from the app target. The value
     70 // is read out of Crossmate/Models/XD.swift at script-start time so this stays
     71 // in sync with the canonical definition.
     72 enum XD {
     73     static let currentCmVersion = ${cm_version}
     74 }
     75 
     76 guard CommandLine.arguments.count >= 2 else {
     77     FileHandle.standardError.write(Data("error: missing JSON path\n".utf8))
     78     exit(2)
     79 }
     80 let url = URL(fileURLWithPath: CommandLine.arguments[1])
     81 let data = try Data(contentsOf: url)
     82 let xd = try NYTToXDConverter.convert(jsonData: data)
     83 print(xd)
     84 SWIFT
     85 
     86 binary="${tmp_dir}/nyt-to-xd"
     87 swiftc -O -swift-version 6 "$converter" "$driver" -o "$binary"
     88 
     89 if [[ -n "$output_path" ]]; then
     90     "$binary" "$json_path" > "$output_path"
     91     echo "wrote $output_path" >&2
     92 else
     93     "$binary" "$json_path"
     94 fi