1
Update Hooks
David Young edited this page 2026-10-26 16:01:09 -06:00

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:

  1. Starts a subshell, so a cd, set -e, exit or stray variable can't affect other hooks.
  2. Sources the file.
  3. If the file defines run_update, calls it, but only if is_installed isn't defined or returns true.
  4. 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.