-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathinstall
More file actions
executable file
·219 lines (196 loc) · 8.29 KB
/
Copy pathinstall
File metadata and controls
executable file
·219 lines (196 loc) · 8.29 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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#!/usr/bin/env bash
# Installs the latest (or a specific) version of jolt, the self-contained jolt
# binary. It bundles the runtime, compiler, jolt-core + stdlib, and the Chez
# boots, so there is nothing else to install — no Chez, no cc, no JVM.
set -euo pipefail
version=""
checksum=""
# Destination precedence mirrors the Makefile (PREFIX ?= root ? /usr/local :
# ~/.local): an explicit --dir wins; else $PREFIX/bin when PREFIX is set; else
# /usr/local/bin for root and ~/.local/bin for everyone else — a plain
# `curl | bash` must never need sudo.
if [[ ${EUID:-$(id -u)} -eq 0 ]]; then
default_install_dir="/usr/local/bin"
else
default_install_dir="$HOME/.local/bin"
fi
if [[ -n "${PREFIX:-}" ]]; then
default_install_dir="${PREFIX%/}/bin"
fi
install_dir="$default_install_dir"
download_dir=""
# Overridable so a fork's build can be installed: a nightly or a candidate
# lives on the fork that produced it, and without this there is no way to
# install one for testing.
repo="${JOLT_REPO:-jolt-lang/jolt}"
print_help() {
echo "Installs the latest (or a specific) version of jolt."
echo "Installation directory defaults to ${default_install_dir}."
echo
echo "Usage:"
echo " install [--dir <dir>] [--download-dir <dir>] [--version <version>] [--checksum <sha256>] [--repo <owner/name>]"
echo
echo "Defaults:"
echo " * Installation directory: \$PREFIX/bin if PREFIX is set;"
echo " otherwise /usr/local/bin when run as root, ~/.local/bin when not"
echo " * Download directory: a temporary directory"
echo " * Version: the latest release on GitHub ('nightly' is the rolling build of main)"
echo " * Checksum: fetched from the release and verified automatically"
echo " * Repo: jolt-lang/jolt, or \$JOLT_REPO (a fork's own nightly lives on the fork)"
exit 1
}
has() {
command -v "$1" >/dev/null 2>&1
}
fetch() {
local url=$1
local outfile=${2:-}
if has curl; then
if [[ -n $outfile ]]; then curl -fsSL "$url" -o "$outfile"; else curl -fsSL "$url"; fi
elif has wget; then
if [[ -n $outfile ]]; then wget -qO "$outfile" "$url"; else wget -qO - "$url"; fi
else
>&2 echo "Either 'curl' or 'wget' needs to be on PATH."
exit 1
fi
}
while [[ $# -gt 0 ]]; do
case "$1" in
--dir) install_dir="$2"; shift 2 ;;
--download-dir) download_dir="$2"; shift 2 ;;
--version) version="$2"; shift 2 ;;
--checksum) checksum="$2"; shift 2 ;;
--repo) repo="$2"; shift 2 ;;
--help|-h) print_help ;;
*) print_help ;;
esac
done
if [[ -z "$download_dir" ]]; then
download_dir="$(mktemp -d)"
trap 'rm -rf "$download_dir"' EXIT
fi
# --- resolve platform / arch to a release target -----------------------------
case "$(uname -s)" in
Linux*) platform=linux ;;
Darwin*) platform=macos ;;
*) >&2 echo "Unsupported OS: $(uname -s). Prebuilt binaries exist for Linux and macOS."; exit 1 ;;
esac
case "$(uname -m)" in
x86_64|amd64) arch=x86_64 ;;
aarch64|arm64) arch=aarch64 ;;
*) >&2 echo "Unsupported architecture: $(uname -m)."; exit 1 ;;
esac
target="${arch}-${platform}"
case "$target" in
x86_64-linux|aarch64-macos) ;;
x86_64-macos)
>&2 echo "No prebuilt jolt for Intel macOS (GitHub retired the Intel runner)."
>&2 echo "Build from source: https://github.com/${repo} (needs Chez Scheme + cc)."
exit 1 ;;
*) >&2 echo "No prebuilt jolt for ${target}."
>&2 echo "Available: x86_64-linux, aarch64-macos."
>&2 echo "Build from source: https://github.com/${repo} (make jolt-release)."
exit 1 ;;
esac
# --- resolve version ---------------------------------------------------------
if [[ -z "$version" ]]; then
# awk consumes the whole response: an early-exiting filter (grep -m1 /
# sed q / head) SIGPIPEs curl mid-stream, and under `set -o pipefail`
# curl's exit 23 kills the script before the download ever starts.
version="$(fetch "https://api.github.com/repos/${repo}/releases/latest" \
| awk -F'"' '/"tag_name"/ && !v { v=$4 } END { if (v) print v }')"
if [[ -z "$version" ]]; then
>&2 echo "Could not determine the latest release. Pass --version explicitly."
exit 1
fi
fi
tag="v${version#v}" # accept 0.1.0 or v0.1.0; the tag/asset carry the leading v
filename="jolt-${tag}-${target}.tar.gz"
download_url="https://github.com/${repo}/releases/download/${tag}/${filename}"
# releases up to v0.4.15 shipped the binary and archives under the old name
legacy_filename="joltc-${tag}-${target}.tar.gz"
legacy_url="https://github.com/${repo}/releases/download/${tag}/${legacy_filename}"
if has sha256sum; then
sha256sum_cmd="sha256sum"
elif has shasum; then
sha256sum_cmd="shasum -a 256"
else
sha256sum_cmd=""
fi
mkdir -p "$download_dir" && (
cd "$download_dir"
echo "Downloading ${download_url}"
if ! fetch "$download_url" "$filename"; then
echo "Not found; trying the pre-rename asset ${legacy_filename}"
download_url="$legacy_url"
filename="$legacy_filename"
fetch "$download_url" "$filename"
fi
# verify: an explicit --checksum wins; otherwise fetch the release's .sha256.
if [[ -z "$checksum" ]]; then
checksum="$(fetch "${download_url}.sha256" 2>/dev/null | cut -d' ' -f1 || true)"
fi
if [[ -n "$checksum" && -n "$sha256sum_cmd" ]]; then
got="$($sha256sum_cmd "$filename" | cut -d' ' -f1)"
if [[ "$got" != "$checksum" ]]; then
>&2 echo "Checksum mismatch on ${filename}"
>&2 echo " got: ${got}"
>&2 echo " expected: ${checksum}"
exit 1
fi
elif [[ -z "$sha256sum_cmd" ]]; then
>&2 echo "Note: no sha256sum/shasum on PATH; skipping checksum verification."
fi
tar -zxf "$filename"
rm -f "$filename"
)
# the tarball unpacks to a directory holding the binary (pre-rename releases
# used the joltc name for both)
extracted="${download_dir}/jolt-${tag}-${target}/jolt"
if [[ ! -f "$extracted" ]]; then
extracted="${download_dir}/joltc-${tag}-${target}/joltc"
fi
if [[ ! -f "$extracted" ]]; then
>&2 echo "Expected the jolt binary in the archive but it was not found."
exit 1
fi
mkdir -p "$install_dir"
if [[ -f "$install_dir/jolt" ]]; then
echo "Moving existing $install_dir/jolt to $install_dir/jolt.old"
mv -f "$install_dir/jolt" "$install_dir/jolt.old"
fi
mv -f "$extracted" "$install_dir/jolt"
chmod +x "$install_dir/jolt"
# verify the binary actually runs here — a glibc older than the build baseline
# fails with an opaque loader error, so diagnose it explicitly.
if ! run_err="$("$install_dir/jolt" --version 2>&1 >/dev/null)"; then
>&2 echo "The installed binary does not run on this system:"
>&2 echo " ${run_err}"
# A macOS build that was linked against a library the machine does not have
# (releases before jolt started baking lz4 in named Homebrew's
# liblz4.1.dylib, which only a Mac with `brew install lz4` carries).
if [[ "$run_err" == *"Library not loaded"* ]]; then
missing="$(printf '%s' "$run_err" | sed -nE 's/.*[Ll]ibrary not loaded: ([^ ]+).*/\1/p' | head -1)"
>&2 echo ""
>&2 echo "This build needs ${missing:-a library that is not installed here}."
>&2 echo "Install that library, or install a jolt that bakes it in:"
>&2 echo " brew install lz4 # if the missing library is liblz4"
fi
if [[ "$run_err" == *GLIBC_* ]]; then
need="$(printf '%s' "$run_err" | sed -nE "s/.*GLIBC_([0-9.]+).*/\1/p" | head -1)"
have="$(ldd --version 2>/dev/null | sed -nE '1s/.* ([0-9.]+)$/\1/p')"
>&2 echo ""
>&2 echo "The prebuilt jolt needs glibc ${need:-?} but this system has ${have:-?}."
>&2 echo "Either upgrade the OS, or build from source (needs Chez Scheme + cc):"
>&2 echo " git clone --recurse-submodules https://github.com/${repo} && cd jolt && make jolt-release"
fi
exit 1
fi
# clear the macOS quarantine flag so Gatekeeper doesn't block the fresh download
if [[ "$platform" == "macos" ]] && has xattr; then
xattr -d com.apple.quarantine "$install_dir/jolt" 2>/dev/null || true
fi
echo "Successfully installed jolt ${tag} to ${install_dir}/jolt"
if ! echo ":$PATH:" | grep -q ":${install_dir}:"; then
echo "Note: ${install_dir} is not on your PATH."
fi