146 lines
4.2 KiB
Bash
146 lines
4.2 KiB
Bash
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
|
MANIFEST="$REPO_ROOT/Bins/versions.json"
|
|
TARGET_DIR="$HOME/.local/bin"
|
|
|
|
ensure_deps() {
|
|
local missing=()
|
|
|
|
for cmd in jq curl tar; do
|
|
if ! command -v "$cmd" >/dev/null 2>&1; then
|
|
missing+=("$cmd")
|
|
fi
|
|
done
|
|
|
|
if [ "${#missing[@]}" -gt 0 ]; then
|
|
printf 'Missing required commands: %s\n' "${missing[*]}" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
detect_platform() {
|
|
case "$(uname -s)" in
|
|
Linux) printf 'linux\n' ;;
|
|
Darwin) printf 'macos\n' ;;
|
|
*)
|
|
printf 'Unsupported operating system: %s\n' "$(uname -s)" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
detect_arch() {
|
|
case "$(uname -m)" in
|
|
x86_64) printf 'x86_64\n' ;;
|
|
aarch64|arm64) printf 'aarch64\n' ;;
|
|
*)
|
|
printf 'Unsupported architecture: %s\n' "$(uname -m)" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
install_tool() {
|
|
local tool="$1"
|
|
local platform arch version owner repo asset binary_rel formula url tmp_dir archive_path extracted_path target_path installed_path formula_prefix
|
|
|
|
platform="$(detect_platform)"
|
|
arch="$(detect_arch)"
|
|
|
|
if ! jq -e --arg tool "$tool" '.[$tool]' "$MANIFEST" >/dev/null; then
|
|
printf 'Unsupported tool: %s\n' "$tool" >&2
|
|
exit 1
|
|
fi
|
|
|
|
version="$(jq -r --arg tool "$tool" '.[$tool].version' "$MANIFEST")"
|
|
owner="$(jq -r --arg tool "$tool" '.[$tool].owner' "$MANIFEST")"
|
|
repo="$(jq -r --arg tool "$tool" '.[$tool].repo' "$MANIFEST")"
|
|
formula="$(jq -r --arg tool "$tool" --arg platform "$platform" '.[$tool][$platform].formula // empty' "$MANIFEST")"
|
|
|
|
if [ -n "$formula" ]; then
|
|
if ! command -v brew >/dev/null 2>&1; then
|
|
printf 'Homebrew is required to install %s on macOS\n' "$tool" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! brew list --formula "$formula" >/dev/null 2>&1; then
|
|
printf 'Installing %s via Homebrew formula %s\n' "$tool" "$formula"
|
|
brew install "$formula"
|
|
else
|
|
printf '%s already installed via Homebrew\n' "$tool"
|
|
fi
|
|
|
|
formula_prefix="$(brew --prefix "$formula" 2>/dev/null || true)"
|
|
if [ -n "$formula_prefix" ] && [ -x "$formula_prefix/bin/$tool" ]; then
|
|
installed_path="$formula_prefix/bin/$tool"
|
|
else
|
|
installed_path="$(command -v "$tool" || true)"
|
|
fi
|
|
|
|
if [ -z "$installed_path" ]; then
|
|
printf 'Installed formula %s but %s is not on PATH\n' "$formula" "$tool" >&2
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p "$TARGET_DIR"
|
|
target_path="$TARGET_DIR/$tool"
|
|
ln -sf "$installed_path" "$target_path"
|
|
printf 'Linked %s -> %s\n' "$target_path" "$installed_path"
|
|
return 0
|
|
fi
|
|
|
|
asset="$(jq -r --arg tool "$tool" --arg platform "$platform" --arg arch "$arch" '.[$tool][$platform][$arch].asset // empty' "$MANIFEST")"
|
|
binary_rel="$(jq -r --arg tool "$tool" --arg platform "$platform" --arg arch "$arch" '.[$tool][$platform][$arch].binary // empty' "$MANIFEST")"
|
|
|
|
if [ -z "$asset" ] || [ -z "$binary_rel" ]; then
|
|
printf 'No %s asset mapping for %s on %s\n' "$platform" "$tool" "$arch" >&2
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p "$TARGET_DIR"
|
|
tmp_dir="$(mktemp -d)"
|
|
archive_path="$tmp_dir/$asset"
|
|
url="https://github.com/$owner/$repo/releases/download/$version/$asset"
|
|
|
|
printf 'Installing %s %s\n' "$tool" "$version"
|
|
curl -fL "$url" -o "$archive_path"
|
|
tar -xzf "$archive_path" -C "$tmp_dir"
|
|
|
|
extracted_path="$tmp_dir/$binary_rel"
|
|
if [ ! -f "$extracted_path" ]; then
|
|
printf 'Expected binary not found after extraction: %s\n' "$binary_rel" >&2
|
|
rm -rf "$tmp_dir"
|
|
exit 1
|
|
fi
|
|
|
|
target_path="$TARGET_DIR/$tool"
|
|
install -m 755 "$extracted_path" "$target_path"
|
|
rm -rf "$tmp_dir"
|
|
|
|
printf 'Installed %s -> %s\n' "$tool" "$target_path"
|
|
}
|
|
|
|
main() {
|
|
ensure_deps
|
|
|
|
if [ "${1:-}" = "--all" ]; then
|
|
while IFS= read -r tool; do
|
|
install_tool "$tool"
|
|
done < <(jq -r 'keys[]' "$MANIFEST")
|
|
exit 0
|
|
fi
|
|
|
|
if [ -z "${1:-}" ]; then
|
|
printf 'Usage: %s [--all|tool]\n' "$0" >&2
|
|
exit 1
|
|
fi
|
|
|
|
install_tool "$1"
|
|
}
|
|
|
|
main "$@"
|