#!/bin/sh # capa-rs (command line) installer, published by Humanly (https://humanly.is). # # curl -fsSL https://humanly.is/install/capa-rs | sh # # What it does, and nothing else: # 1. picks the release file for your OS (macOS or Linux) and CPU (arm64 or x86_64) # from https://github.com/marirs/capa-rs/releases # 2. downloads it and its .sha256 file, and stops if the checksum does not match # 3. copies one binary, capa_cli, into INSTALL_DIR (default: $HOME/.local/bin) # It never uses sudo and never edits your shell profile. # # Options (environment variables): # INSTALL_DIR=/some/dir where to put capa_cli # VERSION=v1.2.3 install a specific release tag instead of the latest # # Windows: download from https://humanly.is/security-tools#capa-rs instead. set -eu REPO="marirs/capa-rs" BINARY="capa_cli" ARCHIVE="raw" say() { printf '%s\n' "$*"; } fail() { printf 'error: %s\n' "$*" >&2; exit 1; } need() { command -v "$1" >/dev/null 2>&1 || fail "'$1' is required but not installed"; } sha256_of() { if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | awk '{print $1}' elif command -v shasum >/dev/null 2>&1; then shasum -a 256 "$1" | awk '{print $1}' else fail "need sha256sum or shasum to verify the download"; fi } main() { need curl need uname if [ "$ARCHIVE" = "tar" ]; then need tar; fi case "$(uname -s)" in Darwin) os=macos; target_os=apple-darwin ;; Linux) os=linux; target_os=unknown-linux-gnu ;; *) fail "unsupported OS $(uname -s). Download from https://github.com/$REPO/releases" ;; esac case "$(uname -m)" in arm64|aarch64) arch=aarch64 ;; x86_64|amd64) arch=x86_64 ;; *) fail "unsupported CPU $(uname -m). Download from https://github.com/$REPO/releases" ;; esac target="$arch-$target_os" tag="${VERSION:-}" if [ -z "$tag" ]; then # /releases/latest redirects to /releases/tag/, so no API token is needed. tag="$(curl -fsSLI -o /dev/null -w '%{url_effective}' "https://github.com/$REPO/releases/latest")" tag="${tag##*/}" fi case "$tag" in ''|latest|releases) fail "could not find the latest release of $REPO" ;; esac asset="capa_cli-$tag-$target" url="https://github.com/$REPO/releases/download/$tag/$asset" dir="${INSTALL_DIR:-$HOME/.local/bin}" tmp="$(mktemp -d)" trap 'rm -rf "$tmp"' EXIT INT TERM say "Downloading $asset ($tag)" curl -fsSL -o "$tmp/$asset" "$url" || fail "download failed: $url" curl -fsSL -o "$tmp/$asset.sha256" "$url.sha256" || fail "checksum file missing: $url.sha256" expected="$(awk '{print $1; exit}' "$tmp/$asset.sha256")" actual="$(sha256_of "$tmp/$asset")" if [ -z "$expected" ] || [ "$expected" != "$actual" ]; then fail "checksum mismatch for $asset, not installing" fi say "Checksum OK" if [ "$ARCHIVE" = "tar" ]; then tar -xzf "$tmp/$asset" -C "$tmp" "$BINARY" || fail "$BINARY not found in $asset" src="$tmp/$BINARY" else src="$tmp/$asset" fi mkdir -p "$dir" cp "$src" "$dir/$BINARY" chmod 755 "$dir/$BINARY" say "Installed $BINARY to $dir/$BINARY" case ":$PATH:" in *":$dir:"*) ;; *) say "Note: $dir is not on your PATH. Add it, for example:" say " export PATH=\"$dir:\$PATH\"" ;; esac } main "$@"