aboutsummaryrefslogtreecommitdiff
path: root/internal/engine/facts.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/engine/facts.go')
-rw-r--r--internal/engine/facts.go21
1 files changed, 19 insertions, 2 deletions
diff --git a/internal/engine/facts.go b/internal/engine/facts.go
index c510b20..f8fde89 100644
--- a/internal/engine/facts.go
+++ b/internal/engine/facts.go
@@ -5,6 +5,7 @@ package engine
import (
"context"
"errors"
+ "io/fs"
"path/filepath"
"sort"
"strings"
@@ -73,11 +74,27 @@ func (run *matchRun) drainDupErrors() {
defer run.mu.Unlock()
for _, idx := range run.dupIdx {
for _, ce := range idx.Errors() {
- run.warn = append(run.warn, "duplicate: "+xdg.Abbrev(ce.Path)+": "+ce.Err.Error())
+ run.warn = append(run.warn, dupWarning(ce))
}
}
}
+// dupWarning is the one form of a duplicate warning (triage 6): "duplicate:
+// PATH: cause", the path abbreviated like every other one shown, and an OS
+// error's cause without the raw path it would repeat.
+func dupWarning(err error) string {
+ var ce dup.CandidateError
+ if !errors.As(err, &ce) {
+ return "duplicate: " + err.Error()
+ }
+ cause := ce.Err.Error()
+ var pe *fs.PathError
+ if errors.As(ce.Err, &pe) {
+ cause = pe.Op + ": " + pe.Err.Error()
+ }
+ return "duplicate: " + xdg.Abbrev(ce.Path) + ": " + cause
+}
+
// dupIndex returns the shared *dup.Index for the resolved, sorted extra
// directories named by key, building it exactly once across every
// concurrent caller that asks for the same key.
@@ -95,7 +112,7 @@ func (run *matchRun) dupIndex(key string, dirs []string) *dup.Index {
run.mu.Lock()
run.dupIdx[key] = idx
for _, err := range errs {
- run.warn = append(run.warn, "duplicate: "+err.Error())
+ run.warn = append(run.warn, dupWarning(err))
}
run.mu.Unlock()
})