#!/bin/sh set -eu REPO="shipload/toolkit" BIN="shiploadcli" MAC_TEAM_ID="CE35MAVD43" MARKER="# added by the shiploadcli installer" say() { printf '%s\n' "$*"; } err() { printf 'error: %s\n' "$*" >&2; exit 1; } need() { command -v "$1" >/dev/null 2>&1 || err "this installer needs '$1', which was not found"; } usage() { cat </dev/null || echo 0)" = "1" ]; then arch="arm64" fi case "$arch" in arm64) ASSET="$BIN-mac-arm64.zip" ;; x86_64) ASSET="$BIN-mac-x64.zip" ;; *) err "unsupported macOS architecture: $arch" ;; esac ;; Linux) if [ -e /etc/alpine-release ] || { command -v ldd >/dev/null 2>&1 && ldd --version 2>&1 | grep -qi musl; }; then err "musl-based Linux (such as Alpine) is not supported; use a glibc distribution" fi case "$arch" in x86_64 | amd64) ASSET="$BIN-linux-x64" ;; aarch64 | arm64) ASSET="$BIN-linux-arm64" ;; *) err "unsupported Linux architecture: $arch" ;; esac ;; MINGW* | MSYS* | CYGWIN*) err "on Windows, run in PowerShell: irm https://get.shiploadgame.com/install.ps1 | iex" ;; *) err "unsupported operating system: $os" ;; esac } sha256_of() { 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 err "this installer needs 'sha256sum' or 'shasum' to verify the download" fi } verify_checksum() { expected="$(awk -v f="$ASSET" '$2 == f || $2 == "*" f { print $1 }' "$1")" [ -n "$expected" ] || err "$ASSET is not listed in the release's SHA256SUMS" actual="$(sha256_of "$2")" [ "$expected" = "$actual" ] || err "checksum mismatch for $ASSET (expected $expected, got $actual)" } verify_mac_signature() { need codesign codesign --verify --strict \ -R="anchor apple generic and certificate leaf[subject.OU] = \"$MAC_TEAM_ID\"" \ "$1" 2>/dev/null || err "$BIN is not signed by the expected developer (team $MAC_TEAM_ID); not installing" } profile_file() { case "$(basename "${SHELL:-sh}")" in zsh) echo "${ZDOTDIR:-$HOME}/.zshrc" ;; bash) if [ "$(uname -s)" = "Darwin" ]; then echo "$HOME/.bash_profile"; else echo "$HOME/.bashrc"; fi ;; fish) echo "${XDG_CONFIG_HOME:-$HOME/.config}/fish/conf.d/$BIN.fish" ;; *) echo "$HOME/.profile" ;; esac } add_to_path() { dir="$1" case ":$PATH:" in *":$dir:"*) ON_PATH=1; return 0 ;; esac if [ "$NO_MODIFY_PATH" = "1" ]; then say "$dir is not on your PATH. Add it to use '$BIN' by name." return 0 fi profile="$(profile_file)" if [ -f "$profile" ] && grep -qF "$MARKER" "$profile"; then say "Open a new terminal to put $dir on your PATH." return 0 fi mkdir -p "$(dirname "$profile")" case "$profile" in *.fish) line="fish_add_path \"$dir\" $MARKER" ;; *) line="export PATH=\"$dir:\$PATH\" $MARKER" ;; esac printf '\n%s\n' "$line" >>"$profile" say "Added $dir to your PATH in $profile. Open a new terminal to use '$BIN' by name." } main() { NO_MODIFY_PATH="${SHIPLOAD_NO_MODIFY_PATH:-0}" ON_PATH=0 for arg in "$@"; do case "$arg" in --no-modify-path) NO_MODIFY_PATH=1 ;; -h | --help) usage; exit 0 ;; *) err "unknown option: $arg (see --help)" ;; esac done need curl need uname need mktemp detect_asset install_dir="${SHIPLOAD_INSTALL_DIR:-$HOME/.local/bin}" base="https://github.com/$REPO/releases/latest/download" tmp="$(mktemp -d)" trap 'rm -rf "$tmp"' EXIT INT TERM say "Downloading $ASSET..." fetch "$base/SHA256SUMS" "$tmp/SHA256SUMS" fetch "$base/$ASSET" "$tmp/$ASSET" verify_checksum "$tmp/SHA256SUMS" "$tmp/$ASSET" case "$ASSET" in *.zip) need unzip unzip -q "$tmp/$ASSET" -d "$tmp/unpacked" binary="$(find "$tmp/unpacked" -type f -name "${ASSET%.zip}" | head -n 1)" [ -n "$binary" ] || err "$ASSET did not contain ${ASSET%.zip}" verify_mac_signature "$binary" ;; *) binary="$tmp/$ASSET" ;; esac chmod 755 "$binary" mkdir -p "$install_dir" cp "$binary" "$install_dir/.$BIN.new" mv -f "$install_dir/.$BIN.new" "$install_dir/$BIN" version="$("$install_dir/$BIN" --version 2>/dev/null || echo unknown)" say "Installed $BIN $version to $install_dir/$BIN" add_to_path "$install_dir" say "" if [ "$ON_PATH" = "1" ]; then say "Next: run '$BIN init' to set up your config." else say "Next: run '$install_dir/$BIN init' to set up your config." fi } main "$@"