Преглед на файлове

Merge pull request #1532 from chris-crone/fix-scan-msg

Fix scan message with quiet flag
Nicolas De loof преди 4 години
родител
ревизия
5841e75cb2
променени са 8 файла, в които са добавени 77 реда и са изтрити 10 реда
  1. 2 0
      api/compose/api.go
  2. 1 0
      cli/cmd/compose/build.go
  3. 11 0
      cli/metrics/metrics.go
  4. 30 0
      cli/metrics/metrics_test.go
  5. 1 1
      cli/mobycli/exec.go
  6. 1 1
      local/compose/build.go
  7. 30 6
      local/e2e/compose/scan_message_test.go
  8. 1 2
      utils/scan_suggest.go

+ 2 - 0
api/compose/api.go

@@ -86,6 +86,8 @@ type BuildOptions struct {
 	Args types.Mapping
 	// NoCache disables cache use
 	NoCache bool
+	// Quiet make the build process not output to the console
+	Quiet bool
 }
 
 // CreateOptions group options of the Create API

+ 1 - 0
cli/cmd/compose/build.go

@@ -97,6 +97,7 @@ func runBuild(ctx context.Context, opts buildOptions, services []string) error {
 			Progress: opts.progress,
 			Args:     types.NewMapping(opts.args),
 			NoCache:  opts.noCache,
+			Quiet:    opts.quiet,
 		})
 	})
 	return err

+ 11 - 0
cli/metrics/metrics.go

@@ -57,6 +57,17 @@ func isCommandFlag(word string) bool {
 	return utils.StringContains(commandFlags, word)
 }
 
