#!/bin/bash set -e # ── Configuration ──────────────────────────────────────────────────────────── BINARY="ostiary" REPO_API="${OSTIARY_API:-https://git.vainend.com/api/v1/repos/admin/ostiary}" INSTALL_DIR="$HOME/.local/bin" # ── Colors ─────────────────────────────────────────────────────────────────── RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m' CYAN='\033[0;36m'; NC='\033[0m' info() { echo -e "${CYAN}[ostiary]${NC} $*"; } ok() { echo -e "${GREEN}[ostiary]${NC} $*"; } warn() { echo -e "${YELLOW}[ostiary]${NC} $*"; } die() { echo -e "${RED}[ostiary]${NC} $*" >&2; exit 1; } # ── Detect OS ──────────────────────────────────────────────────────────────── case "$(uname -s)" in Linux) OS="linux" ;; Darwin) OS="macos" ;; *) die "Unsupported OS: $(uname -s)" ;; esac # ── Detect architecture ────────────────────────────────────────────────────── case "$(uname -m)" in x86_64) ARCH="x86_64" ;; aarch64|arm64) ARCH="aarch64" ;; *) die "Unsupported architecture: $(uname -m)" ;; esac ASSET="${BINARY}-${OS}-${ARCH}" info "Platform: ${OS}-${ARCH}" # ── HTTP helper ────────────────────────────────────────────────────────────── if command -v curl &>/dev/null; then fetch() { curl -fsSL "$1"; } fetch_file() { curl -fsSL -o "$2" "$1"; } http_code() { curl -o /dev/null -sLw "%{http_code}" "$1"; } elif command -v wget &>/dev/null; then fetch() { wget -qO- "$1"; } fetch_file() { wget -qO "$2" "$1"; } http_code() { wget -q --server-response -O /dev/null "$1" 2>&1 \ | awk '/^ HTTP/{code=$2} END{print code}'; } else die "curl or wget is required" fi # ── Fetch latest release tag ───────────────────────────────────────────────── info "Fetching latest release info..." LATEST_JSON=$(fetch "${REPO_API}/releases/latest") \ || die "Failed to reach Gitea API: ${REPO_API}" VERSION=$(printf '%s' "$LATEST_JSON" \ | grep -o '"tag_name":"[^"]*"' \ | head -1 \ | cut -d'"' -f4) [ -z "$VERSION" ] && die "Could not parse version from API response" ok "Latest version: ${VERSION}" # ── Build download URL ─────────────────────────────────────────────────────── BASE_URL=$(printf '%s' "$REPO_API" | sed 's|/api/v1/repos||') DOWNLOAD_URL="${BASE_URL}/releases/download/${VERSION}/${ASSET}" info "Downloading ${DOWNLOAD_URL}..." CODE=$(http_code "$DOWNLOAD_URL") [ "$CODE" = "200" ] || die "Asset not found (HTTP ${CODE}): ${ASSET}" # ── Download ───────────────────────────────────────────────────────────────── TMP=$(mktemp) trap 'rm -f "$TMP"' EXIT fetch_file "$DOWNLOAD_URL" "$TMP" || die "Download failed" chmod +x "$TMP" # ── Install to ~/.local/bin ─────────────────────────────────────────────────── mkdir -p "$INSTALL_DIR" mv "$TMP" "$INSTALL_DIR/$BINARY" ok "Installed → $INSTALL_DIR/$BINARY" # ── Add ~/.local/bin to PATH if missing ────────────────────────────────────── if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then export PATH="$INSTALL_DIR:$PATH" EXPORT_LINE="export PATH=\"\$HOME/.local/bin:\$PATH\"" if [ -f "$HOME/.zshrc" ]; then PROFILE="$HOME/.zshrc" elif [ -f "$HOME/.bashrc" ]; then PROFILE="$HOME/.bashrc" elif [ -f "$HOME/.bash_profile" ]; then PROFILE="$HOME/.bash_profile" elif [ -f "$HOME/.profile" ]; then PROFILE="$HOME/.profile" else PROFILE="$HOME/.bashrc" fi if ! grep -qF "$INSTALL_DIR" "$PROFILE" 2>/dev/null; then printf '\n# Added by ostiary installer\n%s\n' "$EXPORT_LINE" >> "$PROFILE" ok "Added PATH entry to $PROFILE" fi fi echo "" ok "Launching ${BINARY}..." if tty_dev=$(tty 2>/dev/null); then exec "$INSTALL_DIR/$BINARY" <"$tty_dev" >"$tty_dev" 2>"$tty_dev" else ok "Run: $BINARY" fi