Repository navigation
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·341 lines (311 loc) · 13 KB
/
Copy pathsetup.sh
File metadata and controls
executable file
·341 lines (311 loc) · 13 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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
#!/bin/sh
# SPDX-License-Identifier: MPL-2.0
# setup.sh — Universal setup script for rsr-template-repo
#
# Detects your shell, platform, and installs prerequisites.
# Then hands off to `just setup` for project-specific configuration.
#
# Usage:
# ./setup.sh # after cloning — read it first; never pipe a fetched script into a shell
#
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath)
set -eu
# ── Colours (safe — uses symbols too per ADJUST contractile) ──
if [ -t 1 ] && command -v tput >/dev/null 2>&1; then
RED=$(tput setaf 1 2>/dev/null || true)
GREEN=$(tput setaf 2 2>/dev/null || true)
YELLOW=$(tput setaf 3 2>/dev/null || true)
CYAN=$(tput setaf 6 2>/dev/null || true)
BOLD=$(tput bold 2>/dev/null || true)
RESET=$(tput sgr0 2>/dev/null || true)
else
RED="" GREEN="" YELLOW="" CYAN="" BOLD="" RESET=""
fi
ok() { printf " %s[OK]%s %s\n" "$GREEN" "$RESET" "$1"; }
fail() { printf " %s[FAIL]%s %s\n" "$RED" "$RESET" "$1"; }
warn() { printf " %s[WARN]%s %s\n" "$YELLOW" "$RESET" "$1"; }
info() { printf " %s[INFO]%s %s\n" "$CYAN" "$RESET" "$1"; }
# ── Shell Detection ──
detect_shell() {
# Check the actual running shell, not just $SHELL
CURRENT_SHELL="unknown"
if [ -n "${BASH_VERSION:-}" ]; then CURRENT_SHELL="bash"
elif [ -n "${ZSH_VERSION:-}" ]; then CURRENT_SHELL="zsh"
elif [ -n "${FISH_VERSION:-}" ]; then CURRENT_SHELL="fish"
elif [ -n "${KSH_VERSION:-}" ]; then CURRENT_SHELL="ksh"
# Check by process name for shells that don't set version vars
elif command -v ps >/dev/null 2>&1; then
SHELL_PROC=$(ps -p $$ -o comm= 2>/dev/null || echo "unknown")
case "$SHELL_PROC" in
*dash*) CURRENT_SHELL="dash" ;;
*tcsh*) CURRENT_SHELL="tcsh" ;;
*csh*) CURRENT_SHELL="csh" ;;
*elvish*) CURRENT_SHELL="elvish" ;;
*nu*) CURRENT_SHELL="nushell" ;;
*oil*|*osh*) CURRENT_SHELL="oil" ;;
*xonsh*) CURRENT_SHELL="xonsh" ;;
*murex*) CURRENT_SHELL="murex" ;;
*ion*) CURRENT_SHELL="ion" ;;
*hilbish*) CURRENT_SHELL="hilbish" ;;
*oh*) CURRENT_SHELL="oh" ;;
*vsh*) CURRENT_SHELL="vsh" ;;
*pwsh*|*powershell*) CURRENT_SHELL="powershell" ;;
esac
fi
# Fallback: check $SHELL env var
if [ "$CURRENT_SHELL" = "unknown" ] && [ -n "${SHELL:-}" ]; then
case "$SHELL" in
*/bash) CURRENT_SHELL="bash" ;;
*/zsh) CURRENT_SHELL="zsh" ;;
*/fish) CURRENT_SHELL="fish" ;;
*/dash) CURRENT_SHELL="dash" ;;
*/ksh*) CURRENT_SHELL="ksh" ;;
*/tcsh) CURRENT_SHELL="tcsh" ;;
*/csh) CURRENT_SHELL="csh" ;;
*/vsh) CURRENT_SHELL="vsh" ;;
esac
fi
printf "%s" "$CURRENT_SHELL"
}
# ── Platform Detection ──
detect_platform() {
OS="unknown"
DISTRO="unknown"
PKG_MGR="unknown"
ARCH=$(uname -m 2>/dev/null || echo "unknown")
case "$(uname -s 2>/dev/null)" in
Linux*)
OS="linux"
if [ -f /etc/os-release ]; then
DISTRO=$(. /etc/os-release && echo "$ID")
elif [ -f /etc/redhat-release ]; then
DISTRO="rhel"
elif [ -f /etc/debian_version ]; then
DISTRO="debian"
fi
# Detect package manager
if command -v dnf >/dev/null 2>&1; then PKG_MGR="dnf"
elif command -v apt-get >/dev/null 2>&1; then PKG_MGR="apt"
elif command -v pacman >/dev/null 2>&1; then PKG_MGR="pacman"
elif command -v apk >/dev/null 2>&1; then PKG_MGR="apk"
elif command -v zypper >/dev/null 2>&1; then PKG_MGR="zypper"
elif command -v rpm-ostree >/dev/null 2>&1; then PKG_MGR="rpm-ostree"
elif command -v guix >/dev/null 2>&1; then PKG_MGR="guix"
elif command -v nix >/dev/null 2>&1; then PKG_MGR="nix"
fi
;;
Darwin*)
OS="macos"
DISTRO="macos"
if command -v brew >/dev/null 2>&1; then PKG_MGR="brew"
elif command -v port >/dev/null 2>&1; then PKG_MGR="macports"
fi
;;
CYGWIN*|MINGW*|MSYS*)
OS="windows"
DISTRO="msys"
if command -v winget >/dev/null 2>&1; then PKG_MGR="winget"
elif command -v scoop >/dev/null 2>&1; then PKG_MGR="scoop"
elif command -v choco >/dev/null 2>&1; then PKG_MGR="choco"
fi
;;
FreeBSD*)
OS="freebsd"
DISTRO="freebsd"
PKG_MGR="pkg"
;;
esac
}
# ── Verified just install ──
# Replaces `curl https://just.systems/install.sh | bash`: piping a remote script
# into a shell runs whatever the server returns, with no chance to check it.
# A pinned RELEASE BINARY is fetched instead and its digest checked before use
# (ported from hyperpolymath/standards setup.sh, 3079bc12). Digests computed
# 2026-08-07; casey/just publishes none, so this is trust-on-first-use — any
# later substitution fails loudly. An unrecognised platform returns failure
# rather than fetching a plausible-looking binary for the wrong target.
JUST_VERSION="1.58.0"
# Print the just release target for the current OS and architecture.
# Takes no arguments; prints an empty line for unsupported platforms.
just_target() {
case "$(uname -s 2>/dev/null):$(uname -m 2>/dev/null)" in
Linux:x86_64|Linux:amd64) echo "x86_64-unknown-linux-musl" ;;
Linux:aarch64|Linux:arm64) echo "aarch64-unknown-linux-musl" ;;
Darwin:x86_64) echo "x86_64-apple-darwin" ;;
Darwin:arm64|Darwin:aarch64) echo "aarch64-apple-darwin" ;;
*) echo "" ;;
esac
}
# Print the pinned archive SHA-256 for the release target passed as $1.
# Prints an empty line if the target has no known digest for JUST_VERSION.
just_sha256() {
case "$1" in
x86_64-unknown-linux-musl) echo "4a5cc2f53e6f0f8c59092a6cc38291eb729d46a7dd95d3ae582008881b84931d" ;;
aarch64-unknown-linux-musl) echo "748237128c4c40cbdabc65e841d05ceba13cc23a91eaba395495894c1d9764df" ;;
x86_64-apple-darwin) echo "9a09cfef66aaa79da58203970103a0684307716caaabd3e9844cacc4dc0f4023" ;;
aarch64-apple-darwin) echo "50ae3e996c974a0bf32ea7d10f495070df33f1b43e0616b2769e3d4821ed8f48" ;;
*) echo "" ;;
esac
}
# sha256sum is GNU; macOS ships shasum instead.
sha256_of() {
if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | cut -d" " -f1
else shasum -a 256 "$1" | cut -d" " -f1
fi
}
# Download JUST_VERSION for the current platform and verify its pinned digest
# before installing to /usr/local/bin/just with sudo. Takes no arguments.
# Returns nonzero for an unsupported platform, download or checksum failure,
# or failed extraction or installation; removes the temporary download directory.
install_just_verified() {
jv_target="$(just_target)"
[ -z "$jv_target" ] && { fail "just: no verified build for $(uname -s)/$(uname -m); use your package manager"; return 1; }
jv_want="$(just_sha256 "$jv_target")"
jv_tmp="$(mktemp -d)"
jv_url="https://github.com/casey/just/releases/download/${JUST_VERSION}/just-${JUST_VERSION}-${jv_target}.tar.gz"
curl -fsSL --proto '=https' --tlsv1.2 -o "$jv_tmp/just.tar.gz" "$jv_url" || { rm -rf "$jv_tmp"; return 1; }
jv_got="$(sha256_of "$jv_tmp/just.tar.gz")"
if [ "$jv_got" != "$jv_want" ]; then
fail "just: CHECKSUM MISMATCH for $jv_url (expected $jv_want, got $jv_got)"
rm -rf "$jv_tmp"
return 1
fi
tar -xzf "$jv_tmp/just.tar.gz" -C "$jv_tmp" just \
&& sudo install -m 0755 "$jv_tmp/just" /usr/local/bin/just
jv_rc=$?
rm -rf "$jv_tmp"
return "$jv_rc"
}
# ── Install just ──
install_just() {
if command -v just >/dev/null 2>&1; then
ok "just already installed: $(just --version 2>/dev/null | head -1)"
return 0
fi
info "Installing just (task runner)..."
case "$PKG_MGR" in
dnf) sudo dnf install -y just ;;
apt) sudo apt-get install -y just 2>/dev/null || {
# just not in older apt repos — use the verified release binary
install_just_verified
} ;;
pacman) sudo pacman -S --noconfirm just ;;
apk) sudo apk add just ;;
brew) brew install just ;;
scoop) scoop install just ;;
winget) winget install Casey.Just ;;
rpm-ostree) sudo rpm-ostree install just ;;
guix) guix install just ;;
nix) nix-env -iA nixpkgs.just ;;
*)
info "Installing verified just release..."
install_just_verified
;;
esac
if command -v just >/dev/null 2>&1; then
ok "just installed: $(just --version 2>/dev/null | head -1)"
else
fail "Could not install just. Install manually: https://just.systems/"
return 1
fi
}
# ── Main ──
main() {
printf "%s=== rsr-template-repo Setup ===%s\n\n" "$BOLD" "$RESET"
# Detect environment
SHELL_NAME=$(detect_shell)
detect_platform
info "Shell: $SHELL_NAME"
info "Platform: $OS ($DISTRO)"
info "Arch: $ARCH"
info "Packages: $PKG_MGR"
printf "\n"
# Warn about exotic shells
case "$SHELL_NAME" in
vsh)
info "Valence Shell detected — experimental support"
info "Falling back to POSIX sh for setup, vsh for post-setup"
;;
nushell|elvish|murex|ion|hilbish|oil|xonsh|oh)
info "$SHELL_NAME detected — using POSIX sh for setup"
;;
esac
# Step 1: Install just
printf "%sStep 1: Install task runner%s\n" "$BOLD" "$RESET"
install_just || { fail "Cannot proceed without just"; exit 1; }
printf "\n"
# Step 2: Check if we're in the repo directory
if [ ! -f "Justfile" ] && [ ! -f "justfile" ]; then
warn "Not in a repo directory (no Justfile found)"
info "Clone first: git clone https://github.com/hyperpolymath/rsr-template-repo.git"
info "Then: cd rsr-template-repo && ./setup.sh"
exit 1
fi
# Step 3: Run just setup
printf "%sStep 2: Project setup%s\n" "$BOLD" "$RESET"
if just --list 2>/dev/null | grep -q "^setup "; then
just setup
elif just --list 2>/dev/null | grep -q "^setup-dev "; then
just setup-dev
else
warn "No 'setup' recipe in Justfile — running 'just doctor' instead"
just doctor 2>/dev/null || true
fi
printf "\n"
# Step 4: Post-install security snapshot
printf "%sStep 3: Security snapshot%s\n" "$BOLD" "$RESET"
if command -v firewall-cmd >/dev/null 2>&1; then
if firewall-cmd --state 2>/dev/null | grep -q running; then
ok "Firewall: firewalld active"
else
warn "Firewall: firewalld installed but not running"
info " Enable: sudo systemctl enable --now firewalld"
fi
elif command -v ufw >/dev/null 2>&1; then
if ufw status 2>/dev/null | grep -q "Status: active"; then
ok "Firewall: ufw active"
else
warn "Firewall: ufw installed but not active"
info " Enable: sudo ufw enable"
fi
else
warn "Firewall: none detected"
case "$PKG_MGR" in
dnf|rpm-ostree) info " Install: sudo dnf install firewalld && sudo systemctl enable --now firewalld" ;;
apt) info " Install: sudo apt install ufw && sudo ufw enable" ;;
*) info " Install a firewall for your platform" ;;
esac
fi
if command -v getenforce >/dev/null 2>&1; then
SE_STATUS=$(getenforce 2>/dev/null || echo "unknown")
case "$SE_STATUS" in
Enforcing) ok "SELinux: Enforcing" ;;
Permissive) warn "SELinux: Permissive (recommend Enforcing: sudo setenforce 1)" ;;
*) warn "SELinux: $SE_STATUS" ;;
esac
fi
# Write report
REPORT_FILE="INSTALL-SECURITY-REPORT.adoc"
{
printf "// SPDX-License-Identifier: MPL-2.0\n"
printf "= Install Security Report\n"
printf ":date: %s\n\n" "$(date -Iseconds 2>/dev/null || date)"
printf "== Platform\n"
printf "* OS: %s (%s)\n" "$OS" "$DISTRO"
printf "* Arch: %s\n" "$ARCH"
printf "* Package manager: %s\n" "$PKG_MGR"
printf "* Shell: %s\n\n" "$SHELL_NAME"
printf "== Security Status\n"
printf "Run \`just doctor\` for full diagnostic.\n"
} > "$REPORT_FILE"
info "Security report: $REPORT_FILE"
printf "\n"
# Done
printf "%s=== Setup Complete ===%s\n\n" "${BOLD}${GREEN}" "$RESET"
printf "Next steps:\n"
printf " just doctor — verify everything works\n"
printf " just tour — guided tour of the project\n"
printf " just build — build the project\n"
printf " just help-me — get help if stuck\n"
}
main "$@"