junit.go 2.3 KB

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