Skip to content

fix(purge): restore cursor and temp files on any exit path (#915)#928

Merged
tw93 merged 1 commit into
tw93:mainfrom
sebastianbreguel:fix/purge-cursor-restore
May 22, 2026
Merged

fix(purge): restore cursor and temp files on any exit path (#915)#928
tw93 merged 1 commit into
tw93:mainfrom
sebastianbreguel:fix/purge-cursor-restore

Conversation

@sebastianbreguel
Copy link
Copy Markdown
Contributor

Summary

Fixes #915 (mo purge leaves the terminal cursor hidden after running).

bin/purge.sh hid the cursor before perform_purge and restored it via a single trailing show_cursor. Under set -euo pipefail, any abort path other than INT/TERM (e.g. an uncaught error inside perform_purge, a non-zero return, SIGHUP from closing the terminal) skipped that line, so the terminal stayed with the cursor invisible until the user ran tput cnorm themselves.

While fixing that I noticed the main()-scoped trap 'show_cursor; exit 130' INT TERM overwrote the existing file-scope trap cleanup_temp_files EXIT INT TERM. So a Ctrl-C during arg parsing (before perform_purge reinstalled its own trap) would also leak temp files — addressed as part of the same change.

Fix

Fold show_cursor into the file-scope cleanup function alongside cleanup_temp_files, and reinstall the traps in the same shape bin/installer.sh already uses (trap cleanup EXIT + an INT/TERM trap that explicitly calls cleanup before exit 130). The EXIT trap is the catch-all, so every exit path — normal, set -e abort, or signal — runs cleanup exactly once.

Diff is +7 / −6 in a single file.

-# Set up cleanup trap for temporary files
-trap cleanup_temp_files EXIT INT TERM
+# Restores cursor and clears temp files even when set -e aborts (#915).
+cleanup() {
+    show_cursor 2> /dev/null || true
+    cleanup_temp_files
+}
+trap cleanup EXIT
+trap 'trap - EXIT; cleanup; exit 130' INT TERM

…and the corresponding deletions inside main() (the redundant in-main() INT/TERM trap and the trailing show_cursor).

Why mirror installer.sh rather than clean.sh

The repo has three cleanup shapes today (installer.sh, clean.sh, uninstall.sh). installer.sh is the closest cousin to purge.sh — interactive UI, cursor hide/show, temp files, no need to pass the signal name to cleanup. Matching it keeps the variance between files lower.

Test plan

  • shellcheck bin/purge.sh — clean
  • bats tests/purge.bats tests/purge_config_paths.bats — 76/76 pass
  • bash bin/purge.sh --help — parses
  • Walked the worst case mentally: Ctrl-C mid-perform_purgehandle_interrupt runs show_cursor and exit 130exit fires the file-scope EXIT trap → cleanup calls show_cursor (idempotent) and cleanup_temp_files. Both windows (before and during perform_purge) are covered.

Not in scope

bin/clean.sh and bin/uninstall.sh already wrap show_cursor inside a file-scope cleanup, so they are not affected by this bug. Keeping this PR narrow to #915.

mo purge hid the cursor before perform_purge and restored it via a
single trailing show_cursor. Any abort path (set -e, uncaught error,
unhandled signal) skipped that line, leaving the terminal with the
cursor invisible until the user ran tput cnorm. The in-main
INT/TERM trap also overwrote the file-scope cleanup_temp_files trap,
so a Ctrl-C during arg parsing would have leaked temp files.

Fold show_cursor into the file-scope cleanup function alongside
cleanup_temp_files, and reinstall the trap chain in the
installer.sh shape (EXIT plus an INT/TERM trap that explicitly
calls cleanup before exit 130). The EXIT trap is the catch-all, so
every exit path — normal, set -e abort, or signal — restores the
cursor and clears temp files exactly once.
@sebastianbreguel sebastianbreguel requested a review from tw93 as a code owner May 18, 2026 15:33
@tw93 tw93 merged commit 11216af into tw93:main May 22, 2026
9 checks passed
@tw93
Copy link
Copy Markdown
Owner

tw93 commented May 22, 2026

@sebastianbreguel Thanks for the careful fix. Merged into main; this covers #915 and also keeps temp cleanup intact on exit paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Mole - Purge command can't show_cursor

2 participants