Files
mcpctl/installlocal.sh
Michal 292506ec98 fix(install): rebuild when any packaged input changes, not just src/*.ts
installlocal.sh decided the package was up to date by looking only for
`src/**/*.ts` newer than it. nfpm.yaml also packages stack/claude-vllm, the
shell completions and the systemd unit — none of which are TypeScript — so
editing any of those installed a stale package that reported success. Caught by
claude-vllm's new --init being absent from /usr/bin after a clean install.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-09 20:07:55 +01:00

87 lines
2.9 KiB
Bash
Executable File

#!/bin/bash
# Build (if needed) and install mcpctl locally.
# Auto-detects package format: RPM for Fedora/RHEL, DEB for Debian/Ubuntu.
#
# Usage:
# ./installlocal.sh # Build and install for native arch
# MCPCTL_TARGET_ARCH=amd64 ./installlocal.sh # Cross-compile for amd64
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Resolve target architecture
source scripts/arch-helper.sh
resolve_arch "${MCPCTL_TARGET_ARCH:-}"
# Detect package format
if command -v rpm &>/dev/null && command -v dnf &>/dev/null; then
PKG_FORMAT="rpm"
elif command -v dpkg &>/dev/null && command -v apt &>/dev/null; then
PKG_FORMAT="deb"
elif command -v rpm &>/dev/null; then
PKG_FORMAT="rpm"
else
echo "Error: Neither rpm/dnf nor dpkg/apt found. Unsupported system."
exit 1
fi
echo "==> Detected package format: $PKG_FORMAT (arch: $NFPM_ARCH)"
# Any packaged input newer than $1. Mirrors nfpm.yaml's `contents:` — keep the
# two in step, or the build silently serves a stale binary again.
newer_inputs() {
find src/ -name '*.ts' -newer "$1" 2>/dev/null | head -1
find stack/ completions/ deploy/ -type f -newer "$1" 2>/dev/null | head -1
find nfpm.yaml -newer "$1" 2>/dev/null | head -1
}
# Find package matching the target architecture
# RPM uses x86_64/aarch64, DEB uses amd64/arm64
find_pkg() {
local pattern="$1"
ls $pattern 2>/dev/null | grep -E "[._](${NFPM_ARCH}|${RPM_ARCH})[._]" | head -1
}
if [ "$PKG_FORMAT" = "rpm" ]; then
PKG_FILE=$(find_pkg "dist/mcpctl-*.rpm")
# Build if no package exists or if any PACKAGED input is newer.
# Watching only src/*.ts silently shipped a stale package whenever a
# non-TypeScript artifact changed — stack/claude-vllm, the completions, the
# systemd unit are all in nfpm.yaml's contents and none of them are .ts.
if [[ -z "$PKG_FILE" ]] || [[ $(newer_inputs "$PKG_FILE") ]]; then
echo "==> Building RPM..."
bash scripts/build-rpm.sh
PKG_FILE=$(find_pkg "dist/mcpctl-*.rpm")
else
echo "==> RPM is up to date: $PKG_FILE"
fi
echo "==> Installing $PKG_FILE..."
sudo rpm -Uvh --force "$PKG_FILE"
else
PKG_FILE=$(find_pkg "dist/mcpctl*.deb")
# Build if no package exists or if any PACKAGED input is newer.
# Watching only src/*.ts silently shipped a stale package whenever a
# non-TypeScript artifact changed — stack/claude-vllm, the completions, the
# systemd unit are all in nfpm.yaml's contents and none of them are .ts.
if [[ -z "$PKG_FILE" ]] || [[ $(newer_inputs "$PKG_FILE") ]]; then
echo "==> Building DEB..."
bash scripts/build-deb.sh
PKG_FILE=$(find_pkg "dist/mcpctl*.deb")
else
echo "==> DEB is up to date: $PKG_FILE"
fi
echo "==> Installing $PKG_FILE..."
sudo dpkg -i "$PKG_FILE" || sudo apt-get install -f -y
fi
echo "==> Reloading systemd user units..."
systemctl --user daemon-reload
echo "==> Done!"
echo " Enable mcplocal: systemctl --user enable --now mcplocal"