#!/bin/sh # Installs the opposable command line tool from getopposable.com. # # curl -fsSL https://getopposable.com/install.sh | sh # # It downloads the build for this computer, checks it against the published SHA-256 sums, and puts `opposable` in # ~/.local/bin (or /usr/local/bin when that is writable and ~/.local/bin isn't on your PATH). It never uses sudo. # Settings: OPPOSABLE_INSTALL_DIR=/some/dir to choose the folder, OPPOSABLE_VERSION to pick another version. set -eu VERSION="${OPPOSABLE_VERSION:-0.3.0-preview.1}" BASE="${OPPOSABLE_BASE_URL:-https://getopposable.com}" say() { printf '%s\n' "$*"; } die() { printf 'opposable install: %s\n' "$*" >&2; exit 1; } fetch() { # url file if command -v curl >/dev/null 2>&1; then curl -fsSL --retry 2 -o "$2" "$1" elif command -v wget >/dev/null 2>&1; then wget -q -O "$2" "$1" else die "needs curl or wget"; fi } sha256() { if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | cut -d ' ' -f 1 elif command -v shasum >/dev/null 2>&1; then shasum -a 256 "$1" | cut -d ' ' -f 1 else die "needs sha256sum or shasum to check the download"; fi } on_path() { case ":$PATH:" in *":$1:"*) return 0 ;; *) return 1 ;; esac; } main() { os="$(uname -s)" arch="$(uname -m)" case "$os" in Darwin) os=darwin; site_os=macos ;; Linux) os=linux; site_os=linux ;; *) die "this script is for macOS and Linux. On Windows, in PowerShell: irm https://getopposable.com/install.ps1 | iex" ;; esac case "$arch" in arm64 | aarch64) arch=arm64 ;; x86_64 | amd64) arch=x64 ;; *) die "no build for $arch yet" ;; esac # An Intel shell on Apple silicon (Rosetta) still gets the native build. if [ "$os" = darwin ] && [ "$arch" = x64 ] && [ "$(sysctl -n sysctl.proc_translated 2>/dev/null || echo 0)" = 1 ]; then arch=arm64; fi if [ "$os" = linux ] && ldd --version 2>&1 | grep -qi musl; then die "this build needs glibc; Alpine and other musl systems aren't supported yet" fi name="opposable-$VERSION-$os-$arch.gz" if [ -n "${OPPOSABLE_INSTALL_DIR:-}" ]; then dir="$OPPOSABLE_INSTALL_DIR" elif on_path "$HOME/.local/bin"; then dir="$HOME/.local/bin" elif [ -d /usr/local/bin ] && [ -w /usr/local/bin ]; then dir=/usr/local/bin else dir="$HOME/.local/bin"; fi tmp="$(mktemp -d 2>/dev/null || mktemp -d -t opposable)" trap 'rm -rf "$tmp"' EXIT INT TERM say "Downloading opposable $VERSION for $os-$arch…" fetch "$BASE/download/cli/SHA256SUMS" "$tmp/SHA256SUMS" || die "couldn't download the checksums" if [ -n "${OPPOSABLE_VERSION:-}" ]; then url="$BASE/download/cli/$name" else url="$BASE/get/cli-$site_os-$arch?src=install-sh"; fi fetch "$url" "$tmp/$name" || die "couldn't download $name" want="$(grep " $name\$" "$tmp/SHA256SUMS" | cut -d ' ' -f 1)" [ -n "$want" ] || die "$name isn't listed in SHA256SUMS" got="$(sha256 "$tmp/$name")" [ "$want" = "$got" ] || die "checksum mismatch for $name (expected $want, got $got). Nothing was installed." gzip -dc "$tmp/$name" > "$tmp/opposable" || die "couldn't unpack $name" chmod 755 "$tmp/opposable" mkdir -p "$dir" || die "couldn't create $dir (set OPPOSABLE_INSTALL_DIR to another folder)" mv -f "$tmp/opposable" "$dir/opposable" || die "couldn't write to $dir (set OPPOSABLE_INSTALL_DIR to another folder)" say "Installed $("$dir/opposable" --version) to $dir/opposable" if ! on_path "$dir"; then say "" say "$dir isn't on your PATH yet. Add it, for example:" case "${SHELL:-}" in */zsh) say " echo 'export PATH=\"$dir:\$PATH\"' >> ~/.zshrc && exec zsh" ;; */bash) say " echo 'export PATH=\"$dir:\$PATH\"' >> ~/.bashrc && exec bash" ;; *) say " export PATH=\"$dir:\$PATH\"" ;; esac fi say "" say "Next: in the Opposable app on your phone, tap Pair with computer, then run" say " opposable connect CODE" } main "$@"