#!/bin/bash # Official Shotbar installer. Review before piping: # curl -fsSL https://shotbar.app/install.sh # Then: # curl -fsSL https://shotbar.app/install.sh | bash set -euo pipefail if [[ "$(uname -s)" != "Darwin" ]]; then echo "Shotbar is a macOS app." >&2 exit 1 fi ZIP_URL="${SHOTBAR_ZIP_URL:-https://shotbar.app/dl/zip}" DEST="/Applications/Shotbar.app" TMP="$(mktemp -d "${TMPDIR:-/tmp}/shotbar-install.XXXXXX")" trap 'rm -rf "${TMP}"' EXIT echo "Downloading Shotbar..." curl -fL --proto "=https" --tlsv1.2 --retry 3 --retry-delay 1 \ -o "${TMP}/Shotbar.zip" "${ZIP_URL}" # Shotbar is not notarized, so this script is being trusted with more than usual. The published # feed carries the SHA-256 of the archive; checking it here means a download that was tampered # with, truncated, or served by something other than shotbar.app is refused rather than installed. # An older feed without the field still installs — this is a check, not a new requirement. EXPECTED="$(curl -fsSL --proto "=https" --tlsv1.2 "https://shotbar.app/version-data.json" 2>/dev/null \ | /usr/bin/sed -n 's/.*"sha256"[[:space:]]*:[[:space:]]*"\([a-f0-9]*\)".*/\1/p' | head -n 1)" if [[ -n "${EXPECTED}" ]]; then ACTUAL="$(/usr/bin/shasum -a 256 "${TMP}/Shotbar.zip" | awk '{print $1}')" if [[ "${ACTUAL}" != "${EXPECTED}" ]]; then echo "Checksum mismatch — refusing to install." >&2 echo " expected ${EXPECTED}" >&2 echo " got ${ACTUAL}" >&2 exit 1 fi echo "Checksum verified." else echo "Note: no checksum published for this build; skipping verification." fi ditto -x -k "${TMP}/Shotbar.zip" "${TMP}/unpacked" APP="${TMP}/unpacked/Shotbar.app" if [[ ! -d "${APP}" ]]; then APP="$(find "${TMP}/unpacked" -name "Shotbar.app" -type d -print | sed -n '1p')" fi if [[ -z "${APP}" || ! -d "${APP}" ]]; then echo "The download did not contain Shotbar.app." >&2 exit 1 fi if pgrep -qx Shotbar; then echo "Quitting Shotbar so it can be replaced..." osascript -e 'tell application "Shotbar" to quit' >/dev/null 2>&1 || killall Shotbar 2>/dev/null || true sleep 1 fi echo "Installing to ${DEST}..." if [[ -w /Applications ]]; then rm -rf "${DEST}" ditto "${APP}" "${DEST}" else echo "Need permission to write /Applications." sudo rm -rf "${DEST}" sudo ditto "${APP}" "${DEST}" fi xattr -cr "${DEST}" 2>/dev/null || true open "${DEST}" echo "Shotbar is in Applications and launching."