omarchy-update-user-notify.path watched /usr/share/omarchy/migrations, but pacman writes that directory during every update, including the blessed omarchy update, which runs omarchy-migrate a step later. The watcher fired a critical notification for the migrations the update was already applying in the visible terminal. A watcher cannot tell that apart from a bypassed pacman -Syu, so the only trigger that never collides with a running update is a once-per-login check. The service that already ran at graphical-session.target is now the whole mechanism, renamed after the command it runs. That is also all the second-user case needs: markers are per-user, so anyone who did not run the update finds them missing at their next login. Login timing means the toast can be sent before the shell has claimed org.freedesktop.Notifications, so the notifier waits for a live server first. The wait is omarchy-first-run's, lifted into omarchy-notification-wait rather than duplicated. The package keeps omarchy-update-user-notify.service as a symlink onto the new unit. Existing users hold an absolute wants symlink to the old path, and the migration that repoints it only runs for users who run an update, which is the opposite of who the notifier is for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
103 lines
2.2 KiB
Bash
Executable File
103 lines
2.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# omarchy:summary=Run pending Omarchy migrations.
|
|
# omarchy:args=[--pending]
|
|
|
|
set -euo pipefail
|
|
|
|
mode="run"
|
|
|
|
usage() {
|
|
echo "Usage: omarchy-migrate [--pending]"
|
|
}
|
|
|
|
while (($#)); do
|
|
case "$1" in
|
|
--pending|--check)
|
|
mode="pending"
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
OMARCHY_PATH="${OMARCHY_PATH:-/usr/share/omarchy}"
|
|
STATE_DIR="${OMARCHY_MIGRATION_STATE:-$HOME/.local/state/omarchy/migrations}"
|
|
MIGRATIONS_DIR="$OMARCHY_PATH/migrations"
|
|
|
|
migration_entries() {
|
|
[[ -d $MIGRATIONS_DIR ]] || return 0
|
|
|
|
local file filename
|
|
|
|
for file in "$MIGRATIONS_DIR"/*.sh; do
|
|
[[ -f $file ]] || continue
|
|
filename=$(basename "$file")
|
|
printf '%s\t%s\t%s\n' "$filename" "$file" "$STATE_DIR/$filename"
|
|
done
|
|
}
|
|
|
|
pending_migrations() {
|
|
local name file marker
|
|
|
|
while IFS=$'\t' read -r name file marker; do
|
|
[[ -n $name ]] || continue
|
|
if [[ ! -f $marker ]]; then
|
|
printf '%s\n' "$name"
|
|
fi
|
|
done < <(migration_entries)
|
|
}
|
|
|
|
if [[ $mode == "pending" ]]; then
|
|
pending_output=$(pending_migrations)
|
|
if [[ -n $pending_output ]]; then
|
|
printf '%s\n' "$pending_output"
|
|
exit 0
|
|
else
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
wait_for_pacman_transaction() {
|
|
local lock_file=/var/lib/pacman/db.lck
|
|
|
|
[[ -e $lock_file ]] || return 0
|
|
echo "Waiting for pacman transaction to finish before running Omarchy migrations..."
|
|
|
|
for _ in {1..900}; do
|
|
[[ -e $lock_file ]] || return 0
|
|
sleep 1
|
|
done
|
|
|
|
echo "Pacman transaction is still running; Omarchy migrations will retry on next login."
|
|
exit 0
|
|
}
|
|
|
|
wait_for_pacman_transaction
|
|
|
|
mkdir -p "$STATE_DIR"
|
|
[[ -d $MIGRATIONS_DIR ]] || exit 0
|
|
|
|
while IFS=$'\t' read -r name file marker; do
|
|
[[ -n $name ]] || continue
|
|
|
|
if [[ ! -f $marker ]]; then
|
|
echo -e "\e[32m\nRunning migration (${name%.sh})\e[0m"
|
|
OMARCHY_PATH="$OMARCHY_PATH" bash -euo pipefail "$file"
|
|
mkdir -p "$(dirname "$marker")"
|
|
touch "$marker"
|
|
fi
|
|
done < <(migration_entries)
|
|
|
|
# Clear a login-time notification the user left sitting there and then resolved
|
|
# by running migrations some other way. The substring matches both the current
|
|
# and legacy notification titles.
|
|
omarchy-notification-dismiss "Omarchy Migrations" >/dev/null 2>&1 || true
|