Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion bin/omarchy-update-restart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,18 @@ done
if [[ $kernel_updated == "true" ]]; then
confirm_reboot "Linux kernel has been updated. Reboot?"
elif [[ -f $HOME/.local/state/omarchy/reboot-required ]]; then
confirm_reboot "Updates require reboot. Ready?"
# Only omarchy-system-reboot clears this flag, so a reboot by any other route
# (systemctl reboot, the power button, a crash) leaves it behind to prompt
# after every later update. A flag written before the current boot has
# already been honored.
boot_time=$(awk '/^btime/ {print $2}' /proc/stat)
flag_time=$(stat -c %Y "$HOME/.local/state/omarchy/reboot-required")

if (( flag_time < boot_time )); then
omarchy-state clear reboot-required
else
confirm_reboot "Updates require reboot. Ready?"
fi
fi

running_hyprland=$(readlink /proc/$(pgrep -x Hyprland)/exe 2>/dev/null)
Expand Down
114 changes: 114 additions & 0 deletions test/shell.d/update-restart-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/bin/bash

set -euo pipefail

source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"

# The kernel check walks the real /usr/lib/modules; without an installed kernel
# there the reboot-required branch is unreachable and there is nothing to test.
installed_kernel=""
for kernel in /usr/lib/modules/*/vmlinuz; do
[[ -f $kernel ]] || continue
installed_kernel=$(basename "$(dirname "$kernel")")
break
done

if [[ -z $installed_kernel ]]; then
pass "no kernel under /usr/lib/modules; skipping reboot-required checks"
exit 0
fi

test_tmp=$(mktemp -d)
trap 'rm -rf "$test_tmp"' EXIT

mock_bin="$test_tmp/bin"
call_log="$test_tmp/calls.log"
home="$test_tmp/home"
state_dir="$home/.local/state/omarchy"
flag="$state_dir/reboot-required"
mkdir -p "$mock_bin" "$state_dir"

cat >"$mock_bin/uname" <<SH
#!/bin/bash

echo "$installed_kernel"
SH

cat >"$mock_bin/pacman" <<'SH'
#!/bin/bash

exit 0
SH

cat >"$mock_bin/pgrep" <<'SH'
#!/bin/bash

exit 1
SH

# gum records the prompt and declines it, so the script continues past it.
cat >"$mock_bin/gum" <<'SH'
#!/bin/bash

printf 'gum %s\n' "$*" >>"$CALL_LOG"
exit 1
SH

for command in omarchy-system-reboot omarchy-restart-shell; do
cat >"$mock_bin/$command" <<'SH'
#!/bin/bash

printf '%s %s\n' "$(basename "$0")" "$*" >>"$CALL_LOG"
SH
done
chmod +x "$mock_bin"/*

run_update_restart() {
: >"$call_log"
HOME="$home" PATH="$mock_bin:$ROOT/bin:$PATH" CALL_LOG="$call_log" \
"$ROOT/bin/omarchy-update-restart" >/dev/null
}

prompted_for_reboot() {
grep -qF 'gum confirm Updates require reboot. Ready?' "$call_log"
}

boot_time=$(awk '/^btime/ {print $2}' /proc/stat)

# A flag older than the current boot was already honored by a reboot that did
# not go through omarchy-system-reboot.
touch -d "@$((boot_time - 60))" "$flag"
run_update_restart

if prompted_for_reboot; then
fail "reboot-required flag written before the current boot does not prompt"
fi
pass "reboot-required flag written before the current boot does not prompt"

if [[ -e $flag ]]; then
fail "reboot-required flag written before the current boot is cleared"
fi
pass "reboot-required flag written before the current boot is cleared"

# A flag set since boot, e.g. by a migration in this very update, still prompts.
touch "$flag"
run_update_restart

if ! prompted_for_reboot; then
fail "reboot-required flag written since boot prompts for a reboot" "$(cat "$call_log")"
fi
pass "reboot-required flag written since boot prompts for a reboot"

if [[ ! -e $flag ]]; then
fail "declining the prompt keeps the reboot-required flag"
fi
pass "declining the prompt keeps the reboot-required flag"

# No flag, no prompt.
rm -f "$flag"
run_update_restart

if prompted_for_reboot; then
fail "no reboot-required flag means no prompt"
fi
pass "no reboot-required flag means no prompt"