diff --git a/bin/omarchy-first-run b/bin/omarchy-first-run index 5d8be151..3a6a9710 100755 --- a/bin/omarchy-first-run +++ b/bin/omarchy-first-run @@ -35,9 +35,15 @@ while (($#)); do esac done +state_dir=~/.local/state/omarchy +FIRST_RUN_DONE="first-run-user" +if omarchy-done check "$FIRST_RUN_DONE" && (( force == 0 )); then + echo "First-run already complete (rerun with --force to refresh)." + exit 0 +fi + omarchy-finalize-user "${finalize_user_args[@]}" || true -state_dir=~/.local/state/omarchy mkdir -p "$state_dir" FIRST_RUN_LOG="$state_dir/first-run.log" @@ -94,42 +100,32 @@ run_first_run_step() { wait_for_notifications -MIGRATION_NOTIFY_WATCH_MARKER="$state_dir/user-migration-notify-watch-enabled" -if [[ ! -f $MIGRATION_NOTIFY_WATCH_MARKER || $force -eq 1 ]]; then - if systemctl --user enable --now omarchy-update-user-notify.path >/dev/null 2>&1; then - touch "$MIGRATION_NOTIFY_WATCH_MARKER" - fi -fi - +run_first_run_step "enable migration notification watcher" \ + systemctl --user enable --now omarchy-update-user-notify.path run_first_run_step "notify about pending migrations" omarchy-migrate-notify -FIRST_RUN_DONE="first-run-user" -if ! omarchy-done check "$FIRST_RUN_DONE" || (( force )); then - run_first_run_step "install Voxtype post-update hook" \ - omarchy-hook-install post-update "$OMARCHY_PATH/install/user/first-run/install-voxtype.hook" +run_first_run_step "install Voxtype post-update hook" \ + omarchy-hook-install post-update "$OMARCHY_PATH/install/user/first-run/install-voxtype.hook" - run_first_run_step "enable user systemd units" \ - bash "$OMARCHY_PATH/install/user/first-run/enable-user-units.sh" - run_first_run_step "set GNOME theme" \ - bash "$OMARCHY_PATH/install/user/first-run/gnome-theme.sh" - run_first_run_step "set GTK primary paste" \ - bash "$OMARCHY_PATH/install/user/first-run/gtk-primary-paste.sh" +run_first_run_step "enable user systemd units" \ + bash "$OMARCHY_PATH/install/user/first-run/enable-user-units.sh" +run_first_run_step "set GNOME theme" \ + bash "$OMARCHY_PATH/install/user/first-run/gnome-theme.sh" +run_first_run_step "set GTK primary paste" \ + bash "$OMARCHY_PATH/install/user/first-run/gtk-primary-paste.sh" - wait_for_notifications - run_first_run_step "show welcome notification" \ - bash "$OMARCHY_PATH/install/user/first-run/welcome.sh" - # The first-run notification scripts register action callbacks in background - # notify-send processes. Give the notification server a tick to ingest the - # welcome toast before queueing the Wi-Fi/update toasts. - sleep 0.3 - run_first_run_step "show Wi-Fi/update notifications" \ - bash "$OMARCHY_PATH/install/user/first-run/wifi.sh" +wait_for_notifications +run_first_run_step "show welcome notification" \ + bash "$OMARCHY_PATH/install/user/first-run/welcome.sh" +# The first-run notification scripts register action callbacks in background +# notify-send processes. Give the notification server a tick to ingest the +# welcome toast before queueing the Wi-Fi/update toasts. +sleep 0.3 +run_first_run_step "show Wi-Fi/update notifications" \ + bash "$OMARCHY_PATH/install/user/first-run/wifi.sh" - if (( first_run_failed == 0 )); then - omarchy-done mark "$FIRST_RUN_DONE" - else - log_first_run "One or more first-run steps failed; first-run will retry next login" - fi +if (( first_run_failed == 0 )); then + omarchy-done mark "$FIRST_RUN_DONE" else - echo "First-run already complete (rerun with --force to refresh)." + log_first_run "One or more first-run steps failed; first-run will retry next login" fi diff --git a/bin/omarchy-upgrade-to-quattro b/bin/omarchy-upgrade-to-quattro index 1ff13de1..a5c58325 100755 --- a/bin/omarchy-upgrade-to-quattro +++ b/bin/omarchy-upgrade-to-quattro @@ -1175,14 +1175,8 @@ run_post_upgrade_update_steps() { omarchy-update-available 2>&1) || update_status=$? if (( update_status == 0 )); then - warn "Updates are still available after the upgrade; first-run will still offer to run omarchy-update:" + warn "Updates are still available after the upgrade; run omarchy-update after reboot:" printf '%s\n' "$update_output" >&2 - else - # The live upgrade has already completed the package update. Let first-run - # finish session-only setup, but skip its generic fresh-install update - # toast when the update checker confirms nothing remains. - run_as_user mkdir -p "$target_home/.local/state/omarchy" - run_as_user touch "$target_home/.local/state/omarchy/skip-first-run-update-notification" fi fi } @@ -2201,10 +2195,8 @@ if command -v xdg-mime >/dev/null 2>&1; then xdg-mime default HEY.desktop x-scheme-handler/mailto || true fi -if [[ -f $state_dir/first-run-user.done ]]; then - "$root/bin/omarchy-done" mark first-run-user - rm -f "$state_dir/first-run-user.done" -fi +"$root/bin/omarchy-done" mark first-run-user +rm -f "$state_dir/first-run-user.done" "$root/bin/omarchy-done" mark finalize-user rm -f "$state_dir/finalize-user.done" diff --git a/docs/file-layout.md b/docs/file-layout.md index 857696da..08500159 100644 --- a/docs/file-layout.md +++ b/docs/file-layout.md @@ -229,16 +229,17 @@ systemd instance: `install/user/first-run/wifi.sh` — welcome and Wi-Fi/update toasts (waits for a live notification server before firing). -Idempotency marker: `~/.local/state/omarchy/done/first-run-user`, managed -by `omarchy-done`. On -failure the marker is not written and the failed step retries next login. +The entire sequence has one idempotency marker: +`~/.local/state/omarchy/done/first-run-user`, managed by `omarchy-done`. +Completed users exit before any first-run step. On failure the marker is not +written and the sequence retries next login. Completion markers live under `~/.local/state/omarchy/done/`. Use `omarchy-done check ` to check one and `omarchy-done mark ` to record it. Use `omarchy-done ensure ` as a conditional when the guarded work should run only once; it records completion before returning success. -The Quattro upgrade moves legacy completion markers from -`~/.local/state/omarchy/` into `done/`. +The Quattro upgrade completes graphical first-run for upgraded users and moves +the legacy finalization marker from `~/.local/state/omarchy/` into `done/`. ## Root-side install orchestration diff --git a/install/user/first-run/wifi.sh b/install/user/first-run/wifi.sh index 87126bad..0abed885 100644 --- a/install/user/first-run/wifi.sh +++ b/install/user/first-run/wifi.sh @@ -1,14 +1,4 @@ -state_dir="$HOME/.local/state/omarchy" -skip_update_notification_file="$state_dir/skip-first-run-update-notification" -skip_update_notification=0 -if [[ -f $skip_update_notification_file ]]; then - skip_update_notification=1 - rm -f "$skip_update_notification_file" -fi - notify_update() { - (( skip_update_notification )) && return 0 - ( if [[ -n $(omarchy-notification-send -u critical -g  "Update System" "$1" -a) ]]; then omarchy-launch-floating-terminal-with-presentation omarchy-update diff --git a/test/shell.d/first-run-test.sh b/test/shell.d/first-run-test.sh new file mode 100644 index 00000000..83b87db4 --- /dev/null +++ b/test/shell.d/first-run-test.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +source "$(dirname "$0")/base-test.sh" + +test_tmp=$(mktemp -d) +trap 'rm -rf "$test_tmp"' EXIT + +mock_bin="$test_tmp/bin" +mkdir -p "$mock_bin" "$test_tmp/home" + +cat >"$mock_bin/omarchy-done" <<'SH' +#!/bin/bash +[[ $1 == "check" && $2 == "first-run-user" ]] +SH +cat >"$mock_bin/omarchy-finalize-user" <<'SH' +#!/bin/bash +touch "$OMARCHY_TEST_FINALIZE_CALLED" +SH +chmod +x "$mock_bin/omarchy-done" "$mock_bin/omarchy-finalize-user" + +finalize_called="$test_tmp/finalize-called" +HOME="$test_tmp/home" PATH="$mock_bin:$PATH" OMARCHY_TEST_FINALIZE_CALLED="$finalize_called" \ + bash "$ROOT/bin/omarchy-first-run" >"$test_tmp/output" + +[[ ! -e $finalize_called ]] || fail "completed first-run exits before any setup step" +grep -F 'First-run already complete' "$test_tmp/output" >/dev/null || fail "completed first-run reports its lifecycle gate" + +if grep -F 'user-migration-notify-watch-enabled' "$ROOT/bin/omarchy-first-run" >/dev/null; then + fail "first-run does not track the migration watcher separately" +fi +if grep -F 'skip-first-run-update-notification' "$ROOT/install/user/first-run/wifi.sh" >/dev/null; then + fail "first-run does not track update notifications separately" +fi + +pass "first-run uses one lifecycle completion marker" diff --git a/test/shell.d/upgrade-to-quattro-test.sh b/test/shell.d/upgrade-to-quattro-test.sh index 767525a5..0682a1f0 100644 --- a/test/shell.d/upgrade-to-quattro-test.sh +++ b/test/shell.d/upgrade-to-quattro-test.sh @@ -5,7 +5,6 @@ set -euo pipefail source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" upgrade_to_quattro="$ROOT/bin/omarchy-upgrade-to-quattro" -first_run_wifi="$ROOT/install/user/first-run/wifi.sh" snapshot_line=$(grep -n '^create_pre_upgrade_snapshot$' "$upgrade_to_quattro" | cut -d: -f1) pacman_line=$(grep -n '^configure_pacman_channel$' "$upgrade_to_quattro" | cut -d: -f1) @@ -27,16 +26,16 @@ grep -F 'dust' "$upgrade_to_quattro" >/dev/null grep -F 'satty' "$upgrade_to_quattro" >/dev/null pass "Omarchy 4 upgrade applies packaged migrations" -grep -F 'skip-first-run-update-notification' "$upgrade_to_quattro" >/dev/null -grep -F 'skip-first-run-update-notification' "$first_run_wifi" >/dev/null -grep -F '(( skip_update_notification )) && return 0' "$first_run_wifi" >/dev/null -pass "Omarchy 4 upgrade suppresses the fresh-install update toast" +if grep -F 'skip-first-run-update-notification' "$upgrade_to_quattro" >/dev/null; then + fail "Omarchy 4 upgrade does not use notification-specific first-run state" +fi +pass "Omarchy 4 upgrade completes first-run as one lifecycle" grep -F '"$root/bin/omarchy-done" mark first-run-user' "$upgrade_to_quattro" >/dev/null grep -F 'rm -f "$state_dir/first-run-user.done"' "$upgrade_to_quattro" >/dev/null grep -F '"$root/bin/omarchy-done" mark finalize-user' "$upgrade_to_quattro" >/dev/null grep -F 'rm -f "$state_dir/finalize-user.done"' "$upgrade_to_quattro" >/dev/null -pass "Omarchy 4 upgrade migrates legacy completion markers" +pass "Omarchy 4 upgrade completes first-run and migrates legacy completion markers" grep -F 'configure_snapper_policy' "$upgrade_to_quattro" >/dev/null grep -F '/usr/share/omarchy/install/config/snapper.sh' "$upgrade_to_quattro" >/dev/null