Table of Contents
Update Hooks
update runs each *.sh file in updates.d/ in filename order. To add a step to update, add a file there.
How hooks run
For each hook, update:
- Starts a subshell, so a
cd,set -e,exitor stray variable can't affect other hooks. - Sources the file.
- If the file defines
run_update, calls it, but only ifis_installedisn't defined or returns true. - If the subshell exits non-zero, adds the hook to "Done, with errors in: …" at the end. The remaining hooks still run.
$COREDESKTOP is set to ~/.local/share/coredesktop. Nothing from earlier hooks is available, so source utils.sh if you need its helpers. Source it before defining your own is_installed, because utils.sh has a pacman-specific function with that name.
Sudo is already authenticated and kept alive for the whole run. Hooks shouldn't prompt for anything else.
Two styles
Top-level code, for steps that always apply:
#!/bin/bash
COREDESKTOP="$HOME/.local/share/coredesktop"
source "$COREDESKTOP/utils.sh"
echo "Checking for new services..."
enable_services "${SERVICES[@]}"
Functions, for steps that only apply on some machines:
#!/bin/bash
is_installed() {
command -v fwupdmgr &>/dev/null
}
run_update() {
echo "Checking for firmware updates..."
...
return 0
}
Return non-zero from run_update to report a failure.
Order
| Hook | Purpose |
|---|---|
09-snapshot.sh |
Snapper snapshot of / (btrfs only) |
10-pacman.sh |
Remove dropped packages, update keyring and Arch, install new packages |
12-migrations.sh |
One-time migrations |
15-services.sh |
Enable new services |
16-update-notify.sh |
Update-notification timer |
20-aur.sh |
AUR packages; rebuilds yay if a pacman upgrade broke it |
30-flatpak.sh |
Flatpaks |
40-ruby.sh |
mise, Ruby and gems |
45-tmux.sh |
tmux plugins |
46-neovim.sh |
Neovim plugins |
50-bitwarden.sh |
Bitwarden SSH agent |
60-pipx.sh |
pipx apps; rebuilds them after a Python upgrade |
65-migrate.sh |
Migrate backup tool |
70-claude.sh |
Claude Code |
71-siblings.sh |
Sibling projects |
72-sandbox.sh |
Sandbox runtime and Hermes Agent |
80-gnome-extensions.sh |
GNOME extensions |
85-gnome-settings.sh |
GNOME extension settings |
90-firmware.sh |
Report firmware updates |
95-cleanup.sh |
Flatpak and pacman cache cleanup, orphaned packages |
99-reboot-check.sh |
Say whether a reboot is needed |
Pick a number that puts your hook after whatever it depends on. Anything that runs before 60-pipx.sh can't rely on pipx apps working, and anything before 20-aur.sh can't rely on yay.
Testing
Run one hook the way update does:
( COREDESKTOP=~/.local/share/coredesktop
source updates.d/NN-name.sh
if declare -f run_update >/dev/null; then
! declare -f is_installed >/dev/null || is_installed && run_update
fi ); echo "exit: $?"
Run it twice to make sure the second run does nothing harmful.
Using CoreDesktop
Working on CoreDesktop