2018-08-06 07:43:22 +03:00
// Copyright 2018 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repo
import (
"fmt"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification"
)
// CreateCodeComment will create a code comment including an pending review if required
func CreateCodeComment ( ctx * context . Context , form auth . CodeCommentForm ) {
issue := GetActionIssue ( ctx )
if ! issue . IsPull {
return
}
if ctx . Written ( ) {
return
}
if ctx . HasError ( ) {
ctx . Flash . Error ( ctx . Data [ "ErrorMsg" ] . ( string ) )
ctx . Redirect ( fmt . Sprintf ( "%s/pulls/%d/files" , ctx . Repo . RepoLink , issue . Index ) )
return
}
var comment * models . Comment
defer func ( ) {
if comment != nil {
ctx . Redirect ( comment . HTMLURL ( ) )
} else {
ctx . Redirect ( fmt . Sprintf ( "%s/pulls/%d/files" , ctx . Repo . RepoLink , issue . Index ) )
}
} ( )
signedLine := form . Line
if form . Side == "previous" {
signedLine *= - 1
}
review := new ( models . Review )
if form . IsReview {
var err error
// Check if the user has already a pending review for this issue
if review , err = models . GetCurrentReview ( ctx . User , issue ) ; err != nil {
if ! models . IsErrReviewNotExist ( err ) {
ctx . ServerError ( "CreateCodeComment" , err )
return
}
// No pending review exists
// Create a new pending review for this issue & user
if review , err = models . CreateReview ( models . CreateReviewOptions {
Type : models . ReviewTypePending ,
Reviewer : ctx . User ,
Issue : issue ,
} ) ; err != nil {
ctx . ServerError ( "CreateCodeComment" , err )
return
}
}
}
2018-10-22 23:13:35 +03:00
if review . ID == 0 {
review . ID = form . Reply
}
2018-08-06 07:43:22 +03:00
//FIXME check if line, commit and treepath exist
comment , err := models . CreateCodeComment (
ctx . User ,
issue . Repo ,
issue ,
form . Content ,
form . TreePath ,
signedLine ,
review . ID ,
)
if err != nil {
ctx . ServerError ( "CreateCodeComment" , err )
return
}
// Send no notification if comment is pending
2018-10-22 23:13:35 +03:00
if ! form . IsReview || form . Reply != 0 {
2018-10-18 14:23:05 +03:00
notification . NotifyCreateIssueComment ( ctx . User , issue . Repo , issue , comment )
2018-08-06 07:43:22 +03:00
}
log . Trace ( "Comment created: %d/%d/%d" , ctx . Repo . Repository . ID , issue . ID , comment . ID )
}
// SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist
func SubmitReview ( ctx * context . Context , form auth . SubmitReviewForm ) {
issue := GetActionIssue ( ctx )
if ! issue . IsPull {
return
}
if ctx . Written ( ) {
return
}
if ctx . HasError ( ) {
ctx . Flash . Error ( ctx . Data [ "ErrorMsg" ] . ( string ) )
ctx . Redirect ( fmt . Sprintf ( "%s/pulls/%d/files" , ctx . Repo . RepoLink , issue . Index ) )
return
}
var review * models . Review
var err error
reviewType := form . ReviewType ( )
2018-08-20 08:04:01 +03:00
switch reviewType {
case models . ReviewTypeUnknown :
2018-08-06 07:43:22 +03:00
ctx . ServerError ( "GetCurrentReview" , fmt . Errorf ( "unknown ReviewType: %s" , form . Type ) )
return
2018-08-20 08:04:01 +03:00
// can not approve/reject your own PR
case models . ReviewTypeApprove , models . ReviewTypeReject :
if issue . Poster . ID == ctx . User . ID {
var translated string
if reviewType == models . ReviewTypeApprove {
translated = ctx . Tr ( "repo.issues.review.self.approval" )
} else {
translated = ctx . Tr ( "repo.issues.review.self.rejection" )
}
ctx . Flash . Error ( translated )
ctx . Redirect ( fmt . Sprintf ( "%s/pulls/%d/files" , ctx . Repo . RepoLink , issue . Index ) )
return
}
2018-08-06 07:43:22 +03:00
}
2018-08-07 20:15:41 +03:00
2018-09-17 17:59:49 +03:00
review , err = models . GetCurrentReview ( ctx . User , issue )
if err == nil {
review . Issue = issue
if errl := review . LoadCodeComments ( ) ; errl != nil {
ctx . ServerError ( "LoadCodeComments" , err )
return
}
}
if ( ( err == nil && len ( review . CodeComments ) == 0 ) ||
( err != nil && models . IsErrReviewNotExist ( err ) ) ) &&
form . HasEmptyContent ( ) {
2018-08-07 20:15:41 +03:00
ctx . Flash . Error ( ctx . Tr ( "repo.issues.review.content.empty" ) )
2018-08-20 08:04:01 +03:00
ctx . Redirect ( fmt . Sprintf ( "%s/pulls/%d/files" , ctx . Repo . RepoLink , issue . Index ) )
2018-08-07 20:15:41 +03:00
return
}
2018-08-06 07:43:22 +03:00
if err != nil {
if ! models . IsErrReviewNotExist ( err ) {
ctx . ServerError ( "GetCurrentReview" , err )
return
}
// No current review. Create a new one!
if review , err = models . CreateReview ( models . CreateReviewOptions {
Type : reviewType ,
Issue : issue ,
Reviewer : ctx . User ,
Content : form . Content ,
} ) ; err != nil {
ctx . ServerError ( "CreateReview" , err )
return
}
} else {
review . Content = form . Content
review . Type = reviewType
if err = models . UpdateReview ( review ) ; err != nil {
ctx . ServerError ( "UpdateReview" , err )
return
}
}
comm , err := models . CreateComment ( & models . CreateCommentOptions {
Type : models . CommentTypeReview ,
Doer : ctx . User ,
Content : review . Content ,
Issue : issue ,
Repo : issue . Repo ,
ReviewID : review . ID ,
} )
if err != nil || comm == nil {
ctx . ServerError ( "CreateComment" , err )
return
}
if err = review . Publish ( ) ; err != nil {
ctx . ServerError ( "Publish" , err )
return
}
2018-10-18 14:23:05 +03:00
pr , err := issue . GetPullRequest ( )
if err != nil {
ctx . ServerError ( "GetPullRequest" , err )
return
}
notification . NotifyPullRequestReview ( pr , review , comm )
2018-08-06 07:43:22 +03:00
ctx . Redirect ( fmt . Sprintf ( "%s/pulls/%d#%s" , ctx . Repo . RepoLink , issue . Index , comm . HashTag ( ) ) )
}