From 997bcd0bd55f543a54fb0dc6431e1c259ed071d2 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 9 Jul 2026 07:16:02 +0100 Subject: [PATCH] fix(shim): harden rattle discovery + pin canonical compiler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the bare-`affinescript` call with discovery order ($AFFINESCRIPT → PATH → sibling checkout) and an actionable not-found message. Add .affinescript-pin recording the canonical commit this brand surface is validated against. Binding is normative in FACE-CONTRACT.adoc (hyperpolymath/affinescript). Co-Authored-By: Claude Opus 4.8 --- .affinescript-pin | 6 +++++ bin/rattle | 62 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 .affinescript-pin diff --git a/.affinescript-pin b/.affinescript-pin new file mode 100644 index 0000000..fad4070 --- /dev/null +++ b/.affinescript-pin @@ -0,0 +1,6 @@ +# AffineScript canonical pin — the compiler commit this face is validated against. +# Version-lock per docs/specs/FACE-CONTRACT.adoc (hyperpolymath/affinescript). +# Update deliberately (after re-running the face conformance gate), not casually. +repo = https://github.com/hyperpolymath/affinescript.git +commit = 4b36de2fad7bc18408aec9b71c6c3acf1afe8d09 +face = rattle diff --git a/bin/rattle b/bin/rattle index d8675a2..c08dccf 100755 --- a/bin/rattle +++ b/bin/rattle @@ -2,14 +2,60 @@ # SPDX-License-Identifier: MPL-2.0 # SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell (hyperpolymath) # -# rattle — RattleScript shim. Forwards arguments to the affinescript CLI -# with --face rattle injected right after the subcommand. Source files -# should still use the canonical .affine extension and a face: rattlescript -# pragma; this shim only saves typing the --face flag for routine use. +# rattle — RattleScript shim (brand surface only; carries no compiler). +# +# Locates the canonical `affinescript` compiler and injects `--face rattle`. +# Source files use the canonical `.affine` extension plus a `face: rattlescript` +# pragma; this shim only saves typing the flag. Discovery order and the binding +# contract are normative in docs/specs/FACE-CONTRACT.adoc (hyperpolymath/affinescript). +set -euo pipefail +FACE="rattle" +BRAND="RattleScript" + +# Resolve this script's own directory (follow symlinks) for sibling discovery. +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ]; do + DIR="$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd)" + SOURCE="$(readlink "$SOURCE")" + [ "${SOURCE#/}" = "$SOURCE" ] && SOURCE="$DIR/$SOURCE" +done +SCRIPT_DIR="$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd)" + +find_affinescript() { + # 1. explicit override + if [ -n "${AFFINESCRIPT:-}" ] && [ -x "${AFFINESCRIPT:-}" ]; then + printf '%s' "$AFFINESCRIPT"; return 0 + fi + # 2. on PATH (e.g. `opam install affinescript`) + if command -v affinescript >/dev/null 2>&1; then + printf '%s' affinescript; return 0 + fi + # 3. a sibling canonical checkout, built (`dune build`) + local c + for c in \ + "$SCRIPT_DIR/../../γ-affinescript/affinescript/_build/default/bin/main.exe" \ + "$SCRIPT_DIR/../../../γ-affinescript/affinescript/_build/default/bin/main.exe" \ + "$SCRIPT_DIR/../affinescript/_build/default/bin/main.exe" \ + "$HOME/developer/repos/γ-affinescript/affinescript/_build/default/bin/main.exe"; do + if [ -x "$c" ]; then printf '%s' "$c"; return 0; fi + done + return 1 +} + +if ! AS="$(find_affinescript)"; then + cat >&2 <