junit.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package report
  2. import (
  3. "encoding/json"
  4. "encoding/xml"
  5. "fmt"
  6. "io"
  7. "strconv"
  8. )
  9. type JunitReporter struct {
  10. }
  11. var _ Reporter = (*JunitReporter)(nil)
  12. func (r *JunitReporter) Write(w io.WriteCloser, findings []Finding) error {
  13. testSuites := TestSuites{
  14. TestSuites: getTestSuites(findings),
  15. }
  16. io.WriteString(w, xml.Header)
  17. encoder := xml.NewEncoder(w)
  18. encoder.Indent("", "\t")
  19. return encoder.Encode(testSuites)
  20. }
  21. func getTestSuites(findings []Finding) []TestSuite {
  22. return []TestSuite{
  23. {
  24. Failures: strconv.Itoa(len(findings)),
  25. Name: "gitleaks",
  26. Tests: strconv.Itoa(len(findings)),
  27. TestCases: getTestCases(findings),
  28. Time: "",
  29. },
  30. }
  31. }
  32. func getTestCases(findings []Finding) []TestCase {
  33. testCases := []TestCase{}
  34. for _, f := range findings {
  35. testCase := TestCase{
  36. Classname: f.Description,
  37. Failure: getFailure(f),
  38. File: f.File,
  39. Name: getMessage(f),
  40. Time: "",
  41. }
  42. testCases = append(testCases, testCase)
  43. }
  44. return testCases
  45. }
  46. func getFailure(f Finding) Failure {
  47. return Failure{
  48. Data: getData(f),
  49. Message: getMessage(f),
  50. Type: f.Description,
  51. }
  52. }
  53. func getData(f Finding) string {
  54. data, err := json.MarshalIndent(f, "", "\t")
  55. if err != nil {
  56. fmt.Println(err)
  57. return ""
  58. }
  59. return string(data)
  60. }
  61. func getMessage(f Finding) string {
  62. if f.Commit == "" {
  63. return fmt.Sprintf("%s has detected a secret in file %s, line %s.", f.RuleID, f.File, strconv.Itoa(f.StartLine))
  64. }
  65. 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)
  66. }
  67. type TestSuites struct {
  68. XMLName xml.Name `xml:"testsuites"`
  69. TestSuites []TestSuite
  70. }
  71. type TestSuite struct {
  72. XMLName xml.Name `xml:"testsuite"`
  73. Failures string `xml:"failures,attr"`
  74. Name string `xml:"name,attr"`
  75. Tests string `xml:"tests,attr"`
  76. TestCases []TestCase `xml:"testcase"`
  77. Time string `xml:"time,attr"`
  78. }
  79. type TestCase struct {
  80. XMLName xml.Name `xml:"testcase"`
  81. Classname string `xml:"classname,attr"`
  82. Failure Failure `xml:"failure"`
  83. File string `xml:"file,attr"`
  84. Name string `xml:"name,attr"`
  85. Time string `xml:"time,attr"`
  86. }
  87. type Failure struct {
  88. XMLName xml.Name `xml:"failure"`
  89. Data string `xml:",chardata"`
  90. Message string `xml:"message,attr"`
  91. Type string `xml:"type,attr"`
  92. }