#!/usr/bin/env bash # Papyrus CLI installer. Installs to ~/.local/bin by default — no sudo. # # One-liner: # curl -sSL https://api.rapidreview.io/cli/install | bash # # Pin a version: # PAPYRUS_VERSION=v0.2.0 curl -sSL https://api.rapidreview.io/cli/install | bash # # Install system-wide (prompts for sudo): # PAPYRUS_INSTALL_DIR=/usr/local/bin curl -sSL https://api.rapidreview.io/cli/install | bash set -euo pipefail BUCKET="${PAPYRUS_BUCKET:-rr_cli_releases}" VERSION="${PAPYRUS_VERSION:-latest}" # Default to a user-writable path so `curl | bash` never prompts for # sudo on a fresh machine. Matches the rustup / deno / uv convention. # Override with PAPYRUS_INSTALL_DIR=/usr/local/bin for a system-wide # install (will prompt for sudo). INSTALL_DIR="${PAPYRUS_INSTALL_DIR:-$HOME/.local/bin}" for cmd in curl tar uname; do command -v "$cmd" >/dev/null 2>&1 || { echo "error: required command not found: $cmd" >&2 exit 1 } done uname_s=$(uname -s) uname_m=$(uname -m) case "$uname_s/$uname_m" in Darwin/arm64) target="aarch64-apple-darwin" ;; Darwin/x86_64) target="x86_64-apple-darwin" ;; Linux/x86_64) target="x86_64-unknown-linux-musl" ;; Linux/aarch64|Linux/arm64) target="aarch64-unknown-linux-musl" ;; *) echo "error: unsupported platform $uname_s/$uname_m" >&2 echo "supported: Darwin/arm64, Darwin/x86_64, Linux/x86_64, Linux/aarch64" >&2 exit 1 ;; esac # Resolve `latest` → a concrete version. Cache-bust because GCS edge # caches can serve a stale VERSION for up to the object's max-age # (~1h) after a republish. if [[ "$VERSION" == "latest" ]]; then version_url="https://storage.googleapis.com/$BUCKET/latest/VERSION?t=$(date +%s)" if ! VERSION=$(curl -fsSL -H 'Cache-Control: no-cache' "$version_url"); then echo "error: failed to resolve latest papyrus version" >&2 echo "version URL: $version_url" >&2 echo "detected platform: $uname_s/$uname_m ($target)" >&2 exit 1 fi fi archive="papyrus-${VERSION}-${target}.tar.gz" url="https://storage.googleapis.com/$BUCKET/$VERSION/$archive" echo "> installing papyrus $VERSION ($target)" tmpdir=$(mktemp -d) trap 'rm -rf "$tmpdir"' EXIT if ! curl -fsSL -o "$tmpdir/$archive" "$url"; then echo "error: failed to download papyrus archive" >&2 echo "archive URL: $url" >&2 echo "detected platform: $uname_s/$uname_m ($target)" >&2 echo "requested version: $VERSION" >&2 exit 1 fi if curl -fsSL -o "$tmpdir/$archive.sha256" "$url.sha256"; then if command -v shasum >/dev/null 2>&1; then ( cd "$tmpdir" && shasum -a 256 -c "$archive.sha256" >/dev/null ) || { echo "error: checksum mismatch for $archive" >&2 exit 1 } elif command -v sha256sum >/dev/null 2>&1; then ( cd "$tmpdir" && sha256sum -c "$archive.sha256" >/dev/null ) || { echo "error: checksum mismatch for $archive" >&2 exit 1 } else echo "> warning: no checksum verifier found (shasum or sha256sum); skipping checksum" >&2 fi else echo "> warning: checksum unavailable: $url.sha256" >&2 fi if ! tar -xzf "$tmpdir/$archive" -C "$tmpdir"; then echo "error: failed to extract $archive" >&2 echo "archive URL: $url" >&2 exit 1 fi if [[ ! -f "$tmpdir/papyrus" ]]; then echo "error: archive did not contain a papyrus binary" >&2 echo "archive URL: $url" >&2 exit 1 fi chmod +x "$tmpdir/papyrus" if ! "$tmpdir/papyrus" --help >/dev/null; then echo "error: downloaded papyrus binary does not run on this machine" >&2 echo "archive URL: $url" >&2 echo "detected platform: $uname_s/$uname_m ($target)" >&2 exit 1 fi # Anywhere under $HOME is guaranteed user-writable; skip the probe. # For system paths, try a silent mkdir first — it succeeds when the # user has rights and fails silently otherwise, at which point we fall # back to sudo. case "$INSTALL_DIR" in "$HOME"|"$HOME"/*) mkdir -p "$INSTALL_DIR" mv "$tmpdir/papyrus" "$INSTALL_DIR/papyrus" ;; *) if mkdir -p "$INSTALL_DIR" 2>/dev/null && [[ -w "$INSTALL_DIR" ]]; then mv "$tmpdir/papyrus" "$INSTALL_DIR/papyrus" else echo "> need sudo to write $INSTALL_DIR" sudo mkdir -p "$INSTALL_DIR" sudo mv "$tmpdir/papyrus" "$INSTALL_DIR/papyrus" fi ;; esac on_path=0 case ":$PATH:" in *":$INSTALL_DIR:"*) on_path=1 ;; esac echo echo " installed: $INSTALL_DIR/papyrus ($VERSION)" if [[ $on_path -eq 1 ]]; then echo echo " Next step: run the command below to sign in —" echo echo " papyrus" echo else # Covers the common $HOME/.local/bin case where the user's shell # hasn't been rebooted to pick it up. Give a copy-paste fix. echo echo " Note: $INSTALL_DIR is not on your PATH yet." echo " Add this to ~/.bashrc or ~/.zshrc and reopen the terminal:" echo echo " export PATH=\"$INSTALL_DIR:\$PATH\"" echo echo " Then run: papyrus" echo fi