Compare commits

..
2 Commits
Author SHA1 Message Date
sneak 06d18f7839 Re-vendor the canonical files from sneak/prompts at dd4027b (closes #13)
check / check (push) Successful in 1m35s
`.dockerignore`, `.gitignore`, `.golangci.yml` and the workflow are their
copies at that commit. This repo's own entries are kept after the
canonical content: the anchored `/attrsum` binary, the Go entries in
`.gitignore`, and tabs for `*.go` in the new `.editorconfig`.
`REPO_POLICIES.md` is new. The workflow keeps `fetch-depth: 0`, which the
policies require of a repo that stamps a tag-derived version.

The lint phase moves to golangci-lint v2.14.0, which finds nothing in
the code. `script/fmt` now runs goimports with `go run` at its pinned
commit. A version-checked install by `script/bootstrap` would have to be
found on `PATH`, and the CI runner's `PATH` lacks Go's bin directory.

Model: opus-5-5
2026-10-06 06:28:21 +00:00
clawbot 9e55fd7113 Print the byte unit once in the summary line (closes #17)
check / check (push) Successful in 2m13s
formatBytes already ends in a unit, so the summary line read "9 B
bytes" or "1.0 KiB bytes". The format string in Stats.Print no longer
adds the word "bytes".

Print now takes the io.Writer to print to; its callers pass os.Stderr,
and the new test passes a buffer to read the line for one small and
one large byte count.

Model: opus-5-5
2026-10-06 08:27:08 +02:00
3 changed files with 33 additions and 6 deletions
+2
View File
@@ -31,6 +31,8 @@ Author are missing)
the lint phase runs golangci-lint v2.14.0; `script/fmt` runs the lint phase runs golangci-lint v2.14.0; `script/fmt` runs
goimports with `go run` at its pinned commit instead of goimports with `go run` at its pinned commit instead of
`script/bootstrap` installing it `script/bootstrap` installing it
* 2026-10-06: the summary line after `sum`, `check` and `clear` prints
the byte unit once (`1.5 KiB`, not `1.5 KiB bytes`)
* 2026-10-06: a path that `--exclude` or `--exclude-dotfiles` excludes * 2026-10-06: a path that `--exclude` or `--exclude-dotfiles` excludes
is skipped even when it cannot be read, so an excluded directory is skipped even when it cannot be read, so an excluded directory
that cannot be listed no longer fails the run that cannot be listed no longer fails the run
+6 -6
View File
@@ -71,13 +71,13 @@ func (s *Stats) Duration() time.Duration {
return time.Since(s.StartTime) return time.Since(s.StartTime)
} }
func (s *Stats) Print(opts *options, operation string) { func (s *Stats) Print(w io.Writer, opts *options, operation string) {
if opts.quiet { if opts.quiet {
return return
} }
fmt.Fprintf(os.Stderr, _, _ = fmt.Fprintf(w,
"\n%s complete: %d files processed, %d skipped, %d failed, %s bytes in %s\n", "\n%s complete: %d files processed, %d skipped, %d failed, %s in %s\n",
operation, operation,
s.FilesProcessed, s.FilesProcessed,
s.FilesSkipped, s.FilesSkipped,
@@ -227,7 +227,7 @@ func runOverPaths(
} }
finishBar(bar) finishBar(bar)
stats.Print(opts, op) stats.Print(os.Stderr, opts, op)
return nil return nil
} }
@@ -481,7 +481,7 @@ func runCheck(opts *options, args []string, cont bool) error {
if perr != nil { if perr != nil {
if !cont { if !cont {
finishBar(bar) finishBar(bar)
stats.Print(opts, "check") stats.Print(os.Stderr, opts, "check")
return perr return perr
} }
@@ -491,7 +491,7 @@ func runCheck(opts *options, args []string, cont bool) error {
} }
finishBar(bar) finishBar(bar)
stats.Print(opts, "check") stats.Print(os.Stderr, opts, "check")
return finalErr return finalErr
} }
+25
View File
@@ -1,6 +1,7 @@
package main package main
import ( import (
"bytes"
"errors" "errors"
"os" "os"
"path/filepath" "path/filepath"
@@ -376,3 +377,27 @@ func TestCheckContinuePastUnreadable(t *testing.T) {
t.Fatalf("expected verification error from runCheck, got %v", err) t.Fatalf("expected verification error from runCheck, got %v", err)
} }
} }
func TestSummaryPrintsByteUnitOnce(t *testing.T) {
t.Parallel()
tests := []struct {
bytesProcessed int64
want string
}{
{9, ", 9 B in "},
{1536, ", 1.5 KiB in "},
}
for _, tt := range tests {
var out bytes.Buffer
stats := newTestStats()
stats.BytesProcessed = tt.bytesProcessed
stats.Print(&out, &options{}, "check")
if !strings.Contains(out.String(), tt.want) {
t.Errorf("summary %q does not contain %q", out.String(), tt.want)
}
}
}