#!/bin/sh # shellcheck shell=dash set -eu # Pinner CLI installer # Usage: curl -fsSL https://get.pinner.xyz | sh # curl -fsSL https://get.pinner.xyz | sh -s -- --system # curl -fsSL https://get.pinner.xyz | sh -s -- --bin-dir /usr/local/bin PROGRAM_NAME="pinner" ARCHIVE_NAME="pinner-cli" REPO="LumeWeb/pinner-cli" BASE_URL="https://github.com/${REPO}/releases/download" VERSION_URL="https://get.pinner.xyz/version" # --- Shell compatibility guard ----------------------------------------------- if [ -n "${ZSH_VERSION+x}" ]; then echo "Error: Running with zsh is not supported. Please use sh." >&2 exit 1 elif [ -n "${BASH_VERSION+x}" ] && [ -z "${POSIXLY_CORRECT+x}" ]; then echo "Warning: Running with non-POSIX bash may cause issues. Please use sh." >&2 fi # --- Globals ----------------------------------------------------------------- INSTALL_DIR="" OPT_SYSTEM=0 OPT_ARCH="" OPT_BASE_URL="" OPT_UNINSTALL=0 OPT_DEBUG=0 OPT_NO_PKG=0 OPT_VERSION="" DETECTED_SHELL="" RC_FILE="" # GitHub Actions API for snapshot artifacts (commit hash / branch downloads) ACTIONS_API="https://api.github.com/repos/${REPO}/actions" ARTIFACT_NAME="pinner-cli-snapshot" WORKFLOW_FILE="go.yml" # Directory of this script (for CI local version file fallback) SCRIPT_DIR="$(cd "$(dirname "$0")" 2> /dev/null && pwd || echo .)" BREW_PACKAGE="lumeweb/tap/pinner" # CI mode env vars (read once at startup, like PINNER_VERSION/PINNER_INSTALL) PINNER_BREW_TAP="${PINNER_BREW_TAP:-}" PINNER_BREW_FORMULA="${PINNER_BREW_FORMULA:-$BREW_PACKAGE}" # --- Helper functions -------------------------------------------------------- info() { printf '\033[1;34m[info]\033[0m %s\n' "$1" >&2 } warn() { printf '\033[1;33m[warn]\033[0m %s\n' "$1" >&2 } error() { printf '\033[1;31m[error]\033[0m %s\n' "$1" >&2 } completed() { printf '\033[1;32m[ok]\033[0m %s\n' "$1" >&2 } need_cmd() { if ! check_cmd "$1"; then error "Required command '$1' not found. Please install it and try again." exit 1 fi } check_cmd() { command -v "$1" > /dev/null 2>&1 } ensure() { if ! "$@"; then error "Command failed: $*" exit 1 fi } ignore() { "$@" 2> /dev/null || true } # --- Download progress ------------------------------------------------------- # Downloads and extractions are wrapped in run_with_spinner (below) so the only # progress rendering is our own deterministic `\r`-animation on stderr. curl and # wget are always run silent so they never spew their own terminal-control # progress frames, which render as scrambled garbage (`##0=-##`) on some # terminals mid-transfer. # Run a command, animating an indeterminate progress spinner on stderr only when # stderr is attached to a terminal. In non-interactive contexts (CI, redirects, # pipes) the command runs directly with no spinner, keeping output deterministic # and log-clean. The wrapped command's stdout/stderr are captured to a temp file # so a failure still surfaces the underlying tool's error text. # Usage: run_with_spinner