-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall-cli.sh
More file actions
69 lines (69 loc) · 3 KB
/
Copy pathinstall-cli.sh
File metadata and controls
69 lines (69 loc) · 3 KB
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
#!/bin/sh
# Install the host CLI on macOS or Linux; no checkout or build tools needed.
set -eu
umask 077
version=0.2.0
prefix="$HOME/.local"
while [ "$#" -gt 0 ]; do
case "$1" in
--version|--prefix)
[ "$#" -ge 2 ] || { echo "Missing value for $1" >&2; exit 1; }
case "$1" in --version) version=$2;; --prefix) prefix=$2;; esac
shift 2;;
-h|--help)
echo 'Usage: install-cli.sh [--version VERSION] [--prefix DIRECTORY]'
exit 0;;
*) echo "Unknown option: $1" >&2; exit 1;;
esac
done
case "$(uname -s)" in Darwin|Linux) ;; *) echo 'The CLI supports macOS and Linux.' >&2; exit 1;; esac
command -v python3 >/dev/null || { echo 'Install Python 3.9+ first.' >&2; exit 1; }
python3 - "$version" <<'PY'
import re, sys
if sys.version_info < (3, 9):
sys.exit('Install Python 3.9+ first.')
if not re.fullmatch(r'\d+\.\d+\.\d+', sys.argv[1]):
sys.exit('Invalid CLI release version.')
PY
stage=$(mktemp -d "${TMPDIR:-/tmp}/manasprites.XXXXXX")
trap 'rm -rf "$stage"' EXIT HUP INT TERM
archive=manasprites.tar.gz
if [ -n "${MANASPRITES_ARCHIVE:-}" ]; then
cp "$MANASPRITES_ARCHIVE" "$stage/$archive"
cp "$MANASPRITES_ARCHIVE.sha256" "$stage/$archive.sha256"
else
command -v curl >/dev/null || { echo 'Install curl first.' >&2; exit 1; }
base="https://github.com/managoat/manasprites/releases/download/cli-v$version"
curl -fsSL --retry 3 "$base/$archive" -o "$stage/$archive"
curl -fsSL --retry 3 "$base/$archive.sha256" -o "$stage/$archive.sha256"
fi
python3 - "$stage" "$version" <<'PY'
import hashlib, pathlib, re, sys, tarfile
root = pathlib.Path(sys.argv[1])
try:
archive = root / 'manasprites.tar.gz'
if archive.stat().st_size > 20 * 1024 * 1024:
raise ValueError('CLI archive exceeds size limit')
checksum = (root / 'manasprites.tar.gz.sha256').read_text().strip()
match = re.fullmatch(r'([0-9a-f]{64}) manasprites\.tar\.gz', checksum)
if not match or hashlib.sha256(archive.read_bytes()).hexdigest() != match[1]:
raise ValueError('CLI archive checksum mismatch')
expected = {'manasprites.py', 'provision.py', 'provision_remote.py', 'chat.py',
'install-cli.py', 'CLI_VERSION', 'LICENSE'}
with tarfile.open(archive) as tar:
members = tar.getmembers()
if (len(members) != len(expected) or {m.name for m in members} != expected
or any(not m.isfile() or m.size > 2 * 1024 * 1024 for m in members)):
raise ValueError('Invalid CLI archive contents')
# Write only the fixed set of regular files; no tar paths or links are extracted.
target = root / 'release'
target.mkdir()
for member in members:
with tar.extractfile(member) as source:
(target / member.name).write_bytes(source.read())
if (target / 'CLI_VERSION').read_text().strip() != sys.argv[2]:
raise ValueError('CLI release version mismatch')
except (OSError, ValueError, tarfile.TarError) as error:
sys.exit(str(error))
PY
python3 "$stage/release/install-cli.py" --prefix "$prefix"