1#!/usr/bin/env bash
2set -euo pipefail
3ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
4source "$ROOT/lib.sh"
5
6need_cmd brew
7
8#──────────────────────────────────────────────────────────────
9# STATE: Formulae to install
10#──────────────────────────────────────────────────────────────
11FORMULAE=(
12 bash
13 bash-completion@2
14 curl
15 git
16 neovim
17 trash
18 mise
19 direnv
20 protonpass/tap/pass-cli
21 ripgrep
22 fd
23 git-delta
24 eza
25 stow
26 starship
27 anomalyco/tap/opencode
28 jq
29 gum
30 viu
31 podman
32 podman-compose
33 ffmpeg
34 ramonvermeulen/whosthere/whosthere
35)
36
37#──────────────────────────────────────────────────────────────
38# LOGIC: Idempotent convergence (strict mode)
39#──────────────────────────────────────────────────────────────
40
41log "Updating Homebrew"
42brew update
43brew upgrade || true
44
45log "Syncing formulae (strict mode)"
46
47# Get currently installed (only explicitly requested)
48mapfile -t installed < <(brew list --formula --installed-on-request 2>/dev/null || true)
49
50# Install missing
51for formula in "${FORMULAE[@]}"; do
52 name="${formula##*/}"
53 if ! brew list --formula "$name" &>/dev/null; then
54 log "Installing: $formula"
55 brew install "$formula"
56 else
57 log "Already installed: $name"
58 fi
59done
60
61# Remove extras (strict convergence)
62for pkg in "${installed[@]}"; do
63 [[ -z "$pkg" ]] && continue
64 keep=false
65 for formula in "${FORMULAE[@]}"; do
66 [[ "${formula##*/}" == "$pkg" ]] && keep=true && break
67 done
68 if [[ "$keep" == "false" ]]; then
69 log "Removing: $pkg (not in state)"
70 brew uninstall "$pkg"
71 fi
72done
73
74brew cleanup
75log "Formulae synced"
76
77# Configure Podman as Docker replacement
78if command -v podman &>/dev/null; then
79 log "Creating Docker symlink for Podman"
80 sudo ln -sf "$(which podman)" /usr/local/bin/docker
81 log "Docker symlink created"
82fi