@@ -58,8 +58,11 @@ func getAssigneesByIssue(e Engine, issue *Issue) (assignees []*User, err error)
58
58
59
59
// IsUserAssignedToIssue returns true when the user is assigned to the issue
60
60
func IsUserAssignedToIssue (issue * Issue , user * User ) (isAssigned bool , err error ) {
61
- isAssigned , err = x .Exist (& IssueAssignees {IssueID : issue .ID , AssigneeID : user .ID })
62
- return
61
+ return isUserAssignedToIssue (x , issue , user )
62
+ }
63
+
64
+ func isUserAssignedToIssue (e Engine , issue * Issue , user * User ) (isAssigned bool , err error ) {
65
+ return e .Get (& IssueAssignees {IssueID : issue .ID , AssigneeID : user .ID })
63
66
}
64
67
65
68
// DeleteNotPassedAssignee deletes all assignees who aren't passed via the "assignees" array
@@ -78,7 +81,7 @@ func DeleteNotPassedAssignee(issue *Issue, doer *User, assignees []*User) (err e
78
81
79
82
if ! found {
80
83
// This function also does comments and hooks, which is why we call it seperatly instead of directly removing the assignees here
81
- if err := UpdateAssignee ( issue , doer , assignee .ID ); err != nil {
84
+ if _ , _ , err := issue . ToggleAssignee ( doer , assignee .ID ); err != nil {
82
85
return err
83
86
}
84
87
}
@@ -110,73 +113,56 @@ func clearAssigneeByUserID(sess *xorm.Session, userID int64) (err error) {
110
113
return
111
114
}
112
115
113
- // AddAssigneeIfNotAssigned adds an assignee only if he isn't aleady assigned to the issue
114
- func AddAssigneeIfNotAssigned (issue * Issue , doer * User , assigneeID int64 ) (err error ) {
115
- // Check if the user is already assigned
116
- isAssigned , err := IsUserAssignedToIssue (issue , & User {ID : assigneeID })
117
- if err != nil {
118
- return err
119
- }
120
-
121
- if ! isAssigned {
122
- return issue .ChangeAssignee (doer , assigneeID )
123
- }
124
- return nil
125
- }
126
-
127
- // UpdateAssignee deletes or adds an assignee to an issue
128
- func UpdateAssignee (issue * Issue , doer * User , assigneeID int64 ) (err error ) {
129
- return issue .ChangeAssignee (doer , assigneeID )
130
- }
131
-
132
- // ChangeAssignee changes the Assignee of this issue.
133
- func (issue * Issue ) ChangeAssignee (doer * User , assigneeID int64 ) (err error ) {
116
+ // ToggleAssignee changes a user between assigned and not assigned for this issue, and make issue comment for it.
117
+ func (issue * Issue ) ToggleAssignee (doer * User , assigneeID int64 ) (removed bool , comment * Comment , err error ) {
134
118
sess := x .NewSession ()
135
119
defer sess .Close ()
136
120
137
121
if err := sess .Begin (); err != nil {
138
- return err
122
+ return false , nil , err
139
123
}
140
124
141
- if err := issue .changeAssignee (sess , doer , assigneeID , false ); err != nil {
142
- return err
125
+ removed , comment , err = issue .toggleAssignee (sess , doer , assigneeID , false )
126
+ if err != nil {
127
+ return false , nil , err
143
128
}
144
129
145
130
if err := sess .Commit (); err != nil {
146
- return err
131
+ return false , nil , err
147
132
}
148
133
149
134
go HookQueue .Add (issue .RepoID )
150
- return nil
135
+
136
+ return removed , comment , nil
151
137
}
152
138
153
- func (issue * Issue ) changeAssignee (sess * xorm.Session , doer * User , assigneeID int64 , isCreate bool ) (err error ) {
154
- // Update the assignee
155
- removed , err := updateIssueAssignee (sess , issue , assigneeID )
139
+ func (issue * Issue ) toggleAssignee (sess * xorm.Session , doer * User , assigneeID int64 , isCreate bool ) (removed bool , comment * Comment , err error ) {
140
+ removed , err = toggleUserAssignee (sess , issue , assigneeID )
156
141
if err != nil {
157
- return fmt .Errorf ("UpdateIssueUserByAssignee: %v" , err )
142
+ return false , nil , fmt .Errorf ("UpdateIssueUserByAssignee: %v" , err )
158
143
}
159
144
160
145
// Repo infos
161
146
if err = issue .loadRepo (sess ); err != nil {
162
- return fmt .Errorf ("loadRepo: %v" , err )
147
+ return false , nil , fmt .Errorf ("loadRepo: %v" , err )
163
148
}
164
149
165
150
// Comment
166
- if _ , err = createAssigneeComment (sess , doer , issue .Repo , issue , assigneeID , removed ); err != nil {
167
- return fmt .Errorf ("createAssigneeComment: %v" , err )
151
+ comment , err = createAssigneeComment (sess , doer , issue .Repo , issue , assigneeID , removed )
152
+ if err != nil {
153
+ return false , nil , fmt .Errorf ("createAssigneeComment: %v" , err )
168
154
}
169
155
170
156
// if pull request is in the middle of creation - don't call webhook
171
157
if isCreate {
172
- return nil
158
+ return removed , comment , err
173
159
}
174
160
175
161
if issue .IsPull {
176
162
mode , _ := accessLevelUnit (sess , doer , issue .Repo , UnitTypePullRequests )
177
163
178
164
if err = issue .loadPullRequest (sess ); err != nil {
179
- return fmt .Errorf ("loadPullRequest: %v" , err )
165
+ return false , nil , fmt .Errorf ("loadPullRequest: %v" , err )
180
166
}
181
167
issue .PullRequest .Issue = issue
182
168
apiPullRequest := & api.PullRequestPayload {
@@ -190,9 +176,10 @@ func (issue *Issue) changeAssignee(sess *xorm.Session, doer *User, assigneeID in
190
176
} else {
191
177
apiPullRequest .Action = api .HookIssueAssigned
192
178
}
179
+ // Assignee comment triggers a webhook
193
180
if err := prepareWebhooks (sess , issue .Repo , HookEventPullRequest , apiPullRequest ); err != nil {
194
181
log .Error ("PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v" , issue .IsPull , removed , err )
195
- return nil
182
+ return false , nil , err
196
183
}
197
184
} else {
198
185
mode , _ := accessLevelUnit (sess , doer , issue .Repo , UnitTypeIssues )
@@ -208,67 +195,50 @@ func (issue *Issue) changeAssignee(sess *xorm.Session, doer *User, assigneeID in
208
195
} else {
209
196
apiIssue .Action = api .HookIssueAssigned
210
197
}
198
+ // Assignee comment triggers a webhook
211
199
if err := prepareWebhooks (sess , issue .Repo , HookEventIssues , apiIssue ); err != nil {
212
200
log .Error ("PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v" , issue .IsPull , removed , err )
213
- return nil
201
+ return false , nil , err
214
202
}
215
203
}
216
- return nil
204
+ return removed , comment , nil
217
205
}
218
206
219
- // UpdateAPIAssignee is a helper function to add or delete one or multiple issue assignee(s)
220
- // Deleting is done the GitHub way (quote from their api documentation):
221
- // https://developer.github.com/v3/issues/#edit-an-issue
222
- // "assignees" (array): Logins for Users to assign to this issue.
223
- // Pass one or more user logins to replace the set of assignees on this Issue.
224
- // Send an empty array ([]) to clear all assignees from the Issue.
225
- func UpdateAPIAssignee (issue * Issue , oneAssignee string , multipleAssignees []string , doer * User ) (err error ) {
226
- var allNewAssignees []* User
207
+ // toggles user assignee state in database
208
+ func toggleUserAssignee (e * xorm.Session , issue * Issue , assigneeID int64 ) (removed bool , err error ) {
227
209
228
- // Keep the old assignee thingy for compatibility reasons
229
- if oneAssignee != "" {
230
- // Prevent double adding assignees
231
- var isDouble bool
232
- for _ , assignee := range multipleAssignees {
233
- if assignee == oneAssignee {
234
- isDouble = true
235
- break
236
- }
237
- }
238
-
239
- if ! isDouble {
240
- multipleAssignees = append (multipleAssignees , oneAssignee )
241
- }
210
+ // Check if the user exists
211
+ assignee , err := getUserByID (e , assigneeID )
212
+ if err != nil {
213
+ return false , err
242
214
}
243
215
244
- // Loop through all assignees to add them
245
- for _ , assigneeName := range multipleAssignees {
246
- assignee , err := GetUserByName ( assigneeName )
247
- if err != nil {
248
- return err
216
+ // Check if the submitted user is already assigned, if yes delete him otherwise add him
217
+ var i int
218
+ for i = 0 ; i < len ( issue . Assignees ); i ++ {
219
+ if issue . Assignees [ i ]. ID == assigneeID {
220
+ break
249
221
}
250
-
251
- allNewAssignees = append (allNewAssignees , assignee )
252
222
}
253
223
254
- // Delete all old assignees not passed
255
- if err = DeleteNotPassedAssignee (issue , doer , allNewAssignees ); err != nil {
256
- return err
257
- }
224
+ assigneeIn := IssueAssignees {AssigneeID : assigneeID , IssueID : issue .ID }
258
225
259
- // Add all new assignees
260
- // Update the assignee. The function will check if the user exists, is already
261
- // assigned (which he shouldn't as we deleted all assignees before) and
262
- // has access to the repo.
263
- for _ , assignee := range allNewAssignees {
264
- // Extra method to prevent double adding (which would result in removing)
265
- err = AddAssigneeIfNotAssigned (issue , doer , assignee .ID )
226
+ toBeDeleted := i < len (issue .Assignees )
227
+ if toBeDeleted {
228
+ issue .Assignees = append (issue .Assignees [:i ], issue .Assignees [i :]... )
229
+ _ , err = e .Delete (assigneeIn )
266
230
if err != nil {
267
- return err
231
+ return toBeDeleted , err
232
+ }
233
+ } else {
234
+ issue .Assignees = append (issue .Assignees , assignee )
235
+ _ , err = e .Insert (assigneeIn )
236
+ if err != nil {
237
+ return toBeDeleted , err
268
238
}
269
239
}
270
240
271
- return
241
+ return toBeDeleted , nil
272
242
}
273
243
274
244
// MakeIDsFromAPIAssigneesToAdd returns an array with all assignee IDs
@@ -292,7 +262,7 @@ func MakeIDsFromAPIAssigneesToAdd(oneAssignee string, multipleAssignees []string
292
262
}
293
263
294
264
// Get the IDs of all assignees
295
- assigneeIDs = GetUserIDsByNames (multipleAssignees )
265
+ assigneeIDs , err = GetUserIDsByNames (multipleAssignees , false )
296
266
297
267
return
298
268
}
0 commit comments