#!/bin/sh # Guppi installer — https://github.com/ekristen/guppi # Usage: curl -sSL https://get.guppi.sh | sh # # Environment variables: # VERSION — version to install (default: latest) # INSTALL_DIR — where to put the binary (default: /usr/local/bin or ~/.local/bin) set -eu REPO="ekristen/guppi" BINARY="guppi" VERSION="${VERSION:-latest}" INSTALL_DIR="${INSTALL_DIR:-}" # --- helpers ---------------------------------------------------------------- log() { printf '%s\n' "$@"; } err() { log "error: $*" >&2; exit 1; } need() { command -v "$1" > /dev/null 2>&1 || err "$1 is required but not found" } # --- detect platform -------------------------------------------------------- detect_os() { case "$(uname -s)" in Linux*) echo "linux" ;; Darwin*) echo "darwin" ;; *) err "unsupported OS: $(uname -s)" ;; esac } detect_arch() { case "$(uname -m)" in x86_64|amd64) echo "amd64" ;; aarch64|arm64) echo "arm64" ;; *) err "unsupported architecture: $(uname -m)" ;; esac } # --- resolve version -------------------------------------------------------- resolve_version() { if [ "$VERSION" = "latest" ]; then # Try stable release first, fall back to any release (including prereleases) VERSION=$(curl -sSfL "https://api.github.com/repos/${REPO}/releases/latest" 2>/dev/null \ | grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"//;s/".*//' || true) if [ -z "$VERSION" ]; then VERSION=$(curl -sSfL "https://api.github.com/repos/${REPO}/releases" \ | grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"//;s/".*//') fi [ -n "$VERSION" ] || err "could not determine latest version" fi } # --- pick install dir ------------------------------------------------------- pick_install_dir() { if [ -n "$INSTALL_DIR" ]; then return fi if [ "$(id -u)" = "0" ]; then INSTALL_DIR="/usr/local/bin" elif [ -d "/usr/local/bin" ] && [ -w "/usr/local/bin" ]; then INSTALL_DIR="/usr/local/bin" else INSTALL_DIR="${HOME}/.local/bin" fi } # --- main ------------------------------------------------------------------- main() { need curl need tar OS=$(detect_os) ARCH=$(detect_arch) resolve_version ARCHIVE="${BINARY}-${VERSION}-${OS}-${ARCH}.tar.gz" URL="https://github.com/${REPO}/releases/download/${VERSION}/${ARCHIVE}" pick_install_dir mkdir -p "$INSTALL_DIR" TEMP_DIR=$(mktemp -d) trap 'rm -rf "$TEMP_DIR"' EXIT log "" log " Installing ${BINARY} ${VERSION} (${OS}/${ARCH})" log " From: ${URL}" log " To: ${INSTALL_DIR}/${BINARY}" log "" curl -sSfL "$URL" -o "${TEMP_DIR}/${ARCHIVE}" \ || err "download failed — check that ${VERSION} exists at https://github.com/${REPO}/releases" tar -xzf "${TEMP_DIR}/${ARCHIVE}" -C "$TEMP_DIR" \ || err "failed to extract archive" if [ -f "${TEMP_DIR}/${BINARY}" ]; then install -m 755 "${TEMP_DIR}/${BINARY}" "${INSTALL_DIR}/${BINARY}" else err "binary '${BINARY}' not found in archive" fi log " Installed ${BINARY} ${VERSION} to ${INSTALL_DIR}/${BINARY}" log "" # Check if install dir is in PATH case ":${PATH}:" in *":${INSTALL_DIR}:"*) ;; *) log " Note: ${INSTALL_DIR} is not in your PATH." log " Add it with: export PATH=\"${INSTALL_DIR}:\$PATH\"" log "" ;; esac log " Get started:" log " ${BINARY} server # start the dashboard" log " ${BINARY} agent-setup # configure agent hooks" log " ${BINARY} install # install as a system service" log "" } main