Initialize module and dependencies
This commit is contained in:
303
vendor/golang.org/x/vuln/internal/scan/flags.go
generated
vendored
Normal file
303
vendor/golang.org/x/vuln/internal/scan/flags.go
generated
vendored
Normal file
@@ -0,0 +1,303 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package scan
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/buildutil"
|
||||
"golang.org/x/vuln/internal/govulncheck"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
govulncheck.Config
|
||||
patterns []string
|
||||
db string
|
||||
dir string
|
||||
tags buildutil.TagsFlag
|
||||
test bool
|
||||
show ShowFlag
|
||||
format FormatFlag
|
||||
env []string
|
||||
}
|
||||
|
||||
func parseFlags(cfg *config, stderr io.Writer, args []string) error {
|
||||
var version bool
|
||||
var json bool
|
||||
var scanFlag ScanFlag
|
||||
var modeFlag ModeFlag
|
||||
flags := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
flags.SetOutput(stderr)
|
||||
flags.BoolVar(&json, "json", false, "output JSON (Go compatible legacy flag, see format flag)")
|
||||
flags.BoolVar(&cfg.test, "test", false, "analyze test files (only valid for source mode, default false)")
|
||||
flags.StringVar(&cfg.dir, "C", "", "change to `dir` before running govulncheck")
|
||||
flags.StringVar(&cfg.db, "db", "https://vuln.go.dev", "vulnerability database `url`")
|
||||
flags.Var(&modeFlag, "mode", "supports 'source', 'binary', and 'extract' (default 'source')")
|
||||
flags.Var(&cfg.tags, "tags", "comma-separated `list` of build tags")
|
||||
flags.Var(&cfg.show, "show", "enable display of additional information specified by the comma separated `list`\nThe supported values are 'traces','color', 'version', and 'verbose'")
|
||||
flags.Var(&cfg.format, "format", "specify format output\nThe supported values are 'text', 'json', 'sarif', and 'openvex' (default 'text')")
|
||||
flags.BoolVar(&version, "version", false, "print the version information")
|
||||
flags.Var(&scanFlag, "scan", "set the scanning level desired, one of 'module', 'package', or 'symbol' (default 'symbol')")
|
||||
|
||||
// We don't want to print the whole usage message on each flags
|
||||
// error, so we set to a no-op and do the printing ourselves.
|
||||
flags.Usage = func() {}
|
||||
usage := func() {
|
||||
fmt.Fprint(flags.Output(), `Govulncheck reports known vulnerabilities in dependencies.
|
||||
|
||||
Usage:
|
||||
|
||||
govulncheck [flags] [patterns]
|
||||
govulncheck -mode=binary [flags] [binary]
|
||||
|
||||
`)
|
||||
flags.PrintDefaults()
|
||||
fmt.Fprintf(flags.Output(), "\n%s\n", detailsMessage)
|
||||
}
|
||||
|
||||
if err := flags.Parse(args); err != nil {
|
||||
if err == flag.ErrHelp {
|
||||
usage() // print usage only on help
|
||||
return errHelp
|
||||
}
|
||||
return errUsage
|
||||
}
|
||||
cfg.patterns = flags.Args()
|
||||
if version {
|
||||
cfg.show = append(cfg.show, "version")
|
||||
}
|
||||
cfg.ScanLevel = govulncheck.ScanLevel(scanFlag)
|
||||
cfg.ScanMode = govulncheck.ScanMode(modeFlag)
|
||||
if err := validateConfig(cfg, json); err != nil {
|
||||
fmt.Fprintln(flags.Output(), err)
|
||||
return errUsage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateConfig(cfg *config, json bool) error {
|
||||
// take care of default values
|
||||
if cfg.ScanMode == "" {
|
||||
cfg.ScanMode = govulncheck.ScanModeSource
|
||||
}
|
||||
if cfg.ScanLevel == "" {
|
||||
cfg.ScanLevel = govulncheck.ScanLevelSymbol
|
||||
}
|
||||
if json {
|
||||
if cfg.format != formatUnset {
|
||||
return fmt.Errorf("the -json flag cannot be used with -format flag")
|
||||
}
|
||||
cfg.format = formatJSON
|
||||
} else {
|
||||
if cfg.format == formatUnset {
|
||||
cfg.format = formatText
|
||||
}
|
||||
}
|
||||
|
||||
// show flag is only supported with text output
|
||||
if cfg.format != formatText && len(cfg.show) > 0 {
|
||||
return fmt.Errorf("the -show flag is not supported for %s output", cfg.format)
|
||||
}
|
||||
|
||||
switch cfg.ScanMode {
|
||||
case govulncheck.ScanModeSource:
|
||||
if len(cfg.patterns) == 1 && isFile(cfg.patterns[0]) {
|
||||
return fmt.Errorf("%q is a file.\n\n%v", cfg.patterns[0], errNoBinaryFlag)
|
||||
}
|
||||
if cfg.ScanLevel == govulncheck.ScanLevelModule && len(cfg.patterns) != 0 {
|
||||
return fmt.Errorf("patterns are not accepted for module only scanning")
|
||||
}
|
||||
case govulncheck.ScanModeBinary:
|
||||
if cfg.test {
|
||||
return fmt.Errorf("the -test flag is not supported in binary mode")
|
||||
}
|
||||
if len(cfg.tags) > 0 {
|
||||
return fmt.Errorf("the -tags flag is not supported in binary mode")
|
||||
}
|
||||
if len(cfg.patterns) != 1 {
|
||||
return fmt.Errorf("only 1 binary can be analyzed at a time")
|
||||
}
|
||||
if !isFile(cfg.patterns[0]) {
|
||||
return fmt.Errorf("%q is not a file", cfg.patterns[0])
|
||||
}
|
||||
case govulncheck.ScanModeExtract:
|
||||
if cfg.test {
|
||||
return fmt.Errorf("the -test flag is not supported in extract mode")
|
||||
}
|
||||
if len(cfg.tags) > 0 {
|
||||
return fmt.Errorf("the -tags flag is not supported in extract mode")
|
||||
}
|
||||
if len(cfg.patterns) != 1 {
|
||||
return fmt.Errorf("only 1 binary can be extracted at a time")
|
||||
}
|
||||
if cfg.format == formatJSON {
|
||||
return fmt.Errorf("the json format must be off in extract mode")
|
||||
}
|
||||
if !isFile(cfg.patterns[0]) {
|
||||
return fmt.Errorf("%q is not a file (source extraction is not supported)", cfg.patterns[0])
|
||||
}
|
||||
case govulncheck.ScanModeConvert:
|
||||
if len(cfg.patterns) != 0 {
|
||||
return fmt.Errorf("patterns are not accepted in convert mode")
|
||||
}
|
||||
if cfg.dir != "" {
|
||||
return fmt.Errorf("the -C flag is not supported in convert mode")
|
||||
}
|
||||
if cfg.test {
|
||||
return fmt.Errorf("the -test flag is not supported in convert mode")
|
||||
}
|
||||
if len(cfg.tags) > 0 {
|
||||
return fmt.Errorf("the -tags flag is not supported in convert mode")
|
||||
}
|
||||
case govulncheck.ScanModeQuery:
|
||||
if cfg.test {
|
||||
return fmt.Errorf("the -test flag is not supported in query mode")
|
||||
}
|
||||
if len(cfg.tags) > 0 {
|
||||
return fmt.Errorf("the -tags flag is not supported in query mode")
|
||||
}
|
||||
if cfg.format != formatJSON {
|
||||
return fmt.Errorf("the json format must be set in query mode")
|
||||
}
|
||||
for _, pattern := range cfg.patterns {
|
||||
// Parse the input here so that we can catch errors before
|
||||
// outputting the Config.
|
||||
if _, _, err := parseModuleQuery(pattern); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isFile(path string) bool {
|
||||
s, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return !s.IsDir()
|
||||
}
|
||||
|
||||
var errFlagParse = errors.New("see -help for details")
|
||||
|
||||
// ShowFlag is used for parsing and validation of
|
||||
// govulncheck -show flag.
|
||||
type ShowFlag []string
|
||||
|
||||
var supportedShows = map[string]bool{
|
||||
"traces": true,
|
||||
"color": true,
|
||||
"verbose": true,
|
||||
"version": true,
|
||||
}
|
||||
|
||||
func (v *ShowFlag) Set(s string) error {
|
||||
if s == "" {
|
||||
return nil
|
||||
}
|
||||
for _, show := range strings.Split(s, ",") {
|
||||
sh := strings.TrimSpace(show)
|
||||
if _, ok := supportedShows[sh]; !ok {
|
||||
return errFlagParse
|
||||
}
|
||||
*v = append(*v, sh)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *ShowFlag) Get() interface{} { return *v }
|
||||
func (v *ShowFlag) String() string { return "" }
|
||||
|
||||
// Update the text handler h with values of the flag.
|
||||
func (v ShowFlag) Update(h *TextHandler) {
|
||||
for _, show := range v {
|
||||
switch show {
|
||||
case "traces":
|
||||
h.showTraces = true
|
||||
case "color":
|
||||
h.showColor = true
|
||||
case "version":
|
||||
h.showVersion = true
|
||||
case "verbose":
|
||||
h.showVerbose = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FormatFlag is used for parsing and validation of
|
||||
// govulncheck -format flag.
|
||||
type FormatFlag string
|
||||
|
||||
const (
|
||||
formatUnset = ""
|
||||
formatJSON = "json"
|
||||
formatText = "text"
|
||||
formatSarif = "sarif"
|
||||
formatOpenVEX = "openvex"
|
||||
)
|
||||
|
||||
var supportedFormats = map[string]bool{
|
||||
formatJSON: true,
|
||||
formatText: true,
|
||||
formatSarif: true,
|
||||
formatOpenVEX: true,
|
||||
}
|
||||
|
||||
func (f *FormatFlag) Get() interface{} { return *f }
|
||||
func (f *FormatFlag) Set(s string) error {
|
||||
if _, ok := supportedFormats[s]; !ok {
|
||||
return errFlagParse
|
||||
}
|
||||
*f = FormatFlag(s)
|
||||
return nil
|
||||
}
|
||||
func (f *FormatFlag) String() string { return "" }
|
||||
|
||||
// ModeFlag is used for parsing and validation of
|
||||
// govulncheck -mode flag.
|
||||
type ModeFlag string
|
||||
|
||||
var supportedModes = map[string]bool{
|
||||
govulncheck.ScanModeSource: true,
|
||||
govulncheck.ScanModeBinary: true,
|
||||
govulncheck.ScanModeConvert: true,
|
||||
govulncheck.ScanModeQuery: true,
|
||||
govulncheck.ScanModeExtract: true,
|
||||
}
|
||||
|
||||
func (f *ModeFlag) Get() interface{} { return *f }
|
||||
func (f *ModeFlag) Set(s string) error {
|
||||
if _, ok := supportedModes[s]; !ok {
|
||||
return errFlagParse
|
||||
}
|
||||
*f = ModeFlag(s)
|
||||
return nil
|
||||
}
|
||||
func (f *ModeFlag) String() string { return "" }
|
||||
|
||||
// ScanFlag is used for parsing and validation of
|
||||
// govulncheck -scan flag.
|
||||
type ScanFlag string
|
||||
|
||||
var supportedLevels = map[string]bool{
|
||||
govulncheck.ScanLevelModule: true,
|
||||
govulncheck.ScanLevelPackage: true,
|
||||
govulncheck.ScanLevelSymbol: true,
|
||||
}
|
||||
|
||||
func (f *ScanFlag) Get() interface{} { return *f }
|
||||
func (f *ScanFlag) Set(s string) error {
|
||||
if _, ok := supportedLevels[s]; !ok {
|
||||
return errFlagParse
|
||||
}
|
||||
*f = ScanFlag(s)
|
||||
return nil
|
||||
}
|
||||
func (f *ScanFlag) String() string { return "" }
|
||||
Reference in New Issue
Block a user