chore: add installer script
30d81aa2
1 file(s) · +90 −0
| 1 | + | #!/usr/bin/env sh |
|
| 2 | + | # Andromeda installer. |
|
| 3 | + | # |
|
| 4 | + | # Usage: |
|
| 5 | + | # curl -fsSL https://raw.githubusercontent.com/stevedylandev/andromeda/main/install.sh | sh -s -- <app> [version] |
|
| 6 | + | # |
|
| 7 | + | # Examples: |
|
| 8 | + | # curl -fsSL .../install.sh | sh -s -- sipp # latest |
|
| 9 | + | # curl -fsSL .../install.sh | sh -s -- feeds v0.4.0 # specific |
|
| 10 | + | # |
|
| 11 | + | # Env: |
|
| 12 | + | # INSTALL_DIR target dir (default: /usr/local/bin) |
|
| 13 | + | ||
| 14 | + | set -eu |
|
| 15 | + | ||
| 16 | + | REPO="stevedylandev/andromeda" |
|
| 17 | + | APP="${1:-}" |
|
| 18 | + | VERSION="${2:-}" |
|
| 19 | + | INSTALL_DIR="${INSTALL_DIR:-/usr/local/bin}" |
|
| 20 | + | ||
| 21 | + | if [ -z "$APP" ]; then |
|
| 22 | + | echo "error: app name required" >&2 |
|
| 23 | + | echo "usage: install.sh <app> [version]" >&2 |
|
| 24 | + | exit 1 |
|
| 25 | + | fi |
|
| 26 | + | ||
| 27 | + | # Detect OS |
|
| 28 | + | uname_os=$(uname -s) |
|
| 29 | + | case "$uname_os" in |
|
| 30 | + | Linux) os="linux" ;; |
|
| 31 | + | Darwin) os="macos" ;; |
|
| 32 | + | *) echo "error: unsupported OS: $uname_os" >&2; exit 1 ;; |
|
| 33 | + | esac |
|
| 34 | + | ||
| 35 | + | # Detect arch |
|
| 36 | + | uname_arch=$(uname -m) |
|
| 37 | + | case "$uname_arch" in |
|
| 38 | + | x86_64|amd64) arch="x86_64" ;; |
|
| 39 | + | arm64|aarch64) arch="arm64" ;; |
|
| 40 | + | *) echo "error: unsupported arch: $uname_arch" >&2; exit 1 ;; |
|
| 41 | + | esac |
|
| 42 | + | ||
| 43 | + | # Resolve version |
|
| 44 | + | if [ -z "$VERSION" ]; then |
|
| 45 | + | echo "Looking up latest ${APP} release..." |
|
| 46 | + | VERSION=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases?per_page=50" \ |
|
| 47 | + | | grep -o "\"tag_name\": *\"${APP}/v[^\"]*\"" \ |
|
| 48 | + | | head -1 \ |
|
| 49 | + | | sed -E 's/.*"'"${APP}"'\/(v[^"]+)".*/\1/') |
|
| 50 | + | if [ -z "$VERSION" ]; then |
|
| 51 | + | echo "error: no releases found for ${APP}" >&2 |
|
| 52 | + | exit 1 |
|
| 53 | + | fi |
|
| 54 | + | fi |
|
| 55 | + | ||
| 56 | + | # Strip leading v for archive filename (goreleaser strips it from {{.Version}}) |
|
| 57 | + | ver_num="${VERSION#v}" |
|
| 58 | + | tag="${APP}/${VERSION}" |
|
| 59 | + | archive="${APP}_${ver_num}_${os}_${arch}.tar.gz" |
|
| 60 | + | url="https://github.com/${REPO}/releases/download/${tag}/${archive}" |
|
| 61 | + | ||
| 62 | + | echo "Downloading ${url}" |
|
| 63 | + | tmpdir=$(mktemp -d) |
|
| 64 | + | trap 'rm -rf "$tmpdir"' EXIT |
|
| 65 | + | ||
| 66 | + | if ! curl -fsSL "$url" -o "${tmpdir}/${archive}"; then |
|
| 67 | + | echo "error: download failed — does ${tag} have a ${os}/${arch} build?" >&2 |
|
| 68 | + | exit 1 |
|
| 69 | + | fi |
|
| 70 | + | ||
| 71 | + | tar -xzf "${tmpdir}/${archive}" -C "$tmpdir" |
|
| 72 | + | ||
| 73 | + | if [ ! -f "${tmpdir}/${APP}" ]; then |
|
| 74 | + | echo "error: binary ${APP} not found in archive" >&2 |
|
| 75 | + | exit 1 |
|
| 76 | + | fi |
|
| 77 | + | ||
| 78 | + | chmod +x "${tmpdir}/${APP}" |
|
| 79 | + | ||
| 80 | + | # Install. Use sudo if INSTALL_DIR not writable. |
|
| 81 | + | if [ -w "$INSTALL_DIR" ] || [ ! -e "$INSTALL_DIR" ]; then |
|
| 82 | + | mkdir -p "$INSTALL_DIR" |
|
| 83 | + | mv "${tmpdir}/${APP}" "${INSTALL_DIR}/${APP}" |
|
| 84 | + | else |
|
| 85 | + | echo "Installing to ${INSTALL_DIR} (requires sudo)" |
|
| 86 | + | sudo mkdir -p "$INSTALL_DIR" |
|
| 87 | + | sudo mv "${tmpdir}/${APP}" "${INSTALL_DIR}/${APP}" |
|
| 88 | + | fi |
|
| 89 | + | ||
| 90 | + | echo "Installed ${APP} ${VERSION} to ${INSTALL_DIR}/${APP}" |