cargo build --quiet swallowed compiler errors, and the subshell (...) didn't reliably propagate exit codes across bash versions. The script continued past a failed build, then ls/cp failed on the missing binary. Now: removed --quiet so errors are visible, explicit exit-code check with common-cause hints (build-essential, libc6-dev), and a secondary check that the binary actually exists before attempting to install it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
124 lines
4.7 KiB
Bash
Executable File
124 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# install.sh — Build and install claude-statusline (Rust binary)
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
INSTALL_DIR="$HOME/.local/bin"
|
|
BINARY_NAME="claude-statusline"
|
|
CLAUDE_DIR="$HOME/.claude"
|
|
SETTINGS="$CLAUDE_DIR/settings.json"
|
|
|
|
echo "claude-statusline installer"
|
|
echo "==========================="
|
|
echo ""
|
|
|
|
# ── Check toolchain ──────────────────────────────────────────────────
|
|
if ! command -v cargo &>/dev/null; then
|
|
echo "ERROR: cargo (Rust toolchain) is required but not installed."
|
|
echo " Install via: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
|
|
exit 1
|
|
fi
|
|
echo "[ok] cargo found ($(cargo --version))"
|
|
|
|
if ! command -v jq &>/dev/null; then
|
|
echo "ERROR: jq is required for settings.json updates."
|
|
echo " macOS: brew install jq"
|
|
echo " Ubuntu: sudo apt install jq"
|
|
exit 1
|
|
fi
|
|
echo "[ok] jq found"
|
|
|
|
# ── Build release binary ─────────────────────────────────────────────
|
|
echo ""
|
|
echo "Building release binary..."
|
|
if ! (cd "$SCRIPT_DIR" && cargo build --release); then
|
|
echo ""
|
|
echo "ERROR: cargo build failed. Check the output above for details."
|
|
echo " Common causes:"
|
|
echo " - Missing C compiler: sudo apt install build-essential (Debian/Ubuntu)"
|
|
echo " - Missing libc headers: sudo apt install libc6-dev"
|
|
exit 1
|
|
fi
|
|
|
|
BINARY="$SCRIPT_DIR/target/release/$BINARY_NAME"
|
|
if [[ ! -f "$BINARY" ]]; then
|
|
echo "ERROR: Build succeeded but binary not found at $BINARY"
|
|
echo " Check: ls $SCRIPT_DIR/target/release/"
|
|
exit 1
|
|
fi
|
|
echo "[ok] Built: $(ls -lh "$BINARY" | awk '{print $5}')"
|
|
|
|
# ── Install binary ───────────────────────────────────────────────────
|
|
mkdir -p "$INSTALL_DIR"
|
|
cp "$BINARY" "$INSTALL_DIR/$BINARY_NAME"
|
|
chmod +x "$INSTALL_DIR/$BINARY_NAME"
|
|
echo "[ok] Installed to $INSTALL_DIR/$BINARY_NAME"
|
|
|
|
# Verify it's on PATH
|
|
if ! command -v "$BINARY_NAME" &>/dev/null; then
|
|
echo "[warn] $INSTALL_DIR is not on your PATH"
|
|
echo " Add to your shell config: export PATH=\"$INSTALL_DIR:\$PATH\""
|
|
fi
|
|
|
|
# ── Configure Claude Code settings.json ──────────────────────────────
|
|
echo ""
|
|
mkdir -p "$CLAUDE_DIR"
|
|
|
|
BINARY_PATH="$INSTALL_DIR/$BINARY_NAME"
|
|
|
|
# The binary runs in a non-TTY context, so force color on.
|
|
STATUSLINE_CMD="$BINARY_PATH --color=always"
|
|
|
|
if [[ -f "$SETTINGS" ]]; then
|
|
# Update existing settings.json
|
|
CURRENT_CMD=$(jq -r '.statusLine.command // empty' "$SETTINGS" 2>/dev/null || true)
|
|
if [[ -n "$CURRENT_CMD" ]]; then
|
|
echo "[info] Current statusLine command: $CURRENT_CMD"
|
|
fi
|
|
|
|
# Write updated settings
|
|
TMP="$SETTINGS.tmp.$$"
|
|
jq --arg cmd "$STATUSLINE_CMD" '.statusLine = {"type": "command", "command": $cmd, "padding": 0}' "$SETTINGS" > "$TMP"
|
|
mv "$TMP" "$SETTINGS"
|
|
echo "[ok] Updated statusLine in $SETTINGS"
|
|
else
|
|
# Create minimal settings.json
|
|
jq -n --arg cmd "$STATUSLINE_CMD" '{"statusLine": {"type": "command", "command": $cmd, "padding": 0}}' > "$SETTINGS"
|
|
echo "[ok] Created $SETTINGS"
|
|
fi
|
|
|
|
# ── Symlink config ───────────────────────────────────────────────────
|
|
CONFIG_SRC="$SCRIPT_DIR/statusline.json"
|
|
CONFIG_DST="$CLAUDE_DIR/statusline.json"
|
|
|
|
if [[ -f "$CONFIG_SRC" ]]; then
|
|
if [[ -L "$CONFIG_DST" ]]; then
|
|
EXISTING="$(readlink "$CONFIG_DST")"
|
|
if [[ "$EXISTING" == "$CONFIG_SRC" ]]; then
|
|
echo "[ok] Config already linked"
|
|
else
|
|
ln -sf "$CONFIG_SRC" "$CONFIG_DST"
|
|
echo "[ok] Config symlink updated (was: $EXISTING)"
|
|
fi
|
|
elif [[ -f "$CONFIG_DST" ]]; then
|
|
echo "[skip] $CONFIG_DST exists as a regular file"
|
|
echo " To use the symlink, remove it first: rm $CONFIG_DST"
|
|
else
|
|
ln -s "$CONFIG_SRC" "$CONFIG_DST"
|
|
echo "[ok] Config linked: $CONFIG_DST -> $CONFIG_SRC"
|
|
fi
|
|
else
|
|
echo "[info] No statusline.json in project. To customize, create:"
|
|
echo " $CONFIG_SRC"
|
|
echo ""
|
|
echo " Print defaults: $BINARY_NAME --print-defaults"
|
|
echo " Print schema: $BINARY_NAME --config-schema"
|
|
fi
|
|
|
|
# ── Done ─────────────────────────────────────────────────────────────
|
|
echo ""
|
|
echo "Done. Restart Claude Code to see the status line."
|
|
echo ""
|
|
echo "Quick test: $BINARY_NAME --test --color=always"
|
|
echo "Debug: $BINARY_NAME --test --dump-state=json"
|