feat(scripts): automate tool and AUR package installation setup

This commit is contained in:
Prad Nukala committed 2026-10-16 14:08:35 -04:00
1 parent fd1fd0cc16
commit 58b6c10779
4 files changed
+99 -20

No files matched your search

@@ -0,0 +1,58 @@
#!/bin/sh
# Tools that come from their own installers rather than pacman/Homebrew:
# rustup (cargo) and the packages.shared.cargo crates, the
# packages.shared.mise tools (omp, opencode, …), and strata on Linux desktop
# roles. Runs before 20-gh-extensions, whose fish session sources
# ~/.cargo/env.fish (conf.d/rustup.fish) and activates mise.
# cargo hash: {{ .packages.shared.cargo | toJson | sha256sum }}
# mise hash: {{ .packages.shared.mise | toJson | sha256sum }}
set -eu
# Where rustup puts cargo; chezmoi's environment can predate the shell config
# that adds it.
PATH="$HOME/.cargo/bin:$PATH"
export PATH
# rustup: -y answers its prompt (no tty under chezmoi); --no-modify-path keeps
# it out of the shell rc files, which are symlinks into this repo and already
# source ~/.cargo/env (bash, zsh, fish conf.d/rustup.fish).
if ! command -v cargo >/dev/null 2>&1; then
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path
fi
installed=$(cargo install --list | awk '/^[^ ]/{print $1}')
{{ range .packages.shared.cargo -}}
echo "$installed" | grep -qx {{ . | quote }} || cargo install --locked {{ . | quote }}
{{ end }}
# Global mise tools. Only tools absent from the global config are added, so a
# local pin (node = "22") is never rewritten to latest; `mise install` then
# fetches any configured version that is not installed yet.
if command -v mise >/dev/null 2>&1; then
global=$(mise ls --global --json)
missing=''
for tool in{{ range .packages.shared.mise }} {{ . | quote }}{{ end }}; do
echo "$global" | jq -e --arg t "$tool" 'has($t)' >/dev/null || missing="$missing $tool"
done
# shellcheck disable=SC2086 # one word per tool
[ -z "$missing" ] || mise use -g $missing
mise install{{ range .packages.shared.mise }} {{ . | quote }}{{ end }}
# omp's own installer (omp.sh/install) put a binary in ~/.local/bin, which
# precedes mise's shims on PATH; drop it once mise provides omp.
if [ -f "$HOME/.local/bin/omp" ] && [ ! -L "$HOME/.local/bin/omp" ] && mise which omp >/dev/null 2>&1; then
rm -f "$HOME/.local/bin/omp"
fi
else
echo "warning: mise not installed — skipping mise tools" >&2
fi
{{- if and (eq .chezmoi.os "linux") (or (eq .role "desktop") (eq .role "laptop")) }}
# strata (GUI file manager): binary in ~/.local/bin, desktop entry, and the
# FileManager1 D-Bus service for "Open file location". The inode/directory
# default is dot_config/mimeapps.list; --with-folder-association is not used
# because xdg-mime would replace that symlink with a plain file. Runtime deps
# are in packages.arch.desktop.pacman.
if [ ! -e "$HOME/.local/bin/strata" ]; then
curl -fsSL https://raw.githubusercontent.com/lgse/strata/main/install.sh | bash -s -- --with-desktop-entry --with-file-manager
fi
{{- end }}
@@ -1,12 +1,25 @@
#!/bin/sh
#!/usr/bin/env fish
# Install gh extensions declared in .chezmoidata/packages.yaml.
# A fish script, so fish's config (~/.config/fish, applied before after-scripts
# run) is sourced first: PATH (mise, ~/.local/bin, ~/.cargo/bin) and
# GITHUB_TOKEN (conf.d/10-env.fish) match a fish session.
# gh_extensions hash: {{ .packages.shared.gh_extensions | toJson | sha256sum }}
set -eu
command -v gh >/dev/null 2>&1 || { echo "warning: gh not installed — skipping extensions" >&2; exit 0; }
gh auth status >/dev/null 2>&1 || { echo "warning: gh not authenticated — run 'gh auth login', then 'chezmoi apply' again" >&2; exit 0; }
if not command -q gh
echo "warning: gh not installed — skipping extensions" >&2
exit 0
end
if not gh auth status >/dev/null 2>&1
echo "warning: gh not authenticated — run 'gh auth login', then 'chezmoi apply' again" >&2
exit 0
end
installed=$(gh extension list 2>/dev/null | cut -f2 || true)
{{ range .packages.shared.gh_extensions }}
echo "$installed" | grep -qxF "{{ . }}" || gh extension install "{{ . }}"
{{ end }}
set -l installed (gh extension list 2>/dev/null | string split -f2 \t)
set -l failed
for ext in{{ range .packages.shared.gh_extensions }} {{ . | quote }}{{ end }}
contains -- $ext $installed; or gh extension install $ext; or set -a failed $ext
end
if set -q failed[1]
echo "error: gh extension install failed for: $failed" >&2
exit 1
end
@@ -7,12 +7,3 @@ if command -v bat >/dev/null 2>&1; then bat cache --build >/dev/null || true; fi
{{ if eq .chezmoi.os "linux" -}}
if command -v fc-cache >/dev/null 2>&1; then fc-cache -f >/dev/null || true; fi
{{ end -}}
# cargo installs from packages.shared.cargo; skipped when cargo is absent.
# cargo hash: {{ .packages.shared.cargo | toJson | sha256sum }}
if command -v cargo >/dev/null 2>&1; then
installed=$(cargo install --list | awk '/^[^ ]/{print $1}')
{{ range .packages.shared.cargo }}
echo "$installed" | grep -qx "{{ . }}" || cargo install --locked "{{ . }}"
{{ end }}
fi
@@ -28,15 +28,32 @@ aur_pkgs="{{ range .packages.arch.desktop.aur }}{{ . }} {{ end }}{{ range .packa
{{ else -}}
aur_pkgs="{{ range .packages.arch.aur }}{{ . }} {{ end }}"
{{ end -}}
if [ -n "$(echo "$aur_pkgs" | tr -d ' ')" ]; then
# AUR names no installed package provides yet; ones already installed from a
# sync repo (cachyos, [omarchy]) are neither rebuilt nor replaced.
# shellcheck disable=SC2086
aur_missing=$(pacman -T $aur_pkgs || true)
if [ -n "$aur_missing" ]; then
# No AUR helper yet: take yay from a sync repo that ships it (cachyos,
# chaotic-aur), else build yay-bin from the AUR (makepkg refuses root).
if ! command -v yay >/dev/null 2>&1 && ! command -v paru >/dev/null 2>&1; then
if pacman -Si yay >/dev/null 2>&1; then
$PACMAN -S --needed --noconfirm yay
elif [ "$(id -u)" -ne 0 ]; then
install_missing git base-devel
yay_build=$(mktemp -d)
git clone --depth 1 https://aur.archlinux.org/yay-bin.git "$yay_build"
(cd "$yay_build" && makepkg -si --noconfirm)
rm -rf "$yay_build"
fi
fi
if command -v yay >/dev/null 2>&1; then AUR="yay"
elif command -v paru >/dev/null 2>&1; then AUR="paru"
else AUR=""; fi
if [ -n "$AUR" ]; then
# shellcheck disable=SC2086
$AUR -S --needed --noconfirm $aur_pkgs
$AUR -S --needed --noconfirm $aur_missing
else
echo "warning: yay/paru not found — skipping AUR packages: $aur_pkgs" >&2
echo "warning: no yay/paru and none could be bootstrapped — skipping AUR packages:" $aur_missing >&2
fi
fi