[bin] Cleaning up bootstrap and setup scripts

This commit is contained in:
2026-02-27 17:17:08 -05:00
parent dc5912e23d
commit 3ecaa8b389
2 changed files with 293 additions and 277 deletions

View File

@ -9,151 +9,151 @@ PLATFORM=""
# -------- OS detection --------
if [[ "$OS" == "Darwin" ]]; then
PLATFORM="macos"
PLATFORM="macos"
elif [[ "$OS" == "FreeBSD" ]]; then
PLATFORM="freebsd"
PLATFORM="freebsd"
elif [[ "$OS" == "Linux" ]]; then
if [[ -r /etc/os-release ]]; then
# shellcheck disable=SC1091
. /etc/os-release
fi
if [[ -r /etc/os-release ]]; then
# shellcheck disable=SC1091
. /etc/os-release
fi
is_arch=0
case "${ID:-}" in
arch | endeavouros) is_arch=1 ;;
esac
if [[ $is_arch -eq 0 && -n "${ID_LIKE:-}" ]] && echo "$ID_LIKE" | grep -qi arch; then
is_arch=1
fi
is_arch=0
case "${ID:-}" in
arch | endeavouros) is_arch=1 ;;
esac
if [[ $is_arch -eq 0 && -n "${ID_LIKE:-}" ]] && echo "$ID_LIKE" | grep -qi arch; then
is_arch=1
fi
is_fedora=0
case "${ID:-}" in
fedora) is_fedora=1 ;;
esac
if [[ $is_fedora -eq 0 && -n "${ID_LIKE:-}" ]] && echo "$ID_LIKE" | grep -qiE 'fedora|rhel'; then
is_fedora=1
fi
is_fedora=0
case "${ID:-}" in
fedora) is_fedora=1 ;;
esac
if [[ $is_fedora -eq 0 && -n "${ID_LIKE:-}" ]] && echo "$ID_LIKE" | grep -qiE 'fedora|rhel'; then
is_fedora=1
fi
if [[ $is_arch -eq 1 ]]; then
PLATFORM="arch"
elif [[ $is_fedora -eq 1 ]]; then
PLATFORM="fedora"
else
echo "Unsupported Linux distro (ID=${ID:-unknown}, ID_LIKE=${ID_LIKE:-unknown})."
exit 1
fi
if [[ $is_arch -eq 1 ]]; then
PLATFORM="arch"
elif [[ $is_fedora -eq 1 ]]; then
PLATFORM="fedora"
else
echo "Unsupported Linux distro (ID=${ID:-unknown}, ID_LIKE=${ID_LIKE:-unknown})."
exit 1
fi
else
echo "Unsupported OS: $OS"
exit 1
echo "Unsupported OS: $OS"
exit 1
fi
# -------- Helpers --------
install_pacman() {
local pkgs=("$@")
log "pacman install: ${pkgs[*]}"
sudo pacman -Sy --needed --noconfirm "${pkgs[@]}"
local pkgs=("$@")
log "pacman install: ${pkgs[*]}"
sudo pacman -Sy --needed --noconfirm "${pkgs[@]}"
}
install_dnf() {
local pkgs=("$@")
log "dnf install: ${pkgs[*]}"
sudo dnf install -y "${pkgs[@]}"
local pkgs=("$@")
log "dnf install: ${pkgs[*]}"
sudo dnf install -y "${pkgs[@]}"
}
brew_install() {
local pkgs=("$@")
log "brew install: ${pkgs[*]}"
brew install "${pkgs[@]}"
local pkgs=("$@")
log "brew install: ${pkgs[*]}"
brew install "${pkgs[@]}"
}
brew_cask() {
local pkgs=("$@")
log "brew install --cask: ${pkgs[*]}"
brew install --cask "${pkgs[@]}"
local pkgs=("$@")
log "brew install --cask: ${pkgs[*]}"
brew install --cask "${pkgs[@]}"
}
install_pkg() {
local pkgs=("$@")
log "pkg install: ${pkgs[*]}"
sudo pkg install -y "${pkgs[@]}"
local pkgs=("$@")
log "pkg install: ${pkgs[*]}"
sudo pkg install -y "${pkgs[@]}"
}
# Best-effort install loops (skip missing packages cleanly)
dnf_install_best_effort() {
local pkgs=("$@")
for p in "${pkgs[@]}"; do
if sudo dnf info "$p" >/dev/null 2>&1; then
install_dnf "$p"
else
log "Skipping (dnf not found): $p"
fi
done
local pkgs=("$@")
for p in "${pkgs[@]}"; do
if sudo dnf info "$p" >/dev/null 2>&1; then
install_dnf "$p"
else
log "Skipping (dnf not found): $p"
fi
done
}
pacman_install_best_effort() {
local pkgs=("$@")
for p in "${pkgs[@]}"; do
if pacman -Si "$p" >/dev/null 2>&1; then
install_pacman "$p"
else
log "Skipping (pacman not found): $p"
fi
done
local pkgs=("$@")
for p in "${pkgs[@]}"; do
if pacman -Si "$p" >/dev/null 2>&1; then
install_pacman "$p"
else
log "Skipping (pacman not found): $p"
fi
done
}
pkg_install_best_effort() {
local pkgs=("$@")
for p in "${pkgs[@]}"; do
if pkg search -q "^${p}$" >/dev/null 2>&1; then
install_pkg "$p"
else
log "Skipping (pkg not found): $p"
fi
done
local pkgs=("$@")
for p in "${pkgs[@]}"; do
if pkg search -q "^${p}$" >/dev/null 2>&1; then
install_pkg "$p"
else
log "Skipping (pkg not found): $p"
fi
done
}
aur_install_if_possible() {
local pkgs=("$@")
if have yay; then
log "AUR install via yay: ${pkgs[*]}"
yay -S --needed --noconfirm "${pkgs[@]}"
else
log "Skipping AUR packages (yay not found): ${pkgs[*]}"
fi
local pkgs=("$@")
if have yay; then
log "AUR install via yay: ${pkgs[*]}"
yay -S --needed --noconfirm "${pkgs[@]}"
else
log "Skipping AUR packages (yay not found): ${pkgs[*]}"
fi
}
install_opencode() {
if have opencode; then
log "opencode already installed"
return 0
fi
if have npm; then
log "Installing opencode via npm..."
npm install -g opencode-ai
else
log "Skipping opencode (npm not found)"
fi
if have opencode; then
log "opencode already installed"
return 0
fi
if have npm; then
log "Installing opencode via npm..."
npm install -g opencode-ai
else
log "Skipping opencode (npm not found)"
fi
}
ensure_brew() {
if have brew; then return 0; fi
log "Homebrew not found; installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
if have brew; then return 0; fi
log "Homebrew not found; installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
if [[ -x /opt/homebrew/bin/brew ]]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [[ -x /usr/local/bin/brew ]]; then
eval "$(/usr/local/bin/brew shellenv)"
fi
if [[ -x /opt/homebrew/bin/brew ]]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [[ -x /usr/local/bin/brew ]]; then
eval "$(/usr/local/bin/brew shellenv)"
fi
}
ensure_flathub() {
if ! have flatpak; then
log "flatpak not installed; skipping flathub apps."
return 0
fi
log "Ensuring Flathub remote exists..."
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
if ! have flatpak; then
log "flatpak not installed; skipping flathub apps."
return 0
fi
log "Ensuring Flathub remote exists..."
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
}
# -------- Package sets (portable intent) --------
@ -169,52 +169,52 @@ UTILS_LINUX=(gnuplot graphviz shfmt shellcheck pandoc)
DESKTOP_LINUX=(kitty alacritty dino syncthing)
FEDORA_EXTRAS=(
gnome-extensions-app
gnome-tweaks
spice-vdagent
kernel-modules-extra
pinentry-tty
NetworkManager-openvpn-gnome
openvpn
openvpn3-client
libpq-devel
postgresql
pass-otp
chromium
google-chrome-stable
gnome-extensions-app
gnome-tweaks
spice-vdagent
kernel-modules-extra
pinentry-tty
NetworkManager-openvpn-gnome
openvpn
openvpn3-client
libpq-devel
postgresql
pass-otp
chromium
google-chrome-stable
)
ARCH_EXTRAS=(
gnome-extensions-app
gnome-tweaks
spice-vdagent
linux-headers
pinentry
networkmanager-openvpn
openvpn
postgresql-libs
postgresql
pass-otp
chromium
snapcast
gnome-extensions-app
gnome-tweaks
spice-vdagent
linux-headers
pinentry
networkmanager-openvpn
openvpn
postgresql-libs
postgresql
pass-otp
chromium
snapcast
)
MAC_BREW_PKGS=(
fzf direnv stow pass just
fd editorconfig git
cmake libtool
gnuplot graphviz shfmt shellcheck pandoc
postgresql
syncthing
pinentry-mac
fzf direnv stow pass just
fd editorconfig git
cmake libtool
gnuplot graphviz shfmt shellcheck pandoc
postgresql
syncthing
pinentry-mac
)
MAC_CASKS=(
kitty
alacritty
slack
google-chrome
chromium
kitty
alacritty
slack
google-chrome
chromium
)
# FreeBSD name mapping (best-effort)
@ -235,85 +235,97 @@ FREEBSD_MISC=(postgresql16-client syncthing)
# -------- Install per-platform --------
case "$PLATFORM" in
fedora)
log "Platform: Fedora. Refreshing + upgrading..."
sudo dnf -y upgrade --refresh || true
log "Platform: Fedora. Refreshing + upgrading..."
sudo dnf -y upgrade --refresh || true
install_dnf "${CORE_CLI[@]}" "${EXTRA_CLI[@]}" || true
dnf_install_best_effort "${DEV_TOOLS_LINUX[@]}"
dnf_install_best_effort "${UTILS_LINUX[@]}"
dnf_install_best_effort "${DESKTOP_LINUX[@]}"
dnf_install_best_effort "${FEDORA_EXTRAS[@]}"
install_dnf "${CORE_CLI[@]}" "${EXTRA_CLI[@]}" || true
dnf_install_best_effort "${DEV_TOOLS_LINUX[@]}"
dnf_install_best_effort "${UTILS_LINUX[@]}"
dnf_install_best_effort "${DESKTOP_LINUX[@]}"
dnf_install_best_effort "${FEDORA_EXTRAS[@]}"
ensure_flathub
if have flatpak; then
log "Optional: Slack via Flatpak"
sudo flatpak install -y flathub com.slack.Slack || true
fi
ensure_flathub
if have flatpak; then
log "Optional: Slack via Flatpak"
sudo flatpak install -y flathub com.slack.Slack || true
fi
install_opencode
;;
install_opencode
log "Final system upgrade..."
sudo dnf -y upgrade
;;
arch)
log "Platform: EndeavourOS/Arch. Updating package databases..."
sudo pacman -Sy --noconfirm
log "Platform: EndeavourOS/Arch. Updating package databases..."
sudo pacman -Sy --noconfirm
install_pacman "${CORE_CLI[@]}" "${EXTRA_CLI[@]}"
pacman_install_best_effort "${DEV_TOOLS_LINUX[@]}"
pacman_install_best_effort "${UTILS_LINUX[@]}"
pacman_install_best_effort "${DESKTOP_LINUX[@]}"
pacman_install_best_effort "${ARCH_EXTRAS[@]}"
install_pacman "${CORE_CLI[@]}" "${EXTRA_CLI[@]}"
pacman_install_best_effort "${DEV_TOOLS_LINUX[@]}"
pacman_install_best_effort "${UTILS_LINUX[@]}"
pacman_install_best_effort "${DESKTOP_LINUX[@]}"
pacman_install_best_effort "${ARCH_EXTRAS[@]}"
aur_install_if_possible google-chrome slack-desktop || true
aur_install_if_possible google-chrome slack-desktop || true
install_opencode
;;
log "Final system upgrade..."
sudo pacman -Syu --noconfirm
install_opencode
;;
macos)
log "Platform: macOS. Ensuring Homebrew..."
ensure_brew
log "Platform: macOS. Ensuring Homebrew..."
ensure_brew
log "Updating Homebrew..."
brew update
log "Updating Homebrew..."
brew update
brew_install "${MAC_BREW_PKGS[@]}"
brew_cask "${MAC_CASKS[@]}" || true
brew_install "${MAC_BREW_PKGS[@]}"
brew_cask "${MAC_CASKS[@]}" || true
if [[ -f "$(brew --prefix)/opt/fzf/install" ]]; then
log "Tip: run fzf install helper if you want keybindings/completion:"
echo " $(brew --prefix)/opt/fzf/install"
fi
if [[ -f "$(brew --prefix)/opt/fzf/install" ]]; then
log "Tip: run fzf install helper if you want keybindings/completion:"
echo " $(brew --prefix)/opt/fzf/install"
fi
install_opencode
;;
install_opencode
log "Final system upgrade..."
brew upgrade
;;
freebsd)
log "Platform: FreeBSD. Updating pkg metadata..."
sudo pkg update -f
log "Platform: FreeBSD. Updating pkg metadata..."
sudo pkg update -f
# Ensure basic SSL certs exist for fetches/tools that need it
pkg_install_best_effort ca_root_nss || true
# Ensure basic SSL certs exist for fetches/tools that need it
pkg_install_best_effort ca_root_nss || true
# Core CLI tools you asked for
pkg_install_best_effort "${FREEBSD_CORE[@]}"
# Core CLI tools you asked for
pkg_install_best_effort "${FREEBSD_CORE[@]}"
# Extras + dev + utilities
pkg_install_best_effort "${FREEBSD_EXTRA[@]}"
pkg_install_best_effort "${FREEBSD_DEV[@]}"
pkg_install_best_effort "${FREEBSD_UTILS[@]}"
# Extras + dev + utilities
pkg_install_best_effort "${FREEBSD_EXTRA[@]}"
pkg_install_best_effort "${FREEBSD_DEV[@]}"
pkg_install_best_effort "${FREEBSD_UTILS[@]}"
# pass needs gpg + pinentry
pkg_install_best_effort "${FREEBSD_SECURITY[@]}"
# pass needs gpg + pinentry
pkg_install_best_effort "${FREEBSD_SECURITY[@]}"
# Optional stuff from your history where it makes sense
pkg_install_best_effort "${FREEBSD_MISC[@]}"
# Optional stuff from your history where it makes sense
pkg_install_best_effort "${FREEBSD_MISC[@]}"
log "FreeBSD notes:"
cat <<'EOF'
log "Final system upgrade..."
sudo pkg upgrade -y
log "FreeBSD notes:"
cat <<'EOF'
- 'pass' is installed as 'password-store' on FreeBSD; command is still: pass
- Build tools often use gmake (GNU make). If you compile from source, try gmake.
- GUI apps (kitty/alacritty/slack/chrome) are not installed here by default.
EOF
;;
;;
esac
# -------- Post-install notes --------
@ -333,3 +345,21 @@ cat <<'EOF'
EOF
log "Done."
# -------- Doom Emacs --------
DOOM_DIR="${DOOM_DIR:-$HOME/.emacs.d}"
if [[ -d "$DOOM_DIR/.git" ]]; then
log "Doom Emacs already present at $DOOM_DIR (updating)..."
git -C "$DOOM_DIR" pull --rebase || true
elif [[ -e "$DOOM_DIR" ]]; then
log "Skipping Doom Emacs clone because $DOOM_DIR exists but is not a git repo."
log "Move it aside if you want to install Doom there."
else
log "Cloning Doom Emacs to $DOOM_DIR..."
git clone --depth=1 https://github.com/doomemacs/doomemacs "$DOOM_DIR"
fi
if [[ -d "$DOOM_DIR" ]]; then
log "Installing Doom Emacs..."
"$DOOM_DIR/bin/doom" install
fi