+// HasQuietFlag returns true if one of the arguments is `--quiet` or `-q`
+func HasQuietFlag(args []string) bool {
+	for _, a := range args {
+		switch a {
+		case "--quiet", "-q":
+			return true
+		}
+	}
+	return false
+}
+
 // GetCommand get the invoked command
 func GetCommand(args []string) string {
 	result := ""

+ 30 - 0
cli/metrics/metrics_test.go

@@ -22,6 +22,36 @@ import (
 	"gotest.tools/v3/assert"
 )
 
+func TestHasQuietFlag(t *testing.T) {
+	cases := []struct {
+		name     string
+		args     []string
+		expected bool
+	}{
+		{
+			name:     "long flag",
+			args:     []string{"build", "-t", "tag", "--quiet", "."},
+			expected: true,
+		},
+		{
+			name:     "short flag",
+			args:     []string{"build", "-t", "tag", "-q", "."},
+			expected: true,
+		},
+		{
+			name:     "no flag",
+			args:     []string{"build", "-t", "tag", "."},
+			expected: false,
+		},
+	}
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			result := HasQuietFlag(c.args)
+			assert.Equal(t, c.expected, result)
+		})
+	}
+}
+
 func TestGetCommand(t *testing.T) {
 	testCases := []struct {
 		name     string

+ 1 - 1
cli/mobycli/exec.go

@@ -80,7 +80,7 @@ func Exec(root *cobra.Command) {
 		os.Exit(1)
 	}
 	command := metrics.GetCommand(os.Args[1:])
-	if command == "build" {
+	if command == "build" && !metrics.HasQuietFlag(os.Args[1:]) {
 		utils.DisplayScanSuggestMsg()
 	}
 	metrics.Track(store.DefaultContextType, os.Args[1:], metrics.SuccessStatus)

+ 1 - 1
local/compose/build.go

@@ -75,7 +75,7 @@ func (s *composeService) Build(ctx context.Context, project *types.Project, opti
 
 	err := s.build(ctx, project, opts, Containers{}, options.Progress)
 	if err == nil {
-		if len(imagesToBuild) > 0 {
+		if len(imagesToBuild) > 0 && !options.Quiet {
 			utils.DisplayScanSuggestMsg()
 		}
 	}

+ 30 - 6
local/e2e/compose/scan_message_test.go

@@ -42,19 +42,43 @@ func TestDisplayScanMessageAfterBuild(t *testing.T) {
 
 	t.Run("display when docker build", func(t *testing.T) {
 		res := c.RunDockerCmd("build", "-t", "test-image-scan-msg", "./fixtures/simple-build-test/nginx-build")
-		res.Assert(t, icmd.Expected{Out: "Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them"})
+		defer c.RunDockerCmd("rmi", "-f", "test-image-scan-msg")
+		res.Assert(t, icmd.Expected{Err: "Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them"})
 	})
 
-	t.Run("do not display if envvar  DOCKER_SCAN_SUGGEST=false", func(t *testing.T) {
+	t.Run("do not display with docker build and quiet flag", func(t *testing.T) {
+		res := c.RunDockerCmd("build", "-t", "test-image-scan-msg-quiet", "--quiet", "./fixtures/simple-build-test/nginx-build")
+		defer c.RunDockerCmd("rmi", "-f", "test-image-scan-msg-quiet")
+		assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"))
+
+		res = c.RunDockerCmd("build", "-t", "test-image-scan-msg-q", "-q", "./fixtures/simple-build-test/nginx-build")
+		defer c.RunDockerCmd("rmi", "-f", "test-image-scan-msg-q")
+		assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"))
+	})
+
+	t.Run("do not display if envvar DOCKER_SCAN_SUGGEST=false", func(t *testing.T) {
 		cmd := c.NewDockerCmd("build", "-t", "test-image-scan-msg", "./fixtures/build-test/nginx-build")
+		defer c.RunDockerCmd("rmi", "-f", "test-image-scan-msg")
 		cmd.Env = append(cmd.Env, "DOCKER_SCAN_SUGGEST=false")
 		res := icmd.StartCmd(cmd)
 		assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined())
 	})
 
 	t.Run("display on compose build", func(t *testing.T) {
-		res := c.RunDockerCmd("compose", "-f", "./fixtures/simple-build-test/compose.yml", "-p", "scan-msg-test", "build")
-		res.Assert(t, icmd.Expected{Out: "Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them"})
+		res := c.RunDockerCmd("compose", "-f", "./fixtures/simple-build-test/compose.yml", "-p", "scan-msg-test-compose-build", "build")
+		defer c.RunDockerCmd("rmi", "-f", "scan-msg-test-compose-build_nginx")
+		res.Assert(t, icmd.Expected{Err: "Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them"})
+	})
+
+	t.Run("do not display on compose build with quiet flag", func(t *testing.T) {
+		res := c.RunDockerCmd("compose", "-f", "./fixtures/simple-build-test/compose.yml", "-p", "scan-msg-test-quiet", "build", "--quiet")
+		assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined())
+		res = c.RunDockerCmd("rmi", "-f", "scan-msg-test-quiet_nginx")
+		assert.Assert(t, !strings.Contains(res.Combined(), "No such image"))
+
+		res = c.RunDockerCmd("compose", "-f", "./fixtures/simple-build-test/compose.yml", "-p", "scan-msg-test-q", "build", "-q")
+		defer c.RunDockerCmd("rmi", "-f", "scan-msg-test-q_nginx")
+		assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined())
 	})
 
 	_ = c.RunDockerOrExitError("rmi", "scan-msg-test_nginx")
@@ -62,12 +86,12 @@ func TestDisplayScanMessageAfterBuild(t *testing.T) {
 	t.Run("display on compose up if image is built", func(t *testing.T) {
 		res := c.RunDockerCmd("compose", "-f", "./fixtures/simple-build-test/compose.yml", "-p", "scan-msg-test", "up", "-d")
 		defer c.RunDockerCmd("compose", "-f", "./fixtures/simple-build-test/compose.yml", "-p", "scan-msg-test", "down")
-		res.Assert(t, icmd.Expected{Out: "Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them"})
+		res.Assert(t, icmd.Expected{Err: "Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them"})
 	})
 
 	t.Run("do not display on compose up if no image built", func(t *testing.T) { // re-run the same Compose aproject
 		res := c.RunDockerCmd("compose", "-f", "./fixtures/simple-build-test/compose.yml", "-p", "scan-msg-test", "up", "-d")
-		defer c.RunDockerCmd("compose", "-f", "./fixtures/simple-build-test/compose.yml", "-p", "scan-msg-test", "down")
+		defer c.RunDockerCmd("compose", "-f", "./fixtures/simple-build-test/compose.yml", "-p", "scan-msg-test", "down", "--rmi", "all")
 		assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined())
 	})
 

+ 1 - 2
utils/scan_suggest.go

@@ -39,8 +39,7 @@ func DisplayScanSuggestMsg() {
 	if scanAlreadyInvoked() {
 		return
 	}
-	fmt.Println()
-	fmt.Println("Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them")
+	fmt.Fprintf(os.Stderr, "\nUse 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them\n")
 }
 
 func scanAlreadyInvoked() bool {