From 5896cc079e6315bd10c922206dfff29971c62907 Mon Sep 17 00:00:00 2001 From: Pranav Gaikwad Date: Mon, 13 Jan 2025 09:01:48 -0500 Subject: [PATCH] :sparkles: add new scope for excluded patterns [Part 1] (#758) This only does post discovery filtering. We need to do pre-filtering which is incoming in another PR. --------- Signed-off-by: Pranav Gaikwad --- engine/conditions.go | 5 ++-- engine/scopes.go | 55 ++++++++++++++++++++++++++++++++++++++++++++ provider/provider.go | 4 ++-- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/engine/conditions.go b/engine/conditions.go index e09130c0..da796be0 100644 --- a/engine/conditions.go +++ b/engine/conditions.go @@ -311,6 +311,7 @@ func gatherChain(start ConditionEntry, entries []ConditionEntry) []ConditionEntr // Chain Templates are used by rules and providers to pass context around during rule execution. type ChainTemplate struct { - Filepaths []string `yaml:"filepaths"` - Extras map[string]interface{} `yaml:"extras"` + Filepaths []string `yaml:"filepaths,omitempty"` + Extras map[string]interface{} `yaml:"extras,omitempty"` + ExcludedPaths []string `yaml:"excludedPaths,omitempty"` } diff --git a/engine/scopes.go b/engine/scopes.go index b5488b99..2bf0a2ac 100644 --- a/engine/scopes.go +++ b/engine/scopes.go @@ -2,8 +2,11 @@ package engine import ( "fmt" + "net/url" + "regexp" "github.com/go-logr/logr" + "go.lsp.dev/uri" ) const TemplateContextPathScopeKey = "konveyor.io/path-scope" @@ -92,6 +95,10 @@ func (i *includedPathScope) AddToContext(conditionCTX *ConditionContext) error { } func (i *includedPathScope) FilterResponse(response IncidentContext) bool { + // when there are no included paths set, everything is included + if len(i.paths) == 0 { + return false + } for _, path := range i.paths { if string(response.FileURI) != "" && response.FileURI.Filename() == path { return false @@ -106,3 +113,51 @@ func IncludedPathsScope(paths []string, log logr.Logger) Scope { log: log, } } + +type excludedPathsScope struct { + paths []string + log logr.Logger +} + +var _ Scope = &excludedPathsScope{} + +func (e *excludedPathsScope) Name() string { + return "ExcludedPathsScope" +} + +func (e *excludedPathsScope) AddToContext(conditionCtx *ConditionContext) error { + templ := ChainTemplate{} + if existingTempl, ok := conditionCtx.Template[TemplateContextPathScopeKey]; ok { + templ = existingTempl + } + templ.ExcludedPaths = e.paths + conditionCtx.Template[TemplateContextPathScopeKey] = templ + return nil +} + +func (e *excludedPathsScope) FilterResponse(response IncidentContext) bool { + if response.FileURI == "" { + return false + } + for _, path := range e.paths { + e.log.V(5).Info("using path for filtering response", "path", path) + pattern, err := regexp.Compile(path) + if err != nil { + e.log.V(5).Error(err, "invalid pattern", "pattern", path) + continue + } + u, err := url.ParseRequestURI(string(response.FileURI)) + if err == nil && u.Scheme == uri.FileScheme && pattern.MatchString(response.FileURI.Filename()) { + e.log.V(5).Info("excluding the file", "file", response.FileURI.Filename(), "pattern", pattern) + return true + } + } + return false +} + +func ExcludedPathsScope(paths []string, log logr.Logger) Scope { + return &excludedPathsScope{ + paths: paths, + log: log.WithName("excludedPathScope"), + } +} diff --git a/provider/provider.go b/provider/provider.go index 81d9576e..55d4e67a 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -334,8 +334,8 @@ type ProviderContext struct { } func (p *ProviderContext) GetScopedFilepaths() (bool, []string) { - for key, value := range p.Template { - if key == engine.TemplateContextPathScopeKey { + if value, ok := p.Template[engine.TemplateContextPathScopeKey]; ok { + if len(value.Filepaths) > 0 { return true, value.Filepaths } }