|
|
@@ -0,0 +1,102 @@
|
|
|
+package report
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/json"
|
|
|
+ "encoding/xml"
|
|
|
+ "fmt"
|
|
|
+ "io"
|
|
|
+ "strconv"
|
|
|
+)
|
|
|
+
|
|
|
+func writeJunit(findings []Finding, w io.WriteCloser) error {
|
|
|
+ testSuites := TestSuites{
|
|
|
+ TestSuites: getTestSuites(findings),
|
|
|
+ }
|
|
|
+
|
|
|
+ io.WriteString(w, xml.Header)
|
|
|
+ encoder := xml.NewEncoder(w)
|
|
|
+ encoder.Indent("", "\t")
|
|
|
+ return encoder.Encode(testSuites)
|
|
|
+}
|
|
|
+
|
|
|
+func getTestSuites(findings []Finding) []TestSuite {
|
|
|
+ return []TestSuite{
|
|
|
+ {
|
|
|
+ Failures: strconv.Itoa(len(findings)),
|
|
|
+ Name: "gitleaks",
|
|
|
+ Tests: strconv.Itoa(len(findings)),
|
|
|
+ TestCases: getTestCases(findings),
|
|
|
+ Time: "",
|
|
|
+ },
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func getTestCases(findings []Finding) []TestCase {
|
|
|
+ testCases := []TestCase{}
|
|
|
+ for _, f := range findings {
|
|
|
+ testCase := TestCase{
|
|
|
+ Classname: f.Description,
|
|
|
+ Failure: getFailure(f),
|
|
|
+ File: f.File,
|
|
|
+ Name: getMessage(f),
|
|
|
+ Time: "",
|
|
|
+ }
|
|
|
+ testCases = append(testCases, testCase)
|
|
|
+ }
|
|
|
+ return testCases
|
|
|
+}
|
|
|
+
|
|
|
+func getFailure(f Finding) Failure {
|
|
|
+ return Failure{
|
|
|
+ Data: getData(f),
|
|
|
+ Message: getMessage(f),
|
|
|
+ Type: f.Description,
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func getData(f Finding) string {
|
|
|
+ data, err := json.MarshalIndent(f, "", "\t")
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ return string(data)
|
|
|
+}
|
|
|
+
|
|
|
+func getMessage(f Finding) string {
|
|
|
+ if f.Commit == "" {
|
|
|
+ return fmt.Sprintf("%s has detected a secret in file %s, line %s.", f.RuleID, f.File, strconv.Itoa(f.StartLine))
|
|
|
+ }
|
|
|
+
|
|
|
+ return fmt.Sprintf("%s has detected a secret in file %s, line %s, at commit %s.", f.RuleID, f.File, strconv.Itoa(f.StartLine), f.Commit)
|
|
|
+}
|
|
|
+
|
|
|
+type TestSuites struct {
|
|
|
+ XMLName xml.Name `xml:"testsuites"`
|
|
|
+ TestSuites []TestSuite
|
|
|
+}
|
|
|
+
|
|
|
+type TestSuite struct {
|
|
|
+ XMLName xml.Name `xml:"testsuite"`
|
|
|
+ Failures string `xml:"failures,attr"`
|
|
|
+ Name string `xml:"name,attr"`
|
|
|
+ Tests string `xml:"tests,attr"`
|
|
|
+ TestCases []TestCase `xml:"testcase"`
|
|
|
+ Time string `xml:"time,attr"`
|
|
|
+}
|
|
|
+
|
|
|
+type TestCase struct {
|
|
|
+ XMLName xml.Name `xml:"testcase"`
|
|
|
+ Classname string `xml:"classname,attr"`
|
|
|
+ Failure Failure `xml:"failure"`
|
|
|
+ File string `xml:"file,attr"`
|
|
|
+ Name string `xml:"name,attr"`
|
|
|
+ Time string `xml:"time,attr"`
|
|
|
+}
|
|
|
+
|
|
|
+type Failure struct {
|
|
|
+ XMLName xml.Name `xml:"failure"`
|
|
|
+ Data string `xml:",chardata"`
|
|
|
+ Message string `xml:"message,attr"`
|
|
|
+ Type string `xml:"type,attr"`
|
|
|
+}
|