vet/query.go
abhisek 1dba6fdd8e
refactor: Parser to use dependency graph parsers
feat: Add npm package-lock.json graph parser

fix: Npm graph parser path to root traversal

fix: File naming convention for npm graph parser

feat: Add reporter for graph visualization in dot format

feat: Add support for showing dependency upgrade path in summary report

fix: Bug in summary reporter related to random ordering of entries with same score

chore: Add support for experimental flag in scanner config

refactor: Test cases or npm package name extractor into utils

feat: Add support for dependency graph data in CSV report generator

fix: LFP npm handle package links

test: Improve test for npm name extraction

feat: Add support for reconstructing dependency graph using insights data

fix: purl reader to use package manifest builder

test: Add E2E for gradle dependency graph reconstruction

fix: Handle root node marking heuristics for enriched dependency graph

feat: Allow query command to generate dependency graph

fix: Scanner dependency graph reconstruction using dependency distance

fix: Test case for maven dependency graph reconstruction

chore: Improve summary report text for dependency path to root

refactor: Code re-use in npm graph to find by semver range
2024-01-15 00:20:56 +05:30

198 lines
5.4 KiB
Go

package main
import (
"time"
"github.com/safedep/dry/utils"
"github.com/safedep/vet/pkg/analyzer"
"github.com/safedep/vet/pkg/readers"
"github.com/safedep/vet/pkg/reporter"
"github.com/safedep/vet/pkg/scanner"
"github.com/spf13/cobra"
)
var (
queryFilterExpression string
queryFilterSuiteFile string
queryFilterFailOnMatch bool
queryLoadDirectory string
queryEnableConsoleReport bool
queryEnableSummaryReport bool
querySummaryReportMaxAdvice int
queryMarkdownReportPath string
queryJsonReportPath string
queryGraphReportPath string
queryCsvReportPath string
queryExceptionsFile string
queryExceptionsTill string
queryExceptionsFilter string
queryDefaultExceptionExpiry = time.Now().Add(90 * 24 * time.Hour)
)
func newQueryCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "query",
Short: "Query JSON dump and run filters or render reports",
RunE: func(cmd *cobra.Command, args []string) error {
startQuery()
return nil
},
}
cmd.Flags().StringVarP(&queryLoadDirectory, "from", "F", "",
"The directory to load JSON dump files")
cmd.Flags().StringVarP(&queryFilterExpression, "filter", "", "",
"Filter and print packages using CEL")
cmd.Flags().StringVarP(&queryFilterSuiteFile, "filter-suite", "", "",
"Filter packages using CEL Filter Suite from file")
cmd.Flags().BoolVarP(&queryFilterFailOnMatch, "filter-fail", "", false,
"Fail the command if filter matches any package (for security gate)")
cmd.Flags().StringVarP(&queryExceptionsFile, "exceptions-generate", "", "",
"Generate exception records to file (YAML)")
cmd.Flags().StringVarP(&queryExceptionsTill, "exceptions-till", "",
queryDefaultExceptionExpiry.Format("2006-01-02"),
"Generated exceptions are valid till")
cmd.Flags().StringVarP(&queryExceptionsFilter, "exceptions-filter", "", "",
"Generate exception records for packages matching filter")
cmd.Flags().BoolVarP(&queryEnableConsoleReport, "report-console", "", false,
"Minimal summary of package manifest")
cmd.Flags().BoolVarP(&queryEnableSummaryReport, "report-summary", "", false,
"Show an actionable summary based on scan data")
cmd.Flags().IntVarP(&querySummaryReportMaxAdvice, "report-summary-max-advice", "", 5,
"Maximum number of package risk advice to show")
cmd.Flags().StringVarP(&queryMarkdownReportPath, "report-markdown", "", "",
"Generate markdown report to file")
cmd.Flags().StringVarP(&queryJsonReportPath, "report-json", "", "",
"Generate JSON report to file (EXPERIMENTAL)")
cmd.Flags().StringVarP(&queryGraphReportPath, "report-graph", "", "",
"Generate dependency graph as graphviz dot files to directory")
cmd.Flags().StringVarP(&queryCsvReportPath, "report-csv", "", "",
"Generate CSV report of filtered packages to file")
return cmd
}
func startQuery() {
failOnError("query", internalStartQuery())
}
func internalStartQuery() error {
readerList := []readers.PackageManifestReader{}
analyzers := []analyzer.Analyzer{}
reporters := []reporter.Reporter{}
enrichers := []scanner.PackageMetaEnricher{}
reader, err := readers.NewJsonDumpReader(queryLoadDirectory)
if err != nil {
return err
}
readerList = append(readerList, reader)
if !utils.IsEmptyString(queryFilterExpression) {
task, err := analyzer.NewCelFilterAnalyzer(queryFilterExpression,
queryFilterFailOnMatch)
if err != nil {
return err
}
analyzers = append(analyzers, task)
}
if !utils.IsEmptyString(queryFilterSuiteFile) {
task, err := analyzer.NewCelFilterSuiteAnalyzer(queryFilterSuiteFile,
queryFilterFailOnMatch)
if err != nil {
return err
}
analyzers = append(analyzers, task)
}
if !utils.IsEmptyString(queryExceptionsFile) {
task, err := analyzer.NewExceptionsGenerator(analyzer.ExceptionsGeneratorConfig{
Path: queryExceptionsFile,
ExpiresOn: queryExceptionsTill,
Filter: queryExceptionsFilter,
})
if err != nil {
return err
}
analyzers = append(analyzers, task)
}
if queryEnableConsoleReport {
rp, err := reporter.NewConsoleReporter()
if err != nil {
return err
}
reporters = append(reporters, rp)
}
if queryEnableSummaryReport {
rp, err := reporter.NewSummaryReporter(reporter.SummaryReporterConfig{
MaxAdvice: querySummaryReportMaxAdvice,
})
if err != nil {
return err
}
reporters = append(reporters, rp)
}
if !utils.IsEmptyString(queryMarkdownReportPath) {
rp, err := reporter.NewMarkdownReportGenerator(reporter.MarkdownReportingConfig{
Path: queryMarkdownReportPath,
})
if err != nil {
return err
}
reporters = append(reporters, rp)
}
if !utils.IsEmptyString(queryJsonReportPath) {
rp, err := reporter.NewJsonReportGenerator(reporter.JsonReportingConfig{
Path: queryJsonReportPath,
})
if err != nil {
return err
}
reporters = append(reporters, rp)
}
if !utils.IsEmptyString(queryCsvReportPath) {
rp, err := reporter.NewCsvReporter(reporter.CsvReportingConfig{
Path: queryCsvReportPath,
})
if err != nil {
return err
}
reporters = append(reporters, rp)
}
if !utils.IsEmptyString(queryGraphReportPath) {
rp, err := reporter.NewDotGraphReporter(queryGraphReportPath)
if err != nil {
return err
}
reporters = append(reporters, rp)
}
pmScanner := scanner.NewPackageManifestScanner(scanner.Config{
TransitiveAnalysis: false,
}, readerList, enrichers, analyzers, reporters)
redirectLogToFile(logFile)
return pmScanner.Start()
}