#!/bin/sh # Installs Statac on a Mac or Linux from a release's package: # # curl -fsSL https://get.statac.dev | sh # curl -fsSL https://get.statac.dev | sh -s -- --version 0.1.0 --to ~/bin # # It downloads the package for this machine, checks it against the release's # SHA256SUMS, and puts `statac` in ~/.local/bin, or in the folder --to names. # The licences that travel with the program go to ~/.local/share/statac. # It asks for no password and changes no file of the shell's. set -eu releases=${STATAC_RELEASES:-https://github.com/statac-ssg/statac/releases} stop() { echo "$1" >&2 [ $# -lt 2 ] || echo " $2" >&2 exit 1 } # fetch
fetch() { if command -v curl >/dev/null 2>&1; then curl -fsSL "$1" -o "$2" else wget -q -O "$2" "$1" fi } sha256() { if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" else shasum -a 256 "$1" fi | cut -d ' ' -f 1 } # Everything runs from here, called on the last line, so a download cut # short runs nothing. main() { version= to= while [ $# -gt 0 ]; do case $1 in --version | --to) [ $# -ge 2 ] || stop "Missing value: \`$1\` needs one after it." case $1 in --version) version=${2#v} ;; --to) to=$2 ;; esac shift 2 ;; *) stop "Unknown option: \`$1\`" "The options are \`--version\` and \`--to\`." ;; esac done system=$(uname -s) processor=$(uname -m) case $processor in x86_64 | amd64) processor=x86_64 ;; aarch64 | arm64) processor=aarch64 ;; *) processor= ;; esac case $system in Darwin) # A shell running under Rosetta says x86_64 on Apple silicon. if [ "$(sysctl -n hw.optional.arm64 2>/dev/null)" = 1 ]; then processor=aarch64 fi target=$processor-apple-darwin ;; # The static package, which runs on any distribution. Linux) target=$processor-unknown-linux-musl ;; *) processor= ;; esac [ -n "$processor" ] || stop "No package for this machine: $(uname -s) on $(uname -m)" \ "Other ways to install: https://statac.dev/install/" command -v curl >/dev/null 2>&1 || command -v wget >/dev/null 2>&1 || stop "Can't download Statac: this machine has neither \`curl\` nor \`wget\`." \ "Install one, then run this again." command -v sha256sum >/dev/null 2>&1 || command -v shasum >/dev/null 2>&1 || stop "Can't check the package: this machine has neither \`sha256sum\` nor \`shasum\`." \ "Install one, then run this again." work=$(mktemp -d) trap 'rm -rf "$work"' EXIT if [ -n "$version" ]; then sums=$releases/download/v$version/SHA256SUMS fetch "$sums" "$work/SHA256SUMS" || stop "Can't download $sums" \ "Is $version a release? They are listed at $releases" else sums=$releases/latest/download/SHA256SUMS fetch "$sums" "$work/SHA256SUMS" || stop "Can't download $sums" fi # A line is the hash, a space, a space or an asterisk, and the name. line=$(grep -e "-$target\\.tar\\.gz\$" "$work/SHA256SUMS" || true) [ -n "$line" ] || stop "No package for this machine in the release: nothing in $sums ends \`$target.tar.gz\`." \ "Other ways to install: https://statac.dev/install/" expected=${line%% *} package=${line##*[ \*]} name=${package%.tar.gz} version=${name#statac-} version=${version%-"$target"} echo "Downloading Statac $version ($target)" address=$releases/download/v$version/$package fetch "$address" "$work/$package" || stop "Can't download $address" found=$(sha256 "$work/$package") [ "$found" = "$expected" ] || stop "The package doesn't match the release's SHA256SUMS, so nothing was installed." \ "Expected $expected, and the download is $found." tar -xzf "$work/$package" -C "$work" || stop "Can't unpack $package, so nothing was installed." [ -f "$work/$name/statac" ] || stop "The package holds no \`$name/statac\`, so nothing was installed." to=${to:-$HOME/.local/bin} mkdir -p "$to" || stop "Can't make the folder $to" to=$(cd "$to" && pwd) # Written beside its place and moved in, so a `statac` that is running # is replaced whole. cp "$work/$name/statac" "$to/.statac-new" || stop "Can't write to $to" chmod 755 "$to/.statac-new" mv -f "$to/.statac-new" "$to/statac" notices=${XDG_DATA_HOME:-$HOME/.local/share}/statac mkdir -p "$notices" || stop "Can't make the folder $notices" cp "$work/$name/LICENSE-MIT" "$work/$name/LICENSE-APACHE" \ "$work/$name/THIRD-PARTY.md" "$work/$name/THIRD-PARTY-GRAMMARS.md" \ "$notices/" || stop "Can't write to $notices" said=$("$to/statac" --version 2>&1) || stop "Installed $to/statac, and it doesn't run on this machine:" "$said" echo "Installed $said at $to/statac" echo "Its licences are in $notices" case :$PATH: in *:"$to":*) first=$(command -v statac || true) if [ "$first" != "$to/statac" ]; then echo echo "Another \`statac\` comes first on your PATH: $first" echo " Until it is removed, \`statac\` runs that one." fi ;; *) echo echo "$to isn't on your PATH, so \`statac\` alone won't be found." case ${SHELL##*/} in fish) echo " Add it: fish_add_path \"$to\"" ;; zsh) echo " Add this line to ~/.zshrc: export PATH=\"$to:\$PATH\"" ;; bash) echo " Add this line to ~/.bashrc: export PATH=\"$to:\$PATH\"" ;; *) echo " Add this line to your shell's startup file: export PATH=\"$to:\$PATH\"" ;; esac ;; esac } main "$@"