mirror of
https://github.com/anchore/grype
synced 2024-11-10 06:34:13 +00:00
Disable ETUI when piping input (#463)
* disable etui when piping input Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * restore jotframe version Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * remove test code Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * raise error from IsPipedInput Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * factor out verbosity check to function Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
19a513a42a
commit
f75889c694
4 changed files with 63 additions and 29 deletions
21
cmd/root.go
21
cmd/root.go
|
@ -183,10 +183,21 @@ func rootExec(_ *cobra.Command, args []string) error {
|
|||
setupSignals(),
|
||||
eventSubscription,
|
||||
stereoscope.Cleanup,
|
||||
ui.Select(appConfig.CliOptions.Verbosity > 0, appConfig.Quiet, reporter)...,
|
||||
ui.Select(isVerbose(), appConfig.Quiet, reporter)...,
|
||||
)
|
||||
}
|
||||
|
||||
func isVerbose() (result bool) {
|
||||
isPipedInput, err := internal.IsPipedInput()
|
||||
if err != nil {
|
||||
// since we can't tell if there was piped input we assume that there could be to disable the ETUI
|
||||
log.Warnf("unable to determine if there is piped input: %+v", err)
|
||||
return true
|
||||
}
|
||||
// verbosity should consider if there is piped input (in which case we should not show the ETUI)
|
||||
return appConfig.CliOptions.Verbosity > 0 || isPipedInput
|
||||
}
|
||||
|
||||
// nolint:funlen
|
||||
func startWorker(userInput string, failOnSeverity *vulnerability.Severity) <-chan error {
|
||||
errs := make(chan error)
|
||||
|
@ -278,7 +289,13 @@ func startWorker(userInput string, failOnSeverity *vulnerability.Severity) <-cha
|
|||
}
|
||||
|
||||
func validateRootArgs(cmd *cobra.Command, args []string) error {
|
||||
if len(args) == 0 && !internal.IsPipedInput() {
|
||||
isPipedInput, err := internal.IsPipedInput()
|
||||
if err != nil {
|
||||
log.Warnf("unable to determine if there is piped input: %+v", err)
|
||||
isPipedInput = false
|
||||
}
|
||||
|
||||
if len(args) == 0 && !isPipedInput {
|
||||
// in the case that no arguments are given and there is no piped input we want to show the help text and return with a non-0 return code.
|
||||
if err := cmd.Help(); err != nil {
|
||||
return fmt.Errorf("unable to display help: %w", err)
|
||||
|
|
|
@ -8,6 +8,8 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/anchore/grype/internal/log"
|
||||
|
||||
"github.com/anchore/grype/internal"
|
||||
"github.com/anchore/stereoscope/pkg/image"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
|
@ -47,7 +49,13 @@ func Provide(userInput string, scopeOpt source.Scope, registryOptions *image.Reg
|
|||
}
|
||||
|
||||
func bytesFromStdin() []byte {
|
||||
if internal.IsPipedInput() {
|
||||
isPipedInput, err := internal.IsPipedInput()
|
||||
if err != nil {
|
||||
log.Warnf("unable to determine if there is piped input: %+v", err)
|
||||
isPipedInput = false
|
||||
}
|
||||
|
||||
if isPipedInput {
|
||||
capturedStdin, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return nil
|
||||
|
|
|
@ -132,35 +132,38 @@ func (cfg *Application) parseScopeOption() error {
|
|||
}
|
||||
|
||||
func (cfg *Application) parseLogLevelOption() error {
|
||||
if cfg.Quiet {
|
||||
switch {
|
||||
case cfg.Quiet:
|
||||
// TODO: this is bad: quiet option trumps all other logging options (such as to a file on disk)
|
||||
// we should be able to quiet the console logging and leave file logging alone...
|
||||
// ... this will be an enhancement for later
|
||||
cfg.Log.LevelOpt = logrus.PanicLevel
|
||||
} else {
|
||||
if cfg.Log.Level != "" {
|
||||
if cfg.CliOptions.Verbosity > 0 {
|
||||
return fmt.Errorf("cannot explicitly set log level (cfg file or env var) and use -v flag together")
|
||||
}
|
||||
case cfg.Log.Level != "":
|
||||
if cfg.CliOptions.Verbosity > 0 {
|
||||
return fmt.Errorf("cannot explicitly set log level (cfg file or env var) and use -v flag together")
|
||||
}
|
||||
|
||||
lvl, err := logrus.ParseLevel(strings.ToLower(cfg.Log.Level))
|
||||
if err != nil {
|
||||
return fmt.Errorf("bad log level configured (%q): %w", cfg.Log.Level, err)
|
||||
}
|
||||
// set the log level explicitly
|
||||
cfg.Log.LevelOpt = lvl
|
||||
} else {
|
||||
// set the log level implicitly
|
||||
switch v := cfg.CliOptions.Verbosity; {
|
||||
case v == 1:
|
||||
cfg.Log.LevelOpt = logrus.InfoLevel
|
||||
case v >= 2:
|
||||
cfg.Log.LevelOpt = logrus.DebugLevel
|
||||
default:
|
||||
cfg.Log.LevelOpt = logrus.ErrorLevel
|
||||
}
|
||||
lvl, err := logrus.ParseLevel(strings.ToLower(cfg.Log.Level))
|
||||
if err != nil {
|
||||
return fmt.Errorf("bad log level configured (%q): %w", cfg.Log.Level, err)
|
||||
}
|
||||
|
||||
cfg.Log.LevelOpt = lvl
|
||||
if cfg.Log.LevelOpt >= logrus.InfoLevel {
|
||||
cfg.CliOptions.Verbosity = 1
|
||||
}
|
||||
default:
|
||||
|
||||
switch v := cfg.CliOptions.Verbosity; {
|
||||
case v == 1:
|
||||
cfg.Log.LevelOpt = logrus.InfoLevel
|
||||
case v >= 2:
|
||||
cfg.Log.LevelOpt = logrus.DebugLevel
|
||||
default:
|
||||
cfg.Log.LevelOpt = logrus.ErrorLevel
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
package internal
|
||||
|
||||
import "os"
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
// IsPipedInput returns true if there is no input device, which means the user **may** be providing input via a pipe.
|
||||
func IsPipedInput() bool {
|
||||
fi, _ := os.Stdin.Stat()
|
||||
func IsPipedInput() (bool, error) {
|
||||
fi, err := os.Stdin.Stat()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("unable to determine if there is piped input: %w", err)
|
||||
}
|
||||
|
||||
return fi.Mode()&os.ModeNamedPipe != 0
|
||||
return fi.Mode()&os.ModeCharDevice == 0, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue