diff options
Diffstat (limited to 'internal/engine/match.go')
| -rw-r--r-- | internal/engine/match.go | 42 |
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 |
