From d9ed665712d4d2fbc99de90e10c6d80be1fc9593 Mon Sep 17 00:00:00 2001 From: Amin Jamal Date: Mon, 4 May 2026 20:34:24 +0200 Subject: [PATCH] feat(docs): add a command to simply install the binary Co-authored-by: Copilot --- README.md | 13 ++++++ install.sh | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100755 install.sh diff --git a/README.md b/README.md index 7836db4..40e7b39 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,19 @@ Available as both a **Rust library** and a **CLI tool**. ## Installation +### Quick install (Linux / macOS) + +```sh +curl -sSfL https://raw.githubusercontent.com/OWNER/openapi-aggregator/main/install.sh | sh +``` + +Install a specific version or to a custom directory: + +```sh +VERSION=v0.1.0 curl -sSfL https://raw.githubusercontent.com/OWNER/openapi-aggregator/main/install.sh | sh +INSTALL_DIR=~/.local/bin curl -sSfL https://raw.githubusercontent.com/OWNER/openapi-aggregator/main/install.sh | sh +``` + ### From source ```sh diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..42f2c0b --- /dev/null +++ b/install.sh @@ -0,0 +1,121 @@ +#!/bin/sh +# Install script for openapi-aggregator +# Usage: curl -sSfL https://raw.githubusercontent.com/OWNER/openapi-aggregator/main/install.sh | sh +# +# Options (via environment variables): +# VERSION - specific version to install (e.g. v0.1.0). Defaults to latest. +# INSTALL_DIR - directory to install to. Defaults to /usr/local/bin. + +set -e + +REPO="OWNER/openapi-aggregator" +BINARY="openapi-aggregator" +INSTALL_DIR="${INSTALL_DIR:-/usr/local/bin}" + +# --- helpers --------------------------------------------------------------- + +info() { printf '\033[1;34m[info]\033[0m %s\n' "$1"; } +error() { printf '\033[1;31m[error]\033[0m %s\n' "$1" >&2; exit 1; } + +need() { + command -v "$1" >/dev/null 2>&1 || error "required command not found: $1" +} + +# --- detect OS & arch ------------------------------------------------------ + +detect_target() { + OS=$(uname -s) + ARCH=$(uname -m) + + case "$OS" in + Linux) + case "$ARCH" in + x86_64) TARGET="x86_64-unknown-linux-musl" ;; + aarch64) TARGET="aarch64-unknown-linux-musl" ;; + arm64) TARGET="aarch64-unknown-linux-musl" ;; + *) error "unsupported Linux architecture: $ARCH" ;; + esac + EXT="tar.gz" + ;; + Darwin) + case "$ARCH" in + x86_64) TARGET="x86_64-apple-darwin" ;; + arm64) TARGET="aarch64-apple-darwin" ;; + aarch64) TARGET="aarch64-apple-darwin" ;; + *) error "unsupported macOS architecture: $ARCH" ;; + esac + EXT="tar.gz" + ;; + MINGW*|MSYS*|CYGWIN*|Windows_NT) + TARGET="x86_64-pc-windows-msvc" + EXT="zip" + ;; + *) + error "unsupported OS: $OS" + ;; + esac + + info "detected target: $TARGET" +} + +# --- resolve version ------------------------------------------------------- + +resolve_version() { + if [ -n "$VERSION" ]; then + TAG="$VERSION" + else + need curl + TAG=$(curl -sSfL "https://api.github.com/repos/${REPO}/releases/latest" \ + | grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/') + [ -n "$TAG" ] || error "could not determine latest release" + fi + info "installing version: $TAG" +} + +# --- download & install ---------------------------------------------------- + +download_and_install() { + need curl + + FILENAME="${BINARY}-${TARGET}.${EXT}" + URL="https://github.com/${REPO}/releases/download/${TAG}/${FILENAME}" + + TMPDIR=$(mktemp -d) + trap 'rm -rf "$TMPDIR"' EXIT + + info "downloading $URL" + curl -sSfL -o "${TMPDIR}/${FILENAME}" "$URL" \ + || error "download failed — check that version ${TAG} exists and has a ${TARGET} build" + + info "extracting..." + case "$EXT" in + tar.gz) + tar xzf "${TMPDIR}/${FILENAME}" -C "$TMPDIR" + ;; + zip) + need unzip + unzip -q "${TMPDIR}/${FILENAME}" -d "$TMPDIR" + ;; + esac + + # Install binary + if [ -w "$INSTALL_DIR" ]; then + mv "${TMPDIR}/${BINARY}" "${INSTALL_DIR}/${BINARY}" + else + info "elevated permissions required to install to ${INSTALL_DIR}" + sudo mv "${TMPDIR}/${BINARY}" "${INSTALL_DIR}/${BINARY}" + fi + + chmod +x "${INSTALL_DIR}/${BINARY}" + + info "installed ${BINARY} to ${INSTALL_DIR}/${BINARY}" + "${INSTALL_DIR}/${BINARY}" --version 2>/dev/null || true +} + +# --- main ------------------------------------------------------------------ + +detect_target +resolve_version +download_and_install + +info "done!"