-
Notifications
You must be signed in to change notification settings - Fork 59
Expand file tree
/
Copy pathcomment.go
More file actions
163 lines (129 loc) · 5.28 KB
/
comment.go
File metadata and controls
163 lines (129 loc) · 5.28 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package app
import (
"encoding/json"
"net/http"
gitlab "gitlab.com/gitlab-org/api/client-go"
)
type CommentResponse struct {
SuccessResponse
Comment *gitlab.Note `json:"note"`
Discussion *gitlab.Discussion `json:"discussion"`
}
type CommentManager interface {
CreateMergeRequestDiscussion(pid interface{}, mergeRequest int64, opt *gitlab.CreateMergeRequestDiscussionOptions, options ...gitlab.RequestOptionFunc) (*gitlab.Discussion, *gitlab.Response, error)
UpdateMergeRequestDiscussionNote(pid interface{}, mergeRequest int64, discussion string, note int64, opt *gitlab.UpdateMergeRequestDiscussionNoteOptions, options ...gitlab.RequestOptionFunc) (*gitlab.Note, *gitlab.Response, error)
DeleteMergeRequestDiscussionNote(pid interface{}, mergeRequest int64, discussion string, note int64, options ...gitlab.RequestOptionFunc) (*gitlab.Response, error)
}
type commentService struct {
data
client CommentManager
}
/* commentHandler creates, edits, and deletes discussions (comments, multi-line comments) */
func (a commentService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
switch r.Method {
case http.MethodPost:
a.postComment(w, r)
case http.MethodPatch:
a.editComment(w, r)
case http.MethodDelete:
a.deleteComment(w, r)
}
}
type DeleteCommentRequest struct {
NoteId int64 `json:"note_id" validate:"required"`
DiscussionId string `json:"discussion_id" validate:"required"`
}
/* deleteComment deletes a note, multiline comment, or comment, which are all considered discussion notes. */
func (a commentService) deleteComment(w http.ResponseWriter, r *http.Request) {
payload := r.Context().Value(payload("payload")).(*DeleteCommentRequest)
res, err := a.client.DeleteMergeRequestDiscussionNote(a.projectInfo.ProjectId, a.projectInfo.MergeId, payload.DiscussionId, payload.NoteId)
if err != nil {
handleError(w, err, "Could not delete comment", http.StatusInternalServerError)
return
}
if res.StatusCode >= 300 {
handleError(w, GenericError{r.URL.Path}, "Could not delete comment", res.StatusCode)
return
}
w.WriteHeader(http.StatusOK)
response := SuccessResponse{Message: "Comment deleted successfully"}
err = json.NewEncoder(w).Encode(response)
if err != nil {
handleError(w, err, "Could not encode response", http.StatusInternalServerError)
}
}
type PostCommentRequest struct {
Comment string `json:"comment" validate:"required"`
PositionData
}
/* CommentWithPosition is a comment with an (optional) position data value embedded in it. The position data will be non-nil for range-based comments. */
type CommentWithPosition struct {
PositionData PositionData
}
func (comment CommentWithPosition) GetPositionData() PositionData {
return comment.PositionData
}
/* postComment creates a note, multiline comment, or comment. */
func (a commentService) postComment(w http.ResponseWriter, r *http.Request) {
payload := r.Context().Value(payload("payload")).(*PostCommentRequest)
opt := gitlab.CreateMergeRequestDiscussionOptions{
Body: &payload.Comment,
}
/* If we are leaving a comment on a line, leave position. Otherwise,
we are leaving a note (unlinked comment) */
if payload.FileName != "" {
commentWithPositionData := CommentWithPosition{payload.PositionData}
opt.Position = buildCommentPosition(commentWithPositionData)
}
discussion, res, err := a.client.CreateMergeRequestDiscussion(a.projectInfo.ProjectId, a.projectInfo.MergeId, &opt)
if err != nil {
handleError(w, err, "Could not create discussion", http.StatusInternalServerError)
return
}
if res.StatusCode >= 300 {
handleError(w, GenericError{r.URL.Path}, "Could not create discussion", res.StatusCode)
return
}
w.WriteHeader(http.StatusOK)
response := CommentResponse{
SuccessResponse: SuccessResponse{Message: "Comment created successfully"},
Comment: discussion.Notes[0],
Discussion: discussion,
}
err = json.NewEncoder(w).Encode(response)
if err != nil {
handleError(w, err, "Could not encode response", http.StatusInternalServerError)
}
}
type EditCommentRequest struct {
Comment string `json:"comment" validate:"required"`
NoteId int64 `json:"note_id" validate:"required"`
DiscussionId string `json:"discussion_id" validate:"required"`
Resolved bool `json:"resolved"`
}
/* editComment changes the text of a comment or changes it's resolved status. */
func (a commentService) editComment(w http.ResponseWriter, r *http.Request) {
payload := r.Context().Value(payload("payload")).(*EditCommentRequest)
options := gitlab.UpdateMergeRequestDiscussionNoteOptions{
Body: gitlab.Ptr(payload.Comment),
}
note, res, err := a.client.UpdateMergeRequestDiscussionNote(a.projectInfo.ProjectId, a.projectInfo.MergeId, payload.DiscussionId, payload.NoteId, &options)
if err != nil {
handleError(w, err, "Could not update comment", http.StatusInternalServerError)
return
}
if res.StatusCode >= 300 {
handleError(w, GenericError{r.URL.Path}, "Could not update comment", res.StatusCode)
return
}
w.WriteHeader(http.StatusOK)
response := CommentResponse{
SuccessResponse: SuccessResponse{Message: "Comment updated successfully"},
Comment: note,
}
err = json.NewEncoder(w).Encode(response)
if err != nil {
handleError(w, err, "Could not encode response", http.StatusInternalServerError)
}
}