diff --git a/docs/omarchy-shell.md b/docs/omarchy-shell.md index 0b9601ad..e90282d5 100644 --- a/docs/omarchy-shell.md +++ b/docs/omarchy-shell.md @@ -100,7 +100,7 @@ The lower-level IPC methods remain available through `omarchy-shell shell ...`. ## Elsewhen -Elsewhen (`omacom.elsewhen`) ships in the `elsewhen` package at `/usr/share/omarchy/shell/plugins/omacom.elsewhen`, where the shell discovers it automatically. New installs place it immediately before the clock; the migration uses `omarchy bar put omacom.elsewhen --before omarchy.clock`, which preserves an existing placement and uses Elsewhen's normal right-side placement if the clock is absent. Existing plugin directories and symlinks are left intact. The normal update flow restarts the shell after migrations; the migration does not interrupt plugin loading with an immediate restart. +Elsewhen (`omacom.elsewhen`) ships in the `elsewhen` package at `/usr/share/omarchy/shell/plugins/omacom.elsewhen`, where the shell discovers it automatically. New installs place it immediately before the clock; the migration uses `omarchy bar put omacom.elsewhen --before omarchy.clock`, which preserves an existing placement and uses Elsewhen's normal right-side placement if the clock is absent. Existing plugin directories and symlinks are left intact. The normal update flow restarts the shell after migrations; the migration does not interrupt plugin loading with an immediate restart. With no shell to ask, as in an update from a TTY, the migration installs the package and skips the placement rather than failing the update; `omarchy bar put omacom.elsewhen --before omarchy.clock` places the widget later. ## IPC diff --git a/migrations/1789581661.sh b/migrations/1789581661.sh index ad0dfd5e..8dce1c3e 100644 --- a/migrations/1789581661.sh +++ b/migrations/1789581661.sh @@ -2,13 +2,22 @@ echo "Install Elsewhen, the world clock plugin" omarchy-pkg-add elsewhen -# Dev checkouts do not contain plugins installed by system packages. packaged_plugin="/usr/share/omarchy/shell/plugins/omacom.elsewhen" user_plugin="$HOME/.config/omarchy/plugins/omacom.elsewhen" + +# The package moved from plugins/ to shell/plugins/ once, stranding the link an +# earlier run made to the old path. A link the user made is left alone. +if [[ -L $user_plugin && ! -e $user_plugin && $(readlink "$user_plugin") == /usr/share/omarchy/* && -d $packaged_plugin ]]; then + ln -sfn "$packaged_plugin" "$user_plugin" +fi + +# Dev checkouts do not contain plugins installed by system packages. if [[ ! $OMARCHY_PATH -ef /usr/share/omarchy && -d $packaged_plugin && ! -e $user_plugin && ! -L $user_plugin ]]; then mkdir -p "${user_plugin%/*}" ln -s "$packaged_plugin" "$user_plugin" fi -omarchy-shell shell rescanPlugins +# Best-effort, like the put below: an update whose shell cannot be asked still +# finishes, and restarts the shell once the migrations are through. +omarchy-shell -q shell rescanPlugins omarchy-bar put omacom.elsewhen --before omarchy.clock diff --git a/test/shell.d/elsewhen-default-migration-test.sh b/test/shell.d/elsewhen-default-migration-test.sh index 0c2565f4..78dc69a9 100644 --- a/test/shell.d/elsewhen-default-migration-test.sh +++ b/test/shell.d/elsewhen-default-migration-test.sh @@ -18,7 +18,17 @@ SH cat >"$test_dir/bin/omarchy-shell" <<'SH' #!/bin/bash printf '%s\n' "$*" >>"$CALL_LOG" -[[ $2 != "rescanPlugins" ]] || exit "${SCAN_STATUS:-0}" +quiet=0 +if [[ $1 == "-q" ]]; then + quiet=1 + shift +fi +if [[ ${SHELL_ABSENT:-0} == 1 ]]; then + (( quiet )) && exit 0 + echo "omarchy-shell is not running" >&2 + exit 1 +fi +[[ $2 != "rescanPlugins" ]] || exit 0 printf '%s\n' "${TEST_PUT_RESULT:-ok}" SH cat >"$test_dir/bin/omarchy-restart-shell" <<'SH' @@ -50,7 +60,7 @@ run_migration [[ ! -e $ROOT/config/omarchy/plugins/omacom.elsewhen && ! -L $ROOT/config/omarchy/plugins/omacom.elsewhen ]] || fail "fresh installs do not ship a user plugin link" pass "migration and fresh installs rely on the packaged plugin directory" -expected=$'package elsewhen\nshell rescanPlugins\nshell putBarWidget omacom.elsewhen {"before":"omarchy.clock"}' +expected=$'package elsewhen\n-q shell rescanPlugins\nshell putBarWidget omacom.elsewhen {"before":"omarchy.clock"}' [[ $(cat "$CALL_LOG") == "$expected" ]] || fail "install, scan and placement run in order" "$(cat "$CALL_LOG")" pass "real bar helper enables and places before the clock without restarting during reload" @@ -80,10 +90,33 @@ run_migration "$ROOT" [[ $(readlink "$plugin") == "$test_dir/custom-plugin" ]] || fail "existing symlink is preserved" pass "existing symlink is preserved, including a missing target" -for failure in 'SCAN_STATUS=1' 'TEST_PUT_RESULT=unknown'; do - if env "$failure" HOME="$test_dir/home" OMARCHY_PATH="$ROOT" PATH="$test_dir/bin:$ROOT/bin:$PATH" \ - bash -euo pipefail "$test_dir/migration.sh" >"$test_dir/output" 2>&1; then - fail "$failure must leave the migration pending" - fi - pass "$failure leaves the migration pending" +# An earlier revision, and a symlink once shipped under config/, pointed every +# install at the package's old path. +for tree in "$ROOT" "$test_dir/packaged"; do + ln -sfn "$test_dir/packaged/plugins/omacom.elsewhen" "$plugin" + run_migration "$tree" + [[ $(readlink "$plugin") == "$test_dir/packaged/shell/plugins/omacom.elsewhen" ]] || + fail "a stranded link to the package's old path is re-pointed (OMARCHY_PATH=$tree)" "$(readlink "$plugin")" done +pass "a stranded link to the package's old path is re-pointed on every install" +rm "$plugin" + +if env TEST_PUT_RESULT=unknown HOME="$test_dir/home" OMARCHY_PATH="$ROOT" PATH="$test_dir/bin:$ROOT/bin:$PATH" \ + bash -euo pipefail "$test_dir/migration.sh" >"$test_dir/output" 2>&1; then + fail "an unknown widget must leave the migration pending" +fi +pass "an unknown widget leaves the migration pending" + +# An update with no shell to ask, from a TTY or with the shell down, still +# finishes: the package and link land, the placement is skipped, and the update +# restarts the shell afterwards. +rm "$plugin" +: >"$CALL_LOG" +if ! env SHELL_ABSENT=1 OMARCHY_SHELL_ABSENT_ATTEMPTS=1 HOME="$test_dir/home" OMARCHY_PATH="$ROOT" PATH="$test_dir/bin:$ROOT/bin:$PATH" \ + bash -euo pipefail "$test_dir/migration.sh" >"$test_dir/output" 2>&1; then + fail "an absent shell must not fail the migration" "$(cat "$test_dir/output")" +fi +grep -q "omacom.elsewhen was not put on the bar" "$test_dir/output" || fail "an absent shell is reported" "$(cat "$test_dir/output")" +[[ $(readlink "$plugin") == "$test_dir/packaged/shell/plugins/omacom.elsewhen" ]] || fail "the package and plugin link land without a shell" +[[ $(cat "$CALL_LOG") == "$expected" ]] || fail "the rescan is best-effort and the put is still asked" "$(cat "$CALL_LOG")" +pass "an absent shell leaves the update running with the package and link in place"