-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·100 lines (80 loc) · 3.3 KB
/
install.sh
File metadata and controls
executable file
·100 lines (80 loc) · 3.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
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
#!/usr/bin/env bash
# install.sh — download and install the latest craftops release binary.
# Usage: curl -fsSL https://raw.githubusercontent.com/dacrab/craftops/main/install.sh | bash
# VERSION=v2.3.0 bash install.sh # pin a specific version
set -euo pipefail
REPO="dacrab/craftops"
NAME="craftops"
# Install to user bin by default; /usr/local/bin when running as root.
if [ "$(id -u)" -eq 0 ]; then
DEST="/usr/local/bin"
else
DEST="${HOME}/.local/bin"
fi
die() { printf 'Error: %s\n' "$1" >&2; exit 1; }
# ---- OS / arch detection -----------------------------------------------------
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
case "$OS" in
linux|darwin) ;;
*) die "Unsupported OS: $OS" ;;
esac
ARCH=$(uname -m)
case "$ARCH" in
x86_64|amd64) ARCH=amd64 ;;
arm64|aarch64) ARCH=arm64 ;;
*) die "Unsupported architecture: $ARCH" ;;
esac
# ---- Resolve version ---------------------------------------------------------
if [ -z "${VERSION:-}" ]; then
printf 'Checking latest version...\n'
# Parse tag_name from GitHub API response without relying on jq
VERSION=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" \
| grep '"tag_name"' \
| head -1 \
| sed 's/.*"tag_name": *"\([^"]*\)".*/\1/')
fi
[ -n "$VERSION" ] || die "Failed to determine latest version"
# ---- Download ----------------------------------------------------------------
BASE_URL="https://github.com/${REPO}/releases/download/${VERSION}"
BINARY_URL="${BASE_URL}/${NAME}-${OS}-${ARCH}"
SUMS_URL="${BASE_URL}/SHA256SUMS"
printf 'Installing %s %s (%s/%s) → %s\n' "$NAME" "$VERSION" "$OS" "$ARCH" "$DEST"
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
TMPBIN="${TMPDIR}/${NAME}"
TMPSUMS="${TMPDIR}/SHA256SUMS"
curl -fsSL -o "$TMPBIN" "$BINARY_URL" || die "Download failed: $BINARY_URL"
curl -fsSL -o "$TMPSUMS" "$SUMS_URL" || die "Download failed: $SUMS_URL"
# ---- Verify checksum ---------------------------------------------------------
EXPECTED=$(grep "${NAME}-${OS}-${ARCH}" "$TMPSUMS" | awk '{print $1}')
[ -n "$EXPECTED" ] || die "Checksum not found for ${NAME}-${OS}-${ARCH}"
if command -v sha256sum > /dev/null 2>&1; then
ACTUAL=$(sha256sum "$TMPBIN" | awk '{print $1}')
elif command -v shasum > /dev/null 2>&1; then
ACTUAL=$(shasum -a 256 "$TMPBIN" | awk '{print $1}')
else
die "Neither sha256sum nor shasum found — cannot verify download"
fi
[ "$ACTUAL" = "$EXPECTED" ] || die "Checksum mismatch (expected $EXPECTED, got $ACTUAL)"
# ---- Install -----------------------------------------------------------------
chmod +x "$TMPBIN"
mkdir -p "$DEST"
if [ -w "$DEST" ]; then
mv "$TMPBIN" "${DEST}/${NAME}"
else
sudo mv "$TMPBIN" "${DEST}/${NAME}"
fi
printf 'Installed to %s/%s\n' "$DEST" "$NAME"
# ---- Warn if DEST is not in PATH ---------------------------------------------
case ":${PATH}:" in
*":${DEST}:"*) ;;
*) printf "Warning: %s is not in your PATH. Add it with:\n export PATH=\"%s:\$PATH\"\n" "$DEST" "$DEST" ;;
esac
# ---- Optional: create default config -----------------------------------------
CFG="${HOME}/.config/craftops/config.toml"
if [ ! -f "$CFG" ]; then
printf 'Creating default config at %s...\n' "$CFG"
mkdir -p "$(dirname "$CFG")"
"${DEST}/${NAME}" init-config -o "$CFG" > /dev/null 2>&1 || true
fi
printf 'Done. Run '\''%s --help'\'' to get started.\n' "$NAME"