f61b232e42
- Remove zellij_socktop_plugin/target from git (3,577 files committed by
accident in bf6ac87): the root .gitignore anchors /target to the repo
root, so the standalone plugin's own build dir wasn't covered. Ignore
target/ at any depth (also fixes the pre-existing
'/socktop-wasm-test/target' entry, which pointed at a hyphenated path
that doesn't exist).
- install.sh now updates EVERY copy of socktop/socktop_agent on PATH,
not just $PREFIX: a stale 'cargo install' in ~/.cargo/bin shadows
/usr/local/bin on most PATHs, so an install could 'succeed' while
'socktop --version' kept reporting the old release. Extra copies that
can't be written are warned about, not fatal, and the script now
prints which binary is actually active on PATH at the end.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
148 lines
5.7 KiB
Bash
Executable File
148 lines
5.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Build socktop + socktop_agent from source and install them.
|
|
#
|
|
# Works on Linux (x86_64, arm64/armv7, riscv64) and macOS. Handles fresh
|
|
# installs and upgrades; if a systemd socktop-agent service is present, its
|
|
# binary is replaced in place and the service restarted.
|
|
#
|
|
# ./scripts/install.sh # build HEAD of the repo you're in
|
|
# ./scripts/install.sh --ref v1.60.0 # build a tag/branch (clones if needed)
|
|
# ./scripts/install.sh --ref housekeeping-p2
|
|
# ./scripts/install.sh --prefix ~/.local/bin --no-service
|
|
#
|
|
set -euo pipefail
|
|
|
|
REPO_URL="https://github.com/jasonwitty/socktop.git"
|
|
REF=""
|
|
PREFIX=""
|
|
NO_SERVICE=0
|
|
SRC_DIR="${SOCKTOP_SRC_DIR:-$HOME/.cache/socktop-src}"
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--ref) REF="$2"; shift 2 ;;
|
|
--prefix) PREFIX="$2"; shift 2 ;;
|
|
--no-service) NO_SERVICE=1; shift ;;
|
|
-h|--help) grep '^#' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
|
*) echo "unknown argument: $1" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
say() { printf '\033[1;36m==>\033[0m %s\n' "$*"; }
|
|
warn() { printf '\033[1;33mwarn:\033[0m %s\n' "$*" >&2; }
|
|
die() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; }
|
|
|
|
OS="$(uname -s)"
|
|
ARCH="$(uname -m)"
|
|
|
|
# ---------- toolchain ----------
|
|
command -v git >/dev/null || die "git is required"
|
|
if ! command -v cargo >/dev/null; then
|
|
# rustup may be installed but not on PATH in this shell
|
|
[ -f "$HOME/.cargo/env" ] && . "$HOME/.cargo/env"
|
|
fi
|
|
if ! command -v cargo >/dev/null; then
|
|
say "Rust toolchain not found — installing via rustup (stable, default profile)"
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
|
|
. "$HOME/.cargo/env"
|
|
fi
|
|
command -v cc >/dev/null || warn "no C compiler found (apt: build-essential / brew: xcode-select --install) — the build may fail"
|
|
case "$ARCH" in
|
|
riscv64*)
|
|
# protoc-bin-vendored ships no riscv64 binary; the build falls back to
|
|
# the system protoc (see build.rs).
|
|
command -v protoc >/dev/null || die "riscv64 needs a system protoc: sudo apt install protobuf-compiler"
|
|
;;
|
|
esac
|
|
|
|
# ---------- source ----------
|
|
# If run from inside a socktop checkout and no --ref given, build that tree
|
|
# as-is (whatever is checked out, including local changes).
|
|
if [ -z "$REF" ] && git rev-parse --show-toplevel >/dev/null 2>&1 \
|
|
&& grep -qs '^name = "socktop"' "$(git rev-parse --show-toplevel)/socktop/Cargo.toml" 2>/dev/null; then
|
|
SRC_DIR="$(git rev-parse --show-toplevel)"
|
|
say "Building the current checkout: $SRC_DIR ($(git -C "$SRC_DIR" describe --always --dirty 2>/dev/null))"
|
|
else
|
|
REF="${REF:-master}"
|
|
if [ ! -d "$SRC_DIR/.git" ]; then
|
|
say "Cloning $REPO_URL -> $SRC_DIR"
|
|
git clone "$REPO_URL" "$SRC_DIR"
|
|
fi
|
|
say "Checking out $REF"
|
|
git -C "$SRC_DIR" fetch --tags origin
|
|
git -C "$SRC_DIR" checkout -q "$REF"
|
|
# fast-forward when REF is a branch
|
|
git -C "$SRC_DIR" merge --ff-only "origin/$REF" >/dev/null 2>&1 || true
|
|
fi
|
|
|
|
# ---------- build ----------
|
|
say "Building release binaries (this can take a while on SBCs)"
|
|
( cd "$SRC_DIR" && cargo build --release -p socktop -p socktop_agent )
|
|
CLIENT="$SRC_DIR/target/release/socktop"
|
|
AGENT="$SRC_DIR/target/release/socktop_agent"
|
|
|
|
# ---------- install ----------
|
|
if [ -z "$PREFIX" ]; then
|
|
PREFIX="/usr/local/bin"
|
|
fi
|
|
SUDO=""
|
|
if [ ! -w "$PREFIX" ]; then
|
|
if command -v sudo >/dev/null; then SUDO="sudo"; else
|
|
PREFIX="$HOME/.local/bin"; mkdir -p "$PREFIX"
|
|
warn "no sudo — installing to $PREFIX (ensure it is on your PATH)"
|
|
fi
|
|
fi
|
|
say "Installing to $PREFIX"
|
|
$SUDO install -m 755 "$CLIENT" "$PREFIX/socktop"
|
|
$SUDO install -m 755 "$AGENT" "$PREFIX/socktop_agent"
|
|
|
|
# Update every other copy on PATH as well. A stale `cargo install` in
|
|
# ~/.cargo/bin would otherwise SHADOW the fresh binary (~/.cargo/bin
|
|
# usually precedes /usr/local/bin on PATH), leaving `socktop --version`
|
|
# stuck on the old release after a "successful" install.
|
|
update_path_copies() {
|
|
local name="$1" src="$2" copy dir
|
|
# type -ap lists every match on PATH (bash builtin, symlinks not resolved)
|
|
for copy in $(type -ap "$name" | sort -u); do
|
|
[ "$copy" = "$PREFIX/$name" ] && continue
|
|
dir="$(dirname "$copy")"
|
|
say "Updating additional copy on PATH: $copy"
|
|
if [ -w "$copy" ] || [ -w "$dir" ]; then
|
|
install -m 755 "$src" "$copy"
|
|
else
|
|
# Non-fatal: an un-updatable extra copy shouldn't kill the install,
|
|
# but the user must know it may shadow the fresh binary.
|
|
$SUDO install -m 755 "$src" "$copy" || warn "could not update $copy — it may shadow $PREFIX/$name"
|
|
fi
|
|
done
|
|
}
|
|
update_path_copies socktop "$CLIENT"
|
|
update_path_copies socktop_agent "$AGENT"
|
|
|
|
# ---------- systemd service (Linux only) ----------
|
|
if [ "$OS" = "Linux" ] && [ "$NO_SERVICE" -eq 0 ] \
|
|
&& command -v systemctl >/dev/null \
|
|
&& systemctl list-unit-files 2>/dev/null | grep -q '^socktop-agent\.service'; then
|
|
# The deb package's unit points at its own binary path; replace it in place
|
|
# so the running service picks up this build.
|
|
UNIT_BIN="$(systemctl show -p ExecStart socktop-agent.service 2>/dev/null \
|
|
| sed -n 's/.*path=\([^ ;]*\).*/\1/p' | head -1)"
|
|
if [ -n "$UNIT_BIN" ] && [ "$UNIT_BIN" != "$PREFIX/socktop_agent" ]; then
|
|
say "Refreshing systemd service binary at $UNIT_BIN"
|
|
$SUDO systemctl stop socktop-agent.service
|
|
$SUDO install -m 755 "$AGENT" "$UNIT_BIN"
|
|
$SUDO systemctl start socktop-agent.service
|
|
else
|
|
say "Restarting socktop-agent.service"
|
|
$SUDO systemctl restart socktop-agent.service
|
|
fi
|
|
sleep 1
|
|
systemctl --no-pager -l status socktop-agent.service | head -5 || true
|
|
fi
|
|
|
|
say "Installed:"
|
|
"$PREFIX/socktop" --version
|
|
"$PREFIX/socktop_agent" --version
|
|
say "Active on PATH: $(type -p socktop || true) / $(type -p socktop_agent || true)"
|
|
socktop --version
|