/
events_commit_comment.go
121 lines (105 loc) · 3 KB
/
events_commit_comment.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package endpoint
import (
// Stdlib
"bufio"
"bytes"
"fmt"
"net/http"
"regexp"
"strings"
// Internal
"github.com/salsaflow/salsaflow-daemon/internal/github/events"
httputil "github.com/salsaflow/salsaflow-daemon/internal/http"
"github.com/salsaflow/salsaflow-daemon/internal/log"
// Vendor
"github.com/google/go-github/github"
"github.com/salsaflow/salsaflow/github/issues"
)
// HandleCommitCommentEvent implements events.CommitCommentEventHandler
// and it is used to handle GitHub commit_comment events.
func (handler *eventHandler) HandleCommitCommentEvent(
rw http.ResponseWriter,
r *http.Request,
event *events.CommitCommentEvent,
) {
// A command is always placed at the beginning of the line
// and it is prefixed with '!'.
cmdRegexp := regexp.MustCompile("^[!]([a-zA-Z]+) (.*)$")
// Process the comment body.
scanner := bufio.NewScanner(strings.NewReader(*event.Comment.Body))
for scanner.Scan() {
// Check whether this is a command and continue if not.
match := cmdRegexp.FindStringSubmatch(scanner.Text())
if len(match) == 0 {
continue
}
cmd, arg := match[1], strings.TrimSpace(match[2])
var err error
switch cmd {
case "mustfix":
err = handler.createReviewBlockerFromCommitComment(
r,
*event.Repo.Owner.Login,
*event.Repo.Name,
event.Comment,
arg)
}
if err != nil {
httputil.Error(rw, r, err)
return
}
}
if err := scanner.Err(); err != nil {
httputil.Error(rw, r, err)
return
}
httputil.Status(rw, http.StatusAccepted)
}
func (handler *eventHandler) createReviewBlockerFromCommitComment(
r *http.Request,
owner string,
repo string,
comment *github.RepositoryComment,
blockerSummary string,
) error {
// Find the right review issue.
//
// We search the content of all review issues for the right commit hash.
var (
client = handler.client
commitSHA = *comment.CommitID
commentURL = *comment.HTMLURL
commentAuthor = *comment.User.Login
)
issue, err := issues.FindReviewIssueByCommitItem(client, owner, repo, commitSHA)
if err != nil {
return err
}
// Parse issue body.
reviewIssue, err := issues.ParseReviewIssue(issue)
if err != nil {
return err
}
// Add the new review issue record.
reviewIssue.AddReviewBlocker(false, commentURL, commitSHA, blockerSummary)
// Update the review issue.
issueNum := *issue.Number
_, _, err = client.Issues.Edit(owner, repo, issueNum, &github.IssueRequest{
Body: github.String(reviewIssue.FormatBody()),
State: github.String("open"),
})
if err != nil {
return err
}
log.Info(r, "Linked a new review comment to review issue %v/%v#%v", owner, repo, issueNum)
// Add the blocker comment.
var bodyBuffer bytes.Buffer
fmt.Fprintf(&bodyBuffer,
"A new [review blocker](%v) was opened by @%v for review issue #%v. The summary follows:\n",
commentURL, commentAuthor, issueNum)
fmt.Fprintf(&bodyBuffer, "> %v\n", blockerSummary)
_, _, err = client.Issues.CreateComment(owner, repo, issueNum, &github.IssueComment{
Body: github.String(bodyBuffer.String()),
})
return err
}