#!/bin/sh # Install Zetlyn. # # curl -fsSL https://get.zetlyn.com | sh # # It fetches one binary, checks it against the checksums published beside it, and puts it somewhere # on your path. It installs nothing else: adapters are separate programs and the models a build needs # are fetched by `zetlyn model install`, both only when you ask for them. # # ZETLYN_VERSION=0.1.0 sh a version other than the current one # ZETLYN_TO=~/.local/bin sh somewhere other than the first writable place below set -eu FROM=${ZETLYN_FROM:-https://download.zetlyn.com/zetlyn} case "$(uname -s)" in Linux) OS=linux ;; Darwin) OS=macos ;; *) echo "zetlyn: this installs on Linux and macOS. On anything else, build it from source." >&2; exit 1 ;; esac case "$(uname -m)" in x86_64 | amd64) ARCH=x86_64 ;; arm64 | aarch64) ARCH=aarch64 ;; *) echo "zetlyn: $(uname -m) is not a platform binaries are published for." >&2; exit 1 ;; esac TARGET="$OS-$ARCH" fetch() { if command -v curl >/dev/null 2>&1; then curl -fsSL "$1" elif command -v wget >/dev/null 2>&1; then wget -qO- "$1" else echo "zetlyn: neither curl nor wget is here" >&2; exit 1 fi } VERSION=${ZETLYN_VERSION:-$(fetch "$FROM/latest" | tr -d ' \n\r')} [ -n "$VERSION" ] || { echo "zetlyn: $FROM/latest says nothing" >&2; exit 1; } TMP=$(mktemp -d) trap 'rm -rf "$TMP"' EXIT INT TERM echo "zetlyn $VERSION for $TARGET" fetch "$FROM/$VERSION/$TARGET/zetlyn" > "$TMP/zetlyn" || { echo "zetlyn: there is no binary for $TARGET in $VERSION." >&2 echo " What is published is listed at $FROM/$VERSION/" >&2 exit 1 } # Checked before it is run, and not afterwards. A downloaded program that is verified by the person # who remembers to is not verified. fetch "$FROM/$VERSION/SHA256SUMS" > "$TMP/SHA256SUMS" WANT=$(grep " $TARGET/zetlyn\$" "$TMP/SHA256SUMS" | cut -d' ' -f1) if command -v sha256sum >/dev/null 2>&1; then GOT=$(sha256sum "$TMP/zetlyn" | cut -d' ' -f1) elif command -v shasum >/dev/null 2>&1; then GOT=$(shasum -a 256 "$TMP/zetlyn" | cut -d' ' -f1) else echo "zetlyn: no sha256sum and no shasum, so the bytes cannot be checked" >&2; exit 1 fi [ -n "$WANT" ] || { echo "zetlyn: SHA256SUMS names no $TARGET/zetlyn" >&2; exit 1; } [ "$WANT" = "$GOT" ] || { echo "zetlyn: the bytes are not the ones published." >&2 echo " published $WANT" >&2 echo " fetched $GOT" >&2 exit 1 } chmod +x "$TMP/zetlyn" if [ -n "${ZETLYN_TO:-}" ]; then TO=$ZETLYN_TO else TO="" for candidate in /usr/local/bin "$HOME/.local/bin"; do [ -d "$candidate" ] && [ -w "$candidate" ] && { TO=$candidate; break; } done [ -n "$TO" ] || TO="$HOME/.local/bin" fi mkdir -p "$TO" mv "$TMP/zetlyn" "$TO/zetlyn" echo "installed $TO/zetlyn" case ":$PATH:" in *":$TO:"*) ;; *) echo "$TO is not on your PATH" ;; esac echo echo " zetlyn init" echo " zetlyn corpus subscribe zetlyn/docs" echo " zetlyn serve"