返回 CodeWhale
install.sh
根目录 / scripts / release / install.sh
1 #!/usr/bin/env bash
2 set -euo pipefail
3 # CodeWhale Unix installer
4 # Copies codewhale, codew, and codewhale-tui to ~/.local/bin (or $PREFIX/bin)
5
6 PREFIX="${PREFIX:-$HOME/.local}"
7 BIN_DIR="${PREFIX}/bin"
8 SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
9
10 version_code() {
11 local version="$1"
12 local major minor patch
13 IFS=. read -r major minor patch <<< "$version"
14 printf '%d%03d%03d\n' "${major:-0}" "${minor:-0}" "${patch:-0}"
15 }
16
17 detect_host_glibc() {
18 local out
19 if out="$(getconf GNU_LIBC_VERSION 2>/dev/null)"; then
20 printf '%s\n' "$out" | awk '{print $NF; exit}'
21 return 0
22 fi
23 if out="$(ldd --version 2>&1 | head -n 1)"; then
24 printf '%s\n' "$out" | grep -Eo '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n 1
25 return 0
26 fi
27 return 1
28 }
29
30 required_glibc_for_binary() {
31 local bin="$1"
32 local versions
33 versions="$(grep -aoE 'GLIBC_[0-9]+\.[0-9]+(\.[0-9]+)?' "$bin" 2>/dev/null | sed 's/^GLIBC_//' || true)"
34 if [[ -z "$versions" ]]; then
35 return 1
36 fi
37 printf '%s\n' "$versions" | awk -F. '
38 {
39 patch = ($3 == "" ? 0 : $3)
40 code = ($1 * 1000000) + ($2 * 1000) + patch
41 if (code > best) {
42 best = code
43 value = $0
44 }
45 }
46 END {
47 if (value != "") print value
48 }
49 '
50 }
51
52 preflight_glibc() {
53 local bin="$1"
54 if [[ "$(uname -s)" != "Linux" ]]; then
55 return 0
56 fi
57 if [[ "${CODEWHALE_SKIP_GLIBC_CHECK:-}" == "1" || "${DEEPSEEK_TUI_SKIP_GLIBC_CHECK:-}" == "1" || "${DEEPSEEK_SKIP_GLIBC_CHECK:-}" == "1" ]]; then
58 return 0
59 fi
60
61 local required
62 if ! required="$(required_glibc_for_binary "$bin")" || [[ -z "$required" ]]; then
63 return 0
64 fi
65
66 local host
67 if ! host="$(detect_host_glibc)" || [[ -z "$host" ]]; then
68 echo "ERROR: $(basename "$bin") requires GLIBC_$required, but no GNU libc was detected." >&2
69 echo "Build from source instead: cargo install codewhale-cli --locked && cargo install codewhale-tui --locked" >&2
70 echo "Set CODEWHALE_SKIP_GLIBC_CHECK=1 to bypass this check at your own risk." >&2
71 return 1
72 fi
73
74 if [[ "$(version_code "$host")" -lt "$(version_code "$required")" ]]; then
75 echo "ERROR: $(basename "$bin") requires GLIBC_$required, but this system has glibc $host." >&2
76 echo "Ubuntu 22.04 ships glibc 2.35 and cannot run assets built against Ubuntu 24.04/glibc 2.39." >&2
77 echo "Build from source instead: cargo install codewhale-cli --locked && cargo install codewhale-tui --locked" >&2
78 echo "Release follow-up: build Linux GNU assets against an older glibc baseline or add a musl/static asset." >&2
79 echo "Set CODEWHALE_SKIP_GLIBC_CHECK=1 to bypass this check at your own risk." >&2
80 return 1
81 fi
82 }
83
84 mkdir -p "$BIN_DIR"
85
86 echo "Installing codewhale to $BIN_DIR ..."
87
88 install_binary() {
89 local src="$1"
90 local dst="$2"
91 local tmp="${dst}.tmp.$$"
92 rm -f "$tmp"
93 cp "$src" "$tmp"
94 chmod 0755 "$tmp"
95 mv -f "$tmp" "$dst"
96 }
97
98 for bin in codewhale codew codewhale-tui; do
99 src="$SCRIPT_DIR/$bin"
100 dst="$BIN_DIR/$bin"
101 if [[ ! -f "$src" ]]; then
102 echo "ERROR: $src not found in archive"
103 exit 1
104 fi
105 preflight_glibc "$src"
106 install_binary "$src" "$dst"
107 echo " $dst"
108 done
109
110 echo ""
111 echo "Done. Commands installed to $BIN_DIR."
112
113 # Check if BIN_DIR is on PATH
114 if [[ ":$PATH:" != *":$BIN_DIR:"* ]]; then
115 echo ""
116 echo "Add $BIN_DIR to your PATH:"
117 echo ""
118 SHELL_NAME="$(basename "${SHELL:-$SHELL}")"
119 case "$SHELL_NAME" in
120 zsh) RC="$HOME/.zshrc" ;;
121 bash) RC="$HOME/.bashrc" ;;
122 fish) RC="$HOME/.config/fish/config.fish" ;;
123 *) RC="your shell profile" ;;
124 esac
125 echo " echo 'export PATH=\"$BIN_DIR:\$PATH\"' >> $RC"
126 echo " source $RC"
127 fi
128
129 echo ""
130 echo "Then run: codewhale"
131
131 lines BASH