feat: stop subcommand, and disables empty lines from counting as an alarm element

This commit is contained in:
Lewis Wynne 2026-04-01 23:00:00 +01:00
parent c11aefb963
commit 6a13649c54
2 changed files with 107 additions and 3 deletions

64
nag
View file

@ -419,8 +419,8 @@ _read_alarms() {
local _line
while IFS= read -r _line || [[ -n "${_line}" ]]
do
_ALARMS+=("${_line}")
done < "${NAG_PATH}"
[[ -n "${_line}" ]] && _ALARMS+=("${_line}")
done < "${NAG_PATH}" || true
fi
}
@ -540,7 +540,7 @@ _format_time() {
_date_prefix="Tomorrow"
elif (( _days_away <= 6 ))
then
_date_prefix="$(date -d "@${_timestamp}" "+%A")"
_date_prefix="This $(date -d "@${_timestamp}" "+%A")"
elif (( _days_away <= 13 ))
then
_date_prefix="Next $(date -d "@${_timestamp}" "+%A")"
@ -714,6 +714,12 @@ list() {
_read_alarms
if (( ${#_ALARMS[@]} == 0 ))
then
printf "Nothing to nag about.\\n"
return 0
fi
# Sort alarms by timestamp (field 2).
local -a _sorted
IFS=$'\n' _sorted=($(printf "%s\n" "${_ALARMS[@]}" | sort -t$'\t' -k2 -n))
@ -743,6 +749,58 @@ list() {
done
}
# stop ########################################################################
describe "stop" <<HEREDOC
Usage:
${_ME} stop <id>
Description:
Stop an alarm by ID.
HEREDOC
stop() {
local _target_id="${1:-}"
[[ -n "${_target_id}" ]] || _exit_1 printf "Usage: %s stop <id>\\n" "${_ME}"
_acquire_lock
_read_alarms
local -a _new_alarms=()
local _found=0
local _line
for _line in "${_ALARMS[@]:-}"
do
[[ -n "${_line}" ]] || continue
local _id
_id="$(_get_alarm_field "${_line}" 1)"
if [[ "${_id}" == "${_target_id}" ]]
then
_found=1
else
_new_alarms+=("${_line}")
fi
done
if [[ "${_found}" -eq 0 ]]
then
_release_lock
_exit_1 printf "No alarm with ID %s.\\n" "${_target_id}"
fi
if [[ "${#_new_alarms[@]}" -eq 0 ]]
then
_ALARMS=()
: > "${NAG_PATH}"
else
_ALARMS=("${_new_alarms[@]}")
_write_alarms
fi
_release_lock
printf "Stopped alarm %s.\\n" "${_target_id}"
}
# at ##########################################################################
describe "at" <<HEREDOC

View file

@ -100,6 +100,52 @@ load test_helper
[[ "${output}" =~ "[1] Tomorrow, 3pm — take a break" ]]
}
@test "list shows empty message after stopping all alarms" {
run_nag at "tomorrow 3pm" "test alarm"
run_nag stop 1
[ "${status}" -eq 0 ]
run_nag
[[ "${output}" =~ "Nothing to nag about" ]]
}
@test "help stop shows stop usage" {
run_nag help stop
[ "${status}" -eq 0 ]
[[ "${output}" =~ "Usage:" ]]
[[ "${output}" =~ "stop <id>" ]]
}
@test "stop removes an alarm by ID" {
run_nag at "tomorrow 3pm" "take a break"
run_nag stop 1
[ "${status}" -eq 0 ]
[[ "${output}" =~ "Stopped alarm 1" ]]
run_nag
[[ "${output}" =~ "Nothing to nag about" ]]
}
@test "stop removes only the targeted alarm" {
run_nag at "tomorrow 3pm" "first"
run_nag at "tomorrow 4pm" "second"
run_nag at "tomorrow 5pm" "third"
run_nag stop 2
[ "${status}" -eq 0 ]
run_nag
[[ "${output}" =~ "first" ]]
[[ ! "${output}" =~ "second" ]]
[[ "${output}" =~ "third" ]]
}
@test "stop with nonexistent ID fails" {
run_nag stop 99
[ "${status}" -eq 1 ]
}
@test "stop without ID fails" {
run_nag stop
[ "${status}" -eq 1 ]
}
@test "list sorts alarms by time" {
run_nag at "tomorrow 3pm" "take a break"
run_nag at "tomorrow 9am" "standup"