#!/bin/sh set -e REPO="xs-lang0/xs" INSTALL_DIR="${XS_INSTALL_DIR:-/usr/local/bin}" TMP_DIR="$(mktemp -d)" cleanup() { rm -rf "$TMP_DIR" 2>/dev/null; } trap cleanup EXIT err() { echo "error: $1" >&2; exit 1; } need() { command -v "$1" >/dev/null 2>&1 || err "need '$1' (not found)"; } main() { need curl need uname os=$(uname -s | tr '[:upper:]' '[:lower:]') arch=$(uname -m) case "$os" in linux) os="linux" ;; darwin) os="macos" ;; *) err "unsupported OS: $os" ;; esac case "$arch" in x86_64|amd64) arch="x86_64" ;; aarch64|arm64) echo "note: no native arm64 build yet; falling back to x86_64 (rosetta on apple silicon)" >&2 arch="x86_64" ;; *) err "unsupported arch: $arch" ;; esac asset="xs-${os}-${arch}" url="https://github.com/${REPO}/releases/latest/download/${asset}" echo "installing xs..." echo " os: $os" echo " arch: $arch" echo "" echo " downloading binary..." curl -fsSL "$url" -o "$TMP_DIR/xs" || err "download failed: $url" echo " verifying..." curl -fsSL "$url.sha256" -o "$TMP_DIR/xs.sha256" || err "checksum download failed" expected=$(awk '{print $1}' "$TMP_DIR/xs.sha256") if command -v sha256sum >/dev/null 2>&1; then actual=$(cd "$TMP_DIR" && sha256sum xs | awk '{print $1}') else actual=$(cd "$TMP_DIR" && shasum -a 256 xs | awk '{print $1}') fi [ "$expected" = "$actual" ] || err "checksum mismatch (got $actual, expected $expected)" chmod +x "$TMP_DIR/xs" echo " installing to $INSTALL_DIR..." if [ -w "$INSTALL_DIR" ]; then mv "$TMP_DIR/xs" "$INSTALL_DIR/xs" else sudo mv "$TMP_DIR/xs" "$INSTALL_DIR/xs" fi echo "" echo "installed." echo "run: xs --version" echo "upgrade later: xs upgrade" } main