#!/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 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 installed_path="$(command -v "$tool" || true)" 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 "$@"