crossmate

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

commit 544ca1e8bda386448aeb42aeecc2a20c1f80393c
parent 4dd693c5392f7c8f48b5ef10a67fc678931338cb
Author: Michael Camilleri <[email protected]>
Date:   Tue, 19 May 2026 07:11:57 +0900

Update select_puzzles.sh to copy a ranked puzzle batch

A new Scripts/select_puzzles.sh wraps the Pickmake tool: it builds Pickmake in
release, has it score and filter the candidate .xd files under the given inputs
(default Crossmake/Generated), and copies the chosen puzzles into an output
directory rather than only printing their paths. The output directory defaults
to Crossmake/Picked and is overridable with -o/--into; relative paths resolve
against the caller's directory and absolute paths are used as-is, matching how
candidate inputs are already resolved.

Pickmake's --verbose diagnostics still stream to stderr so the selected and
rejected summary stays visible; only the clean path list on stdout is captured
for the copy, so build noise can't contaminate it. --clean wipes existing .xd
files from the target first — scoped to *.xd, never the whole directory — and
runs only after a non-empty selection succeeds, so a failed run can't destroy
an existing curated set. The first positional argument is still the puzzle
count; remaining non-flag arguments are candidate dirs or .xd files.

Co-Authored-By: Claude Opus 4.7 <[email protected]>

Diffstat:
MCrossmake/.gitignore | 1+
MCrossmake/Scripts/select_puzzles.sh | 71++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
2 files changed, 59 insertions(+), 13 deletions(-)

diff --git a/Crossmake/.gitignore b/Crossmake/.gitignore @@ -3,3 +3,4 @@ DerivedData/ Data/ Generated/ +Picked/ diff --git a/Crossmake/Scripts/select_puzzles.sh b/Crossmake/Scripts/select_puzzles.sh @@ -2,29 +2,52 @@ set -euo pipefail COUNT="${1:-10}" -CANDIDATE_DIR="${2:-Generated}" +DEFAULT_CANDIDATE_DIR="Generated" PICKMAKE_EXECUTABLE=".build/release/Pickmake" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CROSSMAKE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" CALLER_DIR="$(pwd)" +OUTPUT_DIR="${CROSSMAKE_DIR}/Picked" +CLEAN=false if ! [[ "$COUNT" =~ ^[0-9]+$ ]] || ((10#$COUNT < 1)); then - echo "Usage: $0 [positive-puzzle-count] [candidate-dir-or-xd-file ...]" >&2 + echo "Usage: $0 [positive-puzzle-count] [-o output-dir] [--clean] [candidate-dir-or-xd-file ...]" >&2 exit 1 fi +resolve_path() { + if [[ "$1" = /* ]]; then + echo "$1" + else + echo "${CALLER_DIR}/$1" + fi +} + shift || true inputs=() -if (($# == 0)); then - inputs+=("${CROSSMAKE_DIR}/${CANDIDATE_DIR}") -else - for input in "$@"; do - if [[ "$input" = /* ]]; then - inputs+=("$input") - else - inputs+=("${CALLER_DIR}/${input}") - fi - done +while (($# > 0)); do + case "$1" in + -o|--into) + if (($# < 2)); then + echo "$1 requires a directory argument" >&2 + exit 1 + fi + OUTPUT_DIR="$(resolve_path "$2")" + shift 2 + ;; + --clean) + CLEAN=true + shift + ;; + *) + inputs+=("$(resolve_path "$1")") + shift + ;; + esac +done + +if ((${#inputs[@]} == 0)); then + inputs+=("${CROSSMAKE_DIR}/${DEFAULT_CANDIDATE_DIR}") fi cd "$CROSSMAKE_DIR" @@ -37,4 +60,26 @@ if [[ ! -x "$PICKMAKE_EXECUTABLE" ]]; then exit 1 fi -"$PICKMAKE_EXECUTABLE" --count "$COUNT" --verbose "${inputs[@]}" +selected_paths="$("$PICKMAKE_EXECUTABLE" --count "$COUNT" --verbose "${inputs[@]}")" + +if [[ -z "$selected_paths" ]]; then + echo "No puzzles selected; nothing copied." >&2 + exit 1 +fi + +mkdir -p "$OUTPUT_DIR" + +if [[ "$CLEAN" == true ]]; then + rm -f "$OUTPUT_DIR"/*.xd + echo "Cleaned existing .xd files from ${OUTPUT_DIR}." >&2 +fi + +copied_count=0 +while IFS= read -r selected_path; do + [[ -n "$selected_path" ]] || continue + cp "$selected_path" "$OUTPUT_DIR/" + echo "Copied ${selected_path} -> ${OUTPUT_DIR}/" + copied_count=$((copied_count + 1)) +done <<<"$selected_paths" + +echo "Copied ${copied_count} puzzle(s) into ${OUTPUT_DIR}." >&2