Browse Source

Add option to include `Line` field in report (#1616)

Signed-off-by: Taiki Ono <taiki@finatext.com>
Taiki Ono 1 year ago
parent
commit
8e94f98e92
7 changed files with 80 additions and 22 deletions
  1. 1 1
      README.md
  2. 1 1
      cmd/root.go
  3. 1 1
      report/finding.go
  4. 11 0
      report/json.go
  5. 41 19
      report/json_test.go
  6. 2 0
      report/report.go
  7. 23 0
      testdata/expected/report/json_extra_simple.json

+ 1 - 1
README.md

@@ -162,7 +162,7 @@ Flags:
       --no-banner                     suppress banner
       --no-color                      turn off color for verbose output
       --redact uint[=100]             redact secrets from logs and stdout. To redact only parts of the secret just apply a percent value from 0..100. For example --redact=20 (default 100%)
-  -f, --report-format string          output format (json, csv, junit, sarif) (default "json")
+  -f, --report-format string          output format (json, jsonextra, csv, junit, sarif) (default "json")
   -r, --report-path string            report file
   -v, --verbose                       show verbose output from scan
       --version                       version for gitleaks

+ 1 - 1
cmd/root.go

@@ -44,7 +44,7 @@ func init() {
 	rootCmd.PersistentFlags().StringP("config", "c", "", configDescription)
 	rootCmd.PersistentFlags().Int("exit-code", 1, "exit code when leaks have been encountered")
 	rootCmd.PersistentFlags().StringP("report-path", "r", "", "report file")
-	rootCmd.PersistentFlags().StringP("report-format", "f", "json", "output format (json, csv, junit, sarif)")
+	rootCmd.PersistentFlags().StringP("report-format", "f", "json", "output format (json, jsonextra, csv, junit, sarif)")
 	rootCmd.PersistentFlags().StringP("baseline-path", "b", "", "path to baseline with issues that can be ignored")
 	rootCmd.PersistentFlags().StringP("log-level", "l", "info", "log level (trace, debug, info, warn, error, fatal)")
 	rootCmd.PersistentFlags().BoolP("verbose", "v", false, "show verbose output from scan")

+ 1 - 1
report/finding.go

@@ -14,7 +14,7 @@ type Finding struct {
 	StartColumn int
 	EndColumn   int
 
-	Line string `json:"-"`
+	Line string `json:",omitempty"`
 
 	Match string
 

+ 11 - 0
report/json.go

@@ -6,6 +6,17 @@ import (
 )
 
 func writeJson(findings []Finding, w io.WriteCloser) error {
+	if len(findings) == 0 {
+		findings = []Finding{}
+	}
+	for i := range findings {
+		// Remove `Line` from JSON output
+		findings[i].Line = ""
+	}
+	return writeJsonExtra(findings, w)
+}
+
+func writeJsonExtra(findings []Finding, w io.WriteCloser) error {
 	if len(findings) == 0 {
 		findings = []Finding{}
 	}

+ 41 - 19
report/json_test.go

@@ -9,6 +9,26 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
+var simpleFinding = Finding{
+	Description: "",
+	RuleID:      "test-rule",
+	Match:       "line containing secret",
+	Line:        "whole line containing secret",
+	Secret:      "a secret",
+	StartLine:   1,
+	EndLine:     2,
+	StartColumn: 1,
+	EndColumn:   2,
+	Message:     "opps",
+	File:        "auth.py",
+	SymlinkFile: "",
+	Commit:      "0000000000000000",
+	Author:      "John Doe",
+	Email:       "johndoe@gmail.com",
+	Date:        "10-19-2003",
+	Tags:        []string{},
+}
+
 func TestWriteJSON(t *testing.T) {
 	tests := []struct {
 		findings       []Finding
@@ -20,25 +40,7 @@ func TestWriteJSON(t *testing.T) {
 			testReportName: "simple",
 			expected:       filepath.Join(expectPath, "report", "json_simple.json"),
 			findings: []Finding{
-				{
-
-					Description: "",
-					RuleID:      "test-rule",
-					Match:       "line containing secret",
-					Secret:      "a secret",
-					StartLine:   1,
-					EndLine:     2,
-					StartColumn: 1,
-					EndColumn:   2,
-					Message:     "opps",
-					File:        "auth.py",
-					SymlinkFile: "",
-					Commit:      "0000000000000000",
-					Author:      "John Doe",
-					Email:       "johndoe@gmail.com",
-					Date:        "10-19-2003",
-					Tags:        []string{},
-				},
+				simpleFinding,
 			}},
 		{
 
@@ -66,3 +68,23 @@ func TestWriteJSON(t *testing.T) {
 		})
 	}
 }
+
+func TestWriteJSONExtra(t *testing.T) {
+	findings := []Finding{
+		simpleFinding,
+	}
+	expected := filepath.Join(expectPath, "report", "json_extra_simple.json")
+
+	tmpfile, err := os.Create(filepath.Join(t.TempDir(), "simple_extra.json"))
+	require.NoError(t, err)
+
+	err = writeJsonExtra(findings, tmpfile)
+	require.NoError(t, err)
+	assert.FileExists(t, tmpfile.Name())
+
+	got, err := os.ReadFile(tmpfile.Name())
+	require.NoError(t, err)
+	want, err := os.ReadFile(expected)
+	require.NoError(t, err)
+	assert.Equal(t, want, got)
+}

+ 2 - 0
report/report.go

@@ -22,6 +22,8 @@ func Write(findings []Finding, cfg config.Config, ext string, reportPath string)
 	switch ext {
 	case ".json", "json":
 		err = writeJson(findings, file)
+	case ".jsonextra", "jsonextra":
+		err = writeJsonExtra(findings, file)
 	case ".csv", "csv":
 		err = writeCsv(findings, file)
 	case ".xml", "junit":

+ 23 - 0
testdata/expected/report/json_extra_simple.json

@@ -0,0 +1,23 @@
+[
+ {
+  "Description": "",
+  "StartLine": 1,
+  "EndLine": 2,
+  "StartColumn": 1,
+  "EndColumn": 2,
+  "Line": "whole line containing secret",
+  "Match": "line containing secret",
+  "Secret": "a secret",
+  "File": "auth.py",
+  "SymlinkFile": "",
+  "Commit": "0000000000000000",
+  "Entropy": 0,
+  "Author": "John Doe",
+  "Email": "johndoe@gmail.com",
+  "Date": "10-19-2003",
+  "Message": "opps",
+  "Tags": [],
+  "RuleID": "test-rule",
+  "Fingerprint": ""
+ }
+]