summaryrefslogtreecommitdiff
path: root/internal/engine/facts.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-15 00:33:04 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-15 00:33:04 +0200
commiteb31377e43fb26a6726b741978db83453fcd7bdd (patch)
tree57837e8301f6bcecc11eb019512051d96fe3e496 /internal/engine/facts.go
parentccd6faf3d10da0669631fb3e3ba17a46b9e63a09 (diff)
downloadkrino-eb31377e43fb26a6726b741978db83453fcd7bdd.tar.gz
krino-eb31377e43fb26a6726b741978db83453fcd7bdd.zip
a rule's duplicate check failure shortens the path too
Diffstat (limited to 'internal/engine/facts.go')
-rw-r--r--internal/engine/facts.go38
1 files changed, 30 insertions, 8 deletions
diff --git a/internal/engine/facts.go b/internal/engine/facts.go
index 89bd71b..641f1ef 100644
--- a/internal/engine/facts.go
+++ b/internal/engine/facts.go
@@ -5,6 +5,7 @@ package engine
import (
"context"
"errors"
+ "fmt"
"io/fs"
"path/filepath"
"sort"
@@ -83,18 +84,39 @@ func (run *matchRun) drainDupErrors() {
// 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 {
+ return "duplicate: " + dupCause(err).Error()
+}
+
+// dupCause is a duplicate check's error as "PATH: cause", the path
+// shortened with xdg.Abbrev and not repeated inside the cause - a candidate
+// that could not be hashed, or an OS error on the file itself (plan 11
+// review L7). It still unwraps to err.
+func dupCause(err error) error {
+ path, cause := "", err
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()
+ switch {
+ case errors.As(err, &ce):
+ path, cause = ce.Path, ce.Err
+ if errors.As(ce.Err, &pe) {
+ cause = fmt.Errorf("%s: %w", pe.Op, pe.Err)
+ }
+ case errors.As(err, &pe):
+ path, cause = pe.Path, fmt.Errorf("%s: %w", pe.Op, pe.Err)
+ default:
+ return err
}
- return "duplicate: " + xdg.Abbrev(ce.Path) + ": " + cause
+ return shortenedErr{msg: xdg.Abbrev(path) + ": " + cause.Error(), err: err}
+}
+
+type shortenedErr struct {
+ msg string
+ err error
}
+func (e shortenedErr) Error() string { return e.msg }
+func (e shortenedErr) Unwrap() error { return e.err }
+
// 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.
@@ -263,7 +285,7 @@ func (f *facts) Duplicate(dirs []string) (string, bool, error) {
idx := f.run.dupIndex(key, sorted)
orig, isDup, err := idx.Lookup(f.file.Path)
if err != nil {
- return "", false, err
+ return "", false, dupCause(err)
}
if !isDup {
return "", false, nil