1 Commits
Author SHA1 Message Date
clawbot 510b545ae5 trees: show its phases as N of M, with progress, elapsed time and ETA (closes #113)
check / check (push) Canceled after 0s
trees now runs in four phases, open, read, group and write, each under
the progress display scan uses, until the summary line. open covers a
wait on a busy database. read counts the records and reads them in one
read-only transaction, so the two agree during a scan; group counts the
directories, and write the groups. The rows reach stdout through a
writer that clears the display and holds its lock while writing, so no
row shares a line with the display on a shared terminal. Each rate
names what its phase counts.

Judgement call: opening the database is a phase of its own, so there are four phases, not the three the issue sketches.

Model: opus-5-5
2026-10-16 17:58:04 +00:00
3 changed files with 11 additions and 6 deletions
+2 -2
View File
@@ -410,8 +410,8 @@ func userVersion(ctx context.Context, db *sql.DB) (int, error) {
func loadFileRows(ctx context.Context, db *sql.DB, total func(n int64),
fn func(r scanRec),
) error {
// Everything goes through tx: the report connection is the only
// one, so a query on db would wait for tx forever.
// Everything goes through tx: db has one connection, so a query on
// db would wait for tx forever.
tx, err := db.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
if err != nil {
return fmt.Errorf("read records: %w", err)
+1 -1
View File
@@ -297,7 +297,7 @@ func (p *progress) warnf(format string, args ...any) {
// "sfdupes trees". It holds what is written to it and writes that to
// out in pieces of about ioBufSize bytes, each under the display's
// lock with the display cleared first, as warnf does for a warning: no
// draw lands in the middle of a piece, and the next one shows the
// draw lands in the middle of a piece, and the next draw shows the
// display again, on the line below. Every write to it must end with a
// newline, as a row written with one fmt.Fprintf does, so that each
// piece ends a line. Flush writes what it holds once the last row is
+8 -3
View File
@@ -5,7 +5,6 @@ import (
"math"
"os"
"path/filepath"
"slices"
"strings"
"testing"
"time"
@@ -613,8 +612,14 @@ func TestProgressWriterRowsOnOwnLines(t *testing.T) {
}
}
if !slices.Equal(shown, want) {
t.Errorf("terminal shows rows %q, want %q", shown, want)
if len(shown) != len(want) {
t.Fatalf("terminal shows %d rows, want %d", len(shown), len(want))
}
for i := range want {
if shown[i] != want[i] {
t.Fatalf("terminal shows %q, want %q", shown[i], want[i])
}
}
}