|
| 1 | +#!/bin/bash |
| 2 | +set -euo pipefail |
| 3 | + |
| 4 | +REPO="tomtev/loopwind" |
| 5 | +INSTALL_DIR="$HOME/.loopwind" |
| 6 | + |
| 7 | +# Colors |
| 8 | +RED='\033[0;31m' |
| 9 | +GREEN='\033[0;32m' |
| 10 | +YELLOW='\033[1;33m' |
| 11 | +CYAN='\033[0;36m' |
| 12 | +BOLD='\033[1m' |
| 13 | +NC='\033[0m' |
| 14 | + |
| 15 | +info() { printf "${CYAN}%s${NC}\n" "$1"; } |
| 16 | +success() { printf "${GREEN}%s${NC}\n" "$1"; } |
| 17 | +warn() { printf "${YELLOW}%s${NC}\n" "$1"; } |
| 18 | +error() { printf "${RED}%s${NC}\n" "$1" >&2; } |
| 19 | + |
| 20 | +# Detect OS |
| 21 | +OS="$(uname -s)" |
| 22 | +case "$OS" in |
| 23 | + Darwin) OS="darwin" ;; |
| 24 | + Linux) OS="linux" ;; |
| 25 | + *) |
| 26 | + error "Unsupported OS: $OS" |
| 27 | + exit 1 |
| 28 | + ;; |
| 29 | +esac |
| 30 | + |
| 31 | +# Detect architecture |
| 32 | +ARCH="$(uname -m)" |
| 33 | +case "$ARCH" in |
| 34 | + x86_64) ARCH="x64" ;; |
| 35 | + aarch64) ARCH="arm64" ;; |
| 36 | + arm64) ARCH="arm64" ;; |
| 37 | + *) |
| 38 | + error "Unsupported architecture: $ARCH" |
| 39 | + exit 1 |
| 40 | + ;; |
| 41 | +esac |
| 42 | + |
| 43 | +TARBALL="loopwind-${OS}-${ARCH}.tar.gz" |
| 44 | +URL="https://github.com/${REPO}/releases/latest/download/${TARBALL}" |
| 45 | + |
| 46 | +echo "" |
| 47 | +printf "${BOLD}loopwind installer${NC}\n" |
| 48 | +echo "" |
| 49 | + |
| 50 | +# Check for Node.js |
| 51 | +if ! command -v node &>/dev/null; then |
| 52 | + error "Node.js is required but not installed." |
| 53 | + echo " Install it from https://nodejs.org/ (v18+)" |
| 54 | + exit 1 |
| 55 | +fi |
| 56 | + |
| 57 | +NODE_VERSION="$(node -v)" |
| 58 | +info "Found Node.js ${NODE_VERSION}" |
| 59 | + |
| 60 | +# Download |
| 61 | +info "Downloading ${TARBALL}..." |
| 62 | +TMPDIR_PATH="$(mktemp -d)" |
| 63 | +trap 'rm -rf "$TMPDIR_PATH"' EXIT |
| 64 | + |
| 65 | +if ! curl -fsSL "$URL" -o "${TMPDIR_PATH}/${TARBALL}"; then |
| 66 | + error "Download failed. Check that a release exists for ${OS}-${ARCH}." |
| 67 | + echo " ${URL}" |
| 68 | + exit 1 |
| 69 | +fi |
| 70 | + |
| 71 | +# Extract |
| 72 | +info "Installing to ${INSTALL_DIR}..." |
| 73 | +rm -rf "$INSTALL_DIR" |
| 74 | +mkdir -p "$INSTALL_DIR" |
| 75 | +tar -xzf "${TMPDIR_PATH}/${TARBALL}" -C "$INSTALL_DIR" --strip-components=1 |
| 76 | + |
| 77 | +# Get version |
| 78 | +VERSION="unknown" |
| 79 | +if [ -f "$INSTALL_DIR/package.json" ]; then |
| 80 | + VERSION="$(node -e "console.log(require('$INSTALL_DIR/package.json').version)" 2>/dev/null || echo "unknown")" |
| 81 | +fi |
| 82 | + |
| 83 | +# Create wrapper script |
| 84 | +WRAPPER='#!/bin/bash |
| 85 | +exec node "$HOME/.loopwind/dist/cli.js" "$@"' |
| 86 | + |
| 87 | +SYSTEM_BIN="/usr/local/bin" |
| 88 | +USER_BIN="$HOME/.loopwind/bin" |
| 89 | + |
| 90 | +if [ -w "$SYSTEM_BIN" ] || [ -w "$(dirname "$SYSTEM_BIN")" ]; then |
| 91 | + echo "$WRAPPER" > "$SYSTEM_BIN/loopwind" |
| 92 | + chmod +x "$SYSTEM_BIN/loopwind" |
| 93 | + WRAPPER_PATH="$SYSTEM_BIN/loopwind" |
| 94 | +elif command -v sudo &>/dev/null; then |
| 95 | + info "Writing to ${SYSTEM_BIN} requires sudo..." |
| 96 | + echo "$WRAPPER" | sudo tee "$SYSTEM_BIN/loopwind" >/dev/null |
| 97 | + sudo chmod +x "$SYSTEM_BIN/loopwind" |
| 98 | + WRAPPER_PATH="$SYSTEM_BIN/loopwind" |
| 99 | +else |
| 100 | + mkdir -p "$USER_BIN" |
| 101 | + echo "$WRAPPER" > "$USER_BIN/loopwind" |
| 102 | + chmod +x "$USER_BIN/loopwind" |
| 103 | + WRAPPER_PATH="$USER_BIN/loopwind" |
| 104 | + warn "Could not write to ${SYSTEM_BIN}. Installed to ${USER_BIN}/loopwind" |
| 105 | + warn "Add this to your shell profile:" |
| 106 | + echo "" |
| 107 | + echo " export PATH=\"\$HOME/.loopwind/bin:\$PATH\"" |
| 108 | + echo "" |
| 109 | +fi |
| 110 | + |
| 111 | +echo "" |
| 112 | +success "loopwind v${VERSION} installed successfully!" |
| 113 | +echo "" |
| 114 | +echo " Location: ${INSTALL_DIR}" |
| 115 | +echo " Command: ${WRAPPER_PATH}" |
| 116 | +echo "" |
| 117 | +echo " Get started:" |
| 118 | +echo " loopwind init" |
| 119 | +echo " loopwind add image-template" |
| 120 | +echo " loopwind render image-template '{\"title\":\"Hello World\"}'" |
| 121 | +echo "" |
0 commit comments