aboutsummaryrefslogtreecommitdiff
path: root/internal/engine/match.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/engine/match.go')
-rw-r--r--internal/engine/match.go42
1 files changed, 42 insertions, 0 deletions
diff --git a/internal/engine/match.go b/internal/engine/match.go
index e68a6e8..ffee7f0 100644
--- a/internal/engine/match.go
+++ b/internal/engine/match.go
@@ -33,6 +33,12 @@ type FileMatch struct {
File scan.File
Rules []RuleMatch // matching rules in order, ending at the first with (stop)
Warnings []string // "<rule>: <warning>", e.g. "acme: content unreadable: needs pdftotext, not installed"
+
+ // NoDelete is non-empty when no delete step may run for this file (spec
+ // §5.5 rule 2), and says why: the file is a duplicate under a scope its
+ // directory's rules use, or that check failed. Only set for a file some
+ // matching rule would delete.
+ NoDelete string
}
// Result is everything Match found in one directory.
@@ -127,9 +133,45 @@ func evalFile(run *matchRun, file scan.File) FileMatch {
break
}
}
+ if len(run.d.DupScopes) > 0 && deletes(fm.Rules) {
+ fm.NoDelete = noDelete(f, run.d.DupScopes)
+ }
return fm
}
+// NeverDeleted is the reason a duplicate's delete step is skipped (spec
+// §5.5).
+const NeverDeleted = "a duplicate is never deleted"
+
+// deletes reports whether any of rules has a delete action.
+func deletes(rules []RuleMatch) bool {
+ for _, rm := range rules {
+ for _, a := range rm.Rule.Conf.Actions {
+ if a.Kind == config.Delete || a.Kind == config.DeletePermanent {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+// noDelete looks f up under every scope, whether or not evaluating the
+// rules reached that test (spec §5.5 rule 2), and returns why f must not be
+// deleted, or "" when it may be. A failed lookup blocks the delete too:
+// krino cannot show the file is not a duplicate, so it keeps it.
+func noDelete(f *facts, scopes [][]string) string {
+ for _, dirs := range scopes {
+ _, dup, err := f.Duplicate(dirs)
+ if err != nil {
+ return "duplicate check failed, so not deleted: " + err.Error()
+ }
+ if dup {
+ return NeverDeleted
+ }
+ }
+ return ""
+}
+
// RuleTrace is one rule's outcome in an Explain call.
type RuleTrace struct {
Rule *Rule