#!/bin/sh # Installs berth: https://berth.lol # # curl -fsSL https://get.berth.lol | sh # # Picks the build for this OS and CPU, checks it against SHA256SUMS and puts # it in ~/.local/bin (or $BERTH_INSTALL_DIR). No sudo, nothing else changed. # # Everything is inside main(), run on the last line, so a download cut short # runs nothing. set -eu BASE="${BERTH_BASE:-https://get.berth.lol}" DIR="${BERTH_INSTALL_DIR:-$HOME/.local/bin}" say() { printf '%s\n' "$*"; } fail() { printf 'berth 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 fail "needs curl or wget" fi } sha256() { if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | cut -d' ' -f1 elif command -v shasum >/dev/null 2>&1; then shasum -a 256 "$1" | cut -d' ' -f1 else fail "needs sha256sum or shasum to check the download" fi } target() { os=$(uname -s) arch=$(uname -m) case "$os-$arch" in Darwin-arm64 | Darwin-aarch64) echo berth-macos-arm64 ;; Darwin-x86_64) echo berth-macos-x64 ;; Linux-aarch64 | Linux-arm64) echo berth-linux-arm64 ;; Linux-x86_64 | Linux-amd64) echo berth-linux-x64 ;; *) fail "no berth build for $os $arch (there are: macOS and Linux, arm64 and x64)" ;; esac } main() { file=$(target) tmp=$(mktemp -d 2>/dev/null || mktemp -d -t berth) trap 'rm -rf "$tmp"' EXIT INT TERM say "⚓ downloading $file…" fetch "$BASE/latest/$file" "$tmp/berth" || fail "couldn't download $BASE/latest/$file" fetch "$BASE/latest/SHA256SUMS" "$tmp/SHA256SUMS" || fail "couldn't download $BASE/latest/SHA256SUMS" want=$(grep " $file\$" "$tmp/SHA256SUMS" | cut -d' ' -f1) [ -n "$want" ] || fail "$file isn't listed in SHA256SUMS" got=$(sha256 "$tmp/berth") [ "$got" = "$want" ] || fail "checksum mismatch for $file (got $got, expected $want) — not installed" chmod 755 "$tmp/berth" mkdir -p "$DIR" || fail "couldn't create $DIR (set BERTH_INSTALL_DIR to install elsewhere)" # A new file rather than overwriting in place: macOS caches code signatures # per file and kills a binary whose contents changed under it. if ! { cp "$tmp/berth" "$DIR/.berth.new" && mv -f "$DIR/.berth.new" "$DIR/berth"; }; then fail "couldn't write to $DIR (set BERTH_INSTALL_DIR to install elsewhere)" fi say "⚓ installed $("$DIR/berth" --version 2>/dev/null || echo berth) to $DIR/berth" case ":$PATH:" in *":$DIR:"*) ;; *) say "" say "$DIR isn't on your PATH. Add it, e.g.:" case "${SHELL:-}" in */zsh) say " echo 'export PATH=\"$DIR:\$PATH\"' >> ~/.zshrc && exec zsh" ;; */fish) say " fish_add_path $DIR" ;; *) say " echo 'export PATH=\"$DIR:\$PATH\"' >> ~/.bashrc && exec bash" ;; esac ;; esac if ! command -v tmux >/dev/null 2>&1; then say "" say "berth runs on tmux, which isn't installed here:" case "$(uname -s)" in Darwin) say " brew install tmux" ;; *) say " sudo apt install tmux (or dnf / apk / pacman)" ;; esac say "No tmux on this machine? Run berth inside a docker container: berth docker" fi say "" say "Start it with: berth" } main "$@"