aboutsummaryrefslogtreecommitdiffstats
path: root/site/install.sh
blob: 25c1ada009df22e0650135d1468c023a54fc7d1e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/bin/sh
# sl0ppi installer.
#
#   curl -fsSL https://sl0ppi.sl0p.foo/install.sh | sh
#   curl -fsSL https://sl0ppi.sl0p.foo/install.sh | sh -s -- --prefix /opt/sl0ppi
#
# Fetches the current release, VERIFIES ITS SHA256, unpacks it, and runs the
# installer inside the tarball. Nothing is installed if the checksum does not
# match.
#
# POSIX sh on purpose, and deliberately short: you are piping this into a shell,
# so it should be readable in one sitting. Read it first:
#   curl -fsSL https://sl0ppi.sl0p.foo/install.sh | less
set -eu

BASE_URL="${SL0PPI_BASE_URL:-https://sl0ppi.sl0p.foo}"
PREFIX="${PREFIX:-$HOME/.local}"
KEEP=0

while [ $# -gt 0 ]; do
    case "$1" in
        --prefix) PREFIX="$2"; shift 2 ;;
        --prefix=*) PREFIX="${1#*=}"; shift ;;
        --keep) KEEP=1; shift ;;
        -h|--help) sed -n '2,14p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
        *) echo "install.sh: unknown argument '$1'" >&2; exit 2 ;;
    esac
done

say()  { printf '\033[36m==>\033[0m %s\n' "$*"; }
die()  { printf '\033[31merror:\033[0m %s\n' "$*" >&2; exit 1; }

need() { command -v "$1" >/dev/null 2>&1 || die "need $1"; }
need curl
need tar

# sha256: coreutils on Linux, shasum on macOS/BSD. No checksum tool, no install.
if command -v sha256sum >/dev/null 2>&1; then
    sha256() { sha256sum "$1" | cut -d' ' -f1; }
elif command -v shasum >/dev/null 2>&1; then
    sha256() { shasum -a 256 "$1" | cut -d' ' -f1; }
else
    die "need sha256sum or shasum to verify the download"
fi

# Only x86_64 linux is published so far; fail clearly rather than install
# something that cannot run.
os="$(uname -s)"; arch="$(uname -m)"
[ "$os" = "Linux" ] || die "no build for $os yet (linux only)"
case "$arch" in
    x86_64|amd64) ;;
    *) die "no build for $arch yet (x86_64 only)" ;;
esac

# One tiny JSON field reader, so this needs no jq.
json_field() {
    sed -n 's/.*"'"$1"'"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1
}

say "asking $BASE_URL for the current release"
latest="$(curl -fsSL "$BASE_URL/latest.json")" || die "could not fetch $BASE_URL/latest.json"

version="$(printf '%s' "$latest" | json_field version)"
artifact="$(printf '%s' "$latest" | json_field artifact)"
want="$(printf '%s' "$latest" | json_field sha256)"
[ -n "$version" ] && [ -n "$artifact" ] && [ -n "$want" ] || die "latest.json is malformed"

tmp="$(mktemp -d "${TMPDIR:-/tmp}/sl0ppi-install.XXXXXX")"
[ "$KEEP" -eq 1 ] || trap 'rm -rf "$tmp"' EXIT INT TERM

say "downloading sl0ppi $version"
curl -fSL --progress-bar -o "$tmp/$artifact" "$BASE_URL/releases/$artifact" \
    || die "download failed"

got="$(sha256 "$tmp/$artifact")"
if [ "$got" != "$want" ]; then
    die "CHECKSUM MISMATCH
  expected $want
  got      $got
Nothing was installed. Either the download was corrupted, or the file is not
what the release says it is; do not run it."
fi
say "sha256 verified"

tar -xzf "$tmp/$artifact" -C "$tmp"
dir="$tmp/$(printf '%s' "$artifact" | sed 's/\.tar\.gz$//')"
[ -x "$dir/install.sh" ] || die "the archive has no installer where one was expected"

say "running the bundled installer"
"$dir/install.sh" --prefix "$PREFIX"