On a terminal, a warning for the last file of a phase erases the finished progress bar #102

Open
opened 2026-10-13 01:02:08 +02:00 by clawbot · 0 comments
Collaborator

On a terminal, when the last file a hash or content phase reads fails, the phase's finished bar line disappears: the warning overwrites it and nothing draws the bar again, so the screen shows the warning where the hash 100% ... line was. A warning in the middle of a phase is fine, because the next item redraws the bar on the line below. Off a terminal the plain lines are unaffected.

Where, at v1.0.0-rc1:

Reproduce, with stderr on a terminal (script -qfc shows the same):

d=$(mktemp -d); truncate -s 777 "$d/a" "$d/b"; chmod 000 "$d/b"
SFDUPES_DATABASE=$(mktemp -d)/db.sqlite ./sfdupes scan "$d"

Files are read in inode order, so b is read last. The terminal ends up showing hash /tmp/.../b: open /tmp/.../b: permission denied on the line where hash 100% |...| (2/2, ...) had just been drawn, then the update bar. README "Progress": each phase gets its own display and a warning lands on a line of its own, never inside it; here the warning replaces the phase's display.

Definition of done

  • After a phase's last item warns, the terminal still shows that phase's final bar frame ((2/2, in the example) and the warning on a line of its own.
  • A test in progress_test.go in the style of TestBarStoppedShortKeepsCount: a bar with total 2, two increment calls, one warnf, then finish; lastFrame(stderr()) must contain (2/2,. It fails before the fix and passes after.
  • Output when stderr is not a terminal is unchanged.

Severity: minor. One line of terminal output is lost; the log, the counts and the database are right.

Model: fable-5-1

On a terminal, when the last file a `hash` or `content` phase reads fails, the phase's finished bar line disappears: the warning overwrites it and nothing draws the bar again, so the screen shows the warning where the `hash 100% ...` line was. A warning in the middle of a phase is fine, because the next item redraws the bar on the line below. Off a terminal the plain lines are unaffected. Where, at `v1.0.0-rc1`: - `readRuns` increments the bar before it warns about the failed read: https://git.eeqj.de/sneak/sfdupes/src/tag/v1.0.0-rc1/scan.go#L576 and https://git.eeqj.de/sneak/sfdupes/src/tag/v1.0.0-rc1/scan.go#L581. The increment that reaches the total draws the finished bar. - `warnf` then clears the line and prints the warning over it: https://git.eeqj.de/sneak/sfdupes/src/tag/v1.0.0-rc1/progress.go#L138. `finish` draws nothing more once the library considers the bar finished: https://git.eeqj.de/sneak/sfdupes/src/tag/v1.0.0-rc1/progress.go#L156. Reproduce, with stderr on a terminal (`script -qfc` shows the same): ``` d=$(mktemp -d); truncate -s 777 "$d/a" "$d/b"; chmod 000 "$d/b" SFDUPES_DATABASE=$(mktemp -d)/db.sqlite ./sfdupes scan "$d" ``` Files are read in inode order, so `b` is read last. The terminal ends up showing `hash /tmp/.../b: open /tmp/.../b: permission denied` on the line where `hash 100% |...| (2/2, ...)` had just been drawn, then the `update` bar. README "Progress": each phase gets its own display and a warning lands on a line of its own, never inside it; here the warning replaces the phase's display. **Definition of done** - After a phase's last item warns, the terminal still shows that phase's final bar frame (`(2/2,` in the example) and the warning on a line of its own. - A test in `progress_test.go` in the style of `TestBarStoppedShortKeepsCount`: a bar with total 2, two `increment` calls, one `warnf`, then `finish`; `lastFrame(stderr())` must contain `(2/2,`. It fails before the fix and passes after. - Output when stderr is not a terminal is unchanged. Severity: minor. One line of terminal output is lost; the log, the counts and the database are right. Model: fable-5-1
Sign in to join this conversation.