You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

templates.go 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package httplistener
  2. import (
  3. "bytes"
  4. "errors"
  5. "github.com/irccloud/irccat/util"
  6. "gopkg.in/go-playground/webhooks.v5/github"
  7. "strings"
  8. "text/template"
  9. )
  10. var defaultTemplates = map[string]string{
  11. "github.release": "[{{b .Repository.Name}}] release {{h .Release.TagName}} has been published by {{g .Release.Author.Login}}: {{.Release.HTMLURL}}",
  12. "github.push": `[{{b .Repository.Name}}] {{g .Sender.Login}} {{if .Forced}}force-{{end}}{{if .Deleted}}deleted{{else}}pushed{{end}} {{if .Commits}}{{.Commits|len}} commit{{if .Commits|len|lt 1}}s{{end}} to {{end}}{{.Ref|refType}} {{.Ref|refName|h}}: {{.Compare}}
  13. {{range commitLimit . 3}}
  14. • {{g .Username}} ({{.Sha|truncateSha|h}}): {{trunc .Message 150}}
  15. {{end}}`,
  16. "github.issue": "[{{b .Repository.Name}}] {{g .Sender.Login}} {{.Action}} issue #{{.Issue.Number}}: {{.Issue.Title}} {{.Issue.HTMLURL}}",
  17. "github.issuecomment": "[{{b .Repository.Name}}] {{g .Comment.User.Login}} commented on issue #{{.Issue.Number}}: {{trunc .Comment.Body 150}} {{.Comment.HTMLURL}}",
  18. "github.pullrequest": "[{{b .Repository.Name}}] {{g .Sender.Login}} {{if .PullRequest.Merged}}merged{{else}}{{.Action}}{{end}} pull request #{{.PullRequest.Number}} (\x0303{{.PullRequest.Base.Ref}}…{{.PullRequest.Head.Ref}}\x0f): {{.PullRequest.Title}} {{.PullRequest.HTMLURL}}",
  19. "github.checksuite": "[{{b .Repository.Name}}] check suite {{b .CheckSuite.Conclusion}}",
  20. "prometheus.alert": `{{range .Alerts}}[{{b "Prometheus"}}] {{if (eq .Status "firing")}}{{b "alerting"}}{{else}}{{h "resolved"}}{{end}}: {{.Annotations.summary}}
  21. {{end}}`,
  22. }
  23. func refName(ref string) string {
  24. // Trim leading 'refs/heads/', 'refs/tags/' etc.
  25. parts := strings.Split(ref, "/")
  26. return strings.Join(parts[2:], "/")
  27. }
  28. func refType(ref string) string {
  29. parts := strings.Split(ref, "/")
  30. if parts[1] == "heads" {
  31. return "branch"
  32. } else if parts[1] == "tags" {
  33. return "tag"
  34. }
  35. return ""
  36. }
  37. func truncateSha(sha string) string {
  38. if len(sha) < 8 {
  39. return ""
  40. }
  41. return sha[:8]
  42. }
  43. // Colour helper functions to try and declutter
  44. func boldFormat(text string) string {
  45. return "\x02" + text + "\x0f"
  46. }
  47. func greyFormat(text string) string {
  48. return "\x0314" + text + "\x0f"
  49. }
  50. func highlightFormat(text string) string {
  51. return "\x0303" + text + "\x0f"
  52. }
  53. func parseTemplates() *template.Template {
  54. funcMap := template.FuncMap{
  55. "trunc": util.Truncate,
  56. "truncateSha": truncateSha,
  57. "refType": refType,
  58. "refName": refName,
  59. "commitLimit": commitLimit,
  60. "b": boldFormat,
  61. "g": greyFormat,
  62. "h": highlightFormat,
  63. }
  64. t := template.New("irccat")
  65. for k, v := range defaultTemplates {
  66. template.Must(t.New(k).Funcs(funcMap).Parse(v))
  67. }
  68. return t
  69. }
  70. func (hl *HTTPListener) renderTemplate(tpl_name string, data interface{}) ([]string, error) {
  71. var out bytes.Buffer
  72. t := hl.tpls.Lookup(tpl_name)
  73. if t == nil {
  74. return []string{}, errors.New("Nonexistent template")
  75. }
  76. t.Execute(&out, data)
  77. // The \r character is also a delimiter in IRC so strip it out.
  78. outStr := strings.Replace(out.String(), "\r", "", -1)
  79. return strings.Split(outStr, "\n"), nil
  80. }
  81. // We need this additional struct and function because the GitHub webhook package represents
  82. // commits as anonymous inner structs and Go's type system is bad. Unless I'm missing something very obvious.
  83. type Commit struct {
  84. Message string
  85. Username string
  86. Sha string
  87. }
  88. func commitLimit(pl github.PushPayload, length int) []Commit {
  89. res := make([]Commit, 0)
  90. i := 0
  91. for _, c := range pl.Commits {
  92. if !c.Distinct {
  93. continue
  94. }
  95. res = append(res, Commit{Message: c.Message, Username: c.Author.Username, Sha: c.ID})
  96. i += 1
  97. if i == length {
  98. break
  99. }
  100. }
  101. return res
  102. }