Refactor filter stat in common code

This commit is contained in:
abhisek 2023-02-19 18:25:28 +05:30
parent e8cebfa539
commit b37834af74
No known key found for this signature in database
GPG Key ID: CB92A4990C02A88F
4 changed files with 88 additions and 18 deletions

View File

@ -31,11 +31,15 @@ Filter expressions get the following input data to work with
| `licenses` | Holds a list of liceses in SPDX license code format |
Refer to [filter input spec](../api/filter_input_spec.proto) for detailed
structure of input messages.
## Expressions
Expressions are [CEL](https://github.com/google/cel-spec) statements. While
CEL internals are not required, an [introductory](https://github.com/google/cel-spec/blob/master/doc/intro.md)
knowledge of CEL will help formulating queries.
knowledge of CEL will help formulating queries. Expressions are logical
statements that evaluate to `true` or `false`.
### Example Queries

View File

@ -5,7 +5,6 @@ import (
"os"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
"github.com/safedep/dry/utils"
"github.com/safedep/vet/pkg/analyzer/filter"
"github.com/safedep/vet/pkg/common/logger"
@ -17,13 +16,7 @@ type celFilterAnalyzer struct {
failOnMatch bool
packages map[string]*models.Package
stat struct {
manifests int
packages int
matched int
err int
}
stat celFilterStat
}
func NewCelFilterAnalyzer(fl string, failOnMatch bool) (Analyzer, error) {
@ -41,6 +34,7 @@ func NewCelFilterAnalyzer(fl string, failOnMatch bool) (Analyzer, error) {
evaluator: evaluator,
failOnMatch: failOnMatch,
packages: make(map[string]*models.Package),
stat: celFilterStat{},
}, nil
}
@ -52,17 +46,19 @@ func (f *celFilterAnalyzer) Analyze(manifest *models.PackageManifest,
handler AnalyzerEventHandler) error {
logger.Infof("CEL filtering manifest: %s", manifest.Path)
f.stat.manifests += 1
f.stat.IncScannedManifest()
for _, pkg := range manifest.Packages {
f.stat.packages += 1
f.stat.IncEvaluatedPackage()
res, err := f.evaluator.EvalPackage(pkg)
if err != nil {
f.stat.err += 1
f.stat.IncError(err)
logger.Errorf("Failed to evaluate CEL for %s:%s : %v",
pkg.PackageDetails.Name,
pkg.PackageDetails.Version, err)
continue
}
@ -72,7 +68,7 @@ func (f *celFilterAnalyzer) Analyze(manifest *models.PackageManifest,
continue
}
f.stat.matched += 1
f.stat.IncMatchedPackage()
f.packages[pkg.Id()] = pkg
}
}
@ -95,10 +91,7 @@ func (f *celFilterAnalyzer) Finish() error {
})
}
fmt.Printf("%s\n", text.Bold.Sprint("Filter evaluated with ",
f.stat.matched, " out of ", f.stat.packages, " uniquely matched and ",
f.stat.err, " error(s) ", "across ", f.stat.manifests,
" manifest(s)"))
f.stat.PrintStatMessage(os.Stderr)
tbl.Render()
return nil
@ -106,7 +99,7 @@ func (f *celFilterAnalyzer) Finish() error {
func (f *celFilterAnalyzer) notifyCaller(manifest *models.PackageManifest,
handler AnalyzerEventHandler) error {
if f.failOnMatch && (f.stat.matched > 0) {
if f.failOnMatch && (len(f.packages) > 0) {
handler(&AnalyzerEvent{
Source: f.Name(),
Type: ET_AnalyzerFailOnError,

View File

@ -8,6 +8,7 @@ import (
"github.com/safedep/dry/utils"
"github.com/safedep/vet/gen/filtersuite"
"github.com/safedep/vet/pkg/analyzer/filter"
"github.com/safedep/vet/pkg/common/logger"
"github.com/safedep/vet/pkg/models"
)
@ -21,6 +22,7 @@ type celFilterSuiteAnalyzer struct {
suite *filtersuite.FilterSuite
failOnMatch bool
matchedPackages map[string]*celFilterMatchedPackage
stat celFilterStat
}
func NewCelFilterSuiteAnalyzer(path string, failOnMatch bool) (Analyzer, error) {
@ -46,6 +48,7 @@ func NewCelFilterSuiteAnalyzer(path string, failOnMatch bool) (Analyzer, error)
suite: fs,
failOnMatch: failOnMatch,
matchedPackages: make(map[string]*celFilterMatchedPackage),
stat: celFilterStat{},
}, nil
}
@ -56,9 +59,20 @@ func (f *celFilterSuiteAnalyzer) Name() string {
func (f *celFilterSuiteAnalyzer) Analyze(manifest *models.PackageManifest,
handler AnalyzerEventHandler) error {
logger.Infof("CEL Filter Suite: Analyzing manifest: %s", manifest.Path)
f.stat.IncScannedManifest()
for _, pkg := range manifest.Packages {
f.stat.IncEvaluatedPackage()
res, err := f.evaluator.EvalPackage(pkg)
if err != nil {
f.stat.IncError(err)
logger.Errorf("Failed to evaluate CEL for %s:%s : %v",
pkg.PackageDetails.Name,
pkg.PackageDetails.Version, err)
continue
}
@ -102,6 +116,7 @@ func (f *celFilterSuiteAnalyzer) renderMatchTable() {
})
}
f.stat.PrintStatMessage(os.Stderr)
tbl.Render()
}
@ -111,6 +126,7 @@ func (f *celFilterSuiteAnalyzer) queueMatchedPkg(pkg *models.Package,
return
}
f.stat.IncMatchedPackage()
f.matchedPackages[pkg.Id()] = &celFilterMatchedPackage{
filterName: filterName,
pkg: pkg,
@ -122,6 +138,8 @@ func (f *celFilterSuiteAnalyzer) queueMatchedPkg(pkg *models.Package,
// officially supported yamlpb, equivalent to jsonpb, we convert YAML
// to JSON before unmarshalling it into a protobuf message
func loadFilterSuiteFromFile(path string) (*filtersuite.FilterSuite, error) {
logger.Debugf("CEL Filter Suite: Loading suite from file: %s", path)
file, err := os.Open(path)
if err != nil {
return nil, err

View File

@ -0,0 +1,55 @@
package analyzer
import (
"fmt"
"io"
"github.com/jedib0t/go-pretty/v6/text"
)
type celFilterStat struct {
evaluatedManifests int
evaluatedPackages int
matchedPackages int
errCount int
}
func (s *celFilterStat) IncScannedManifest() {
s.evaluatedManifests += 1
}
func (s *celFilterStat) IncEvaluatedPackage() {
s.evaluatedPackages += 1
}
func (s *celFilterStat) IncMatchedPackage() {
s.matchedPackages += 1
}
func (s *celFilterStat) IncError(_ error) {
s.errCount += 1
}
func (s *celFilterStat) EvaluatedManifests() int {
return s.evaluatedManifests
}
func (s *celFilterStat) EvaluatedPackages() int {
return s.evaluatedPackages
}
func (s *celFilterStat) MatchedPackages() int {
return s.matchedPackages
}
func (s *celFilterStat) ErrorCount() int {
return s.errCount
}
func (s *celFilterStat) PrintStatMessage(writer io.Writer) {
fmt.Fprintf(writer, "%s\n", text.Bold.Sprint("Filter evaluated with ",
s.matchedPackages, " out of ", s.evaluatedPackages, " uniquely matched and ",
s.errCount, " error(s) ", "across ", s.evaluatedManifests,
" manifest(s)"))
}