From 1f1a303c617057f149b4f0d748ee0a195484642c Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Mon, 14 Sep 2026 23:51:33 +0200 Subject: output: wrap by terminal columns, names cannot fake step lines, -v lists unscanned destinations --- internal/engine/match.go | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'internal') diff --git a/internal/engine/match.go b/internal/engine/match.go index 9f5ff12..6b98d73 100644 --- a/internal/engine/match.go +++ b/internal/engine/match.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "runtime" + "slices" "sort" "strings" "sync" @@ -54,6 +55,10 @@ type Result struct { Unmatched []FileMatch // no rule matched (Warnings may say why); sorted by File.Rel Skipped []scan.Skipped Warnings []string // directory-level, sorted; e.g. "duplicate: /x/y does not exist" + // Unscanned is every existing rule destination inside the root, which + // the walk leaves out (spec ยง8.1), so -v can say its files were not + // counted (triage 4). + Unscanned []string Elapsed time.Duration } @@ -124,12 +129,20 @@ func (e *Engine) Match(ctx context.Context, d *Dir) (*Result, error) { } sort.Strings(warnings) + var unscanned []string + for _, dir := range e.destinationDirs(d) { + if fi, err := os.Stat(dir); err == nil && fi.IsDir() && !slices.Contains(unscanned, dir) { + unscanned = append(unscanned, dir) + } + } + return &Result{ Dir: d, Matched: matched, Unmatched: unmatched, Skipped: wres.Skipped, Warnings: warnings, + Unscanned: unscanned, Elapsed: time.Since(started), }, nil } @@ -485,6 +498,19 @@ func isBusy(path string, suffixes []string) bool { // Acme/{mtime:%Y}" excludes "Work/Acme", and "Work/Acme-{mtime:%Y}" // (the placeholder mid-segment) excludes "Work". func (e *Engine) excludeDirs(d *Dir) []string { + out := e.destinationDirs(d) + root := filepath.Clean(d.Root) + for _, p := range []string{filepath.Join(xdg.DataHome(), "Trash"), filepath.Dir(e.MainFile)} { + if p = filepath.Clean(p); strings.HasPrefix(p, root+string(filepath.Separator)) { + out = append(out, p) + } + } + return out +} + +// destinationDirs is the rule-destination half of excludeDirs: every +// copy/move destination's static directory strictly inside d's root. +func (e *Engine) destinationDirs(d *Dir) []string { root := filepath.Clean(d.Root) var out []string add := func(p string) { @@ -515,7 +541,5 @@ func (e *Engine) excludeDirs(d *Dir) []string { add(plan.ResolveDir(prefix, root)) } } - add(filepath.Join(xdg.DataHome(), "Trash")) - add(filepath.Dir(e.MainFile)) return out } -- cgit v1.3