summaryrefslogtreecommitdiffstats
path: root/models/review.go
diff options
context:
space:
mode:
author赵智超 <1012112796@qq.com>2020-04-07 00:33:34 +0800
committerGitHub <noreply@github.com>2020-04-06 19:33:34 +0300
commitef89e75d0eb232e98ca7a7ef278b8681c7f4fe50 (patch)
treec7b17df4d92441f2ce8420dbf8aa79aee47a3c13 /models/review.go
parent88c14326b1a5d9216d5f6905dcbe44e43efdb5b3 (diff)
downloadgitea-ef89e75d0eb232e98ca7a7ef278b8681c7f4fe50.tar.gz
gitea-ef89e75d0eb232e98ca7a7ef278b8681c7f4fe50.zip
add request review from specific reviewers feature in pull request (#10756)
* add request review feature in pull request add a way to notify specific reviewers to review like github , by add or delet a special type review . The acton is is similar to Assign , so many code reuse the function and items of Assignee, but the meaning and result is different. The Permission style is is similar to github, that only writer can add a review request from Reviewers, but the poster can recall and remove a review request after a reviwer has revied even if he don't have Write Premission. only manager , the poster and reviewer of a request review can remove it. The reviewers can be requested to review contain all readers for private repo , for public, contain all writers and watchers. The offical Review Request will block merge if Reject can block it. an other change: add ui otify for Assignees. Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> Co-authored-by: Lauris BH <lauris@nix.lv> Signed-off-by: a1012112796 <1012112796@qq.com> * new change * add placeholder string * do some changes follow #10238 to add review requests num on lists also change icon for review requests to eye Co-authored-by: Lauris BH <lauris@nix.lv>
Diffstat (limited to 'models/review.go')
-rw-r--r--models/review.go154
1 files changed, 151 insertions, 3 deletions
diff --git a/models/review.go b/models/review.go
index 993b5577bd..3f7223154e 100644
--- a/models/review.go
+++ b/models/review.go
@@ -27,6 +27,8 @@ const (
ReviewTypeComment
// ReviewTypeReject gives feedback blocking merge
ReviewTypeReject
+ // ReviewTypeRequest request review from others
+ ReviewTypeRequest
)
// Icon returns the corresponding icon for the review type
@@ -38,6 +40,8 @@ func (rt ReviewType) Icon() string {
return "request-changes"
case ReviewTypeComment:
return "comment"
+ case ReviewTypeRequest:
+ return "primitive-dot"
default:
return "comment"
}
@@ -369,15 +373,15 @@ func GetReviewersByIssueID(issueID int64) (reviews []*Review, err error) {
}
// Get latest review of each reviwer, sorted in order they were made
- if err := sess.SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND type in (?, ?) GROUP BY issue_id, reviewer_id) ORDER BY review.updated_unix ASC",
- issueID, ReviewTypeApprove, ReviewTypeReject).
+ if err := sess.SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND type in (?, ?, ?) GROUP BY issue_id, reviewer_id) ORDER BY review.updated_unix ASC",
+ issueID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest).
Find(&reviewsUnfiltered); err != nil {
return nil, err
}
// Load reviewer and skip if user is deleted
for _, review := range reviewsUnfiltered {
- if err := review.loadReviewer(sess); err != nil {
+ if err = review.loadReviewer(sess); err != nil {
if !IsErrUserNotExist(err) {
return nil, err
}
@@ -389,6 +393,19 @@ func GetReviewersByIssueID(issueID int64) (reviews []*Review, err error) {
return reviews, nil
}
+// GetReviewerByIssueIDAndUserID get the latest review of reviewer for a pull request
+func GetReviewerByIssueIDAndUserID(issueID, userID int64) (review *Review, err error) {
+ review = new(Review)
+
+ if _, err := x.SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_id = ? AND type in (?, ?, ?))",
+ issueID, userID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest).
+ Get(review); err != nil {
+ return nil, err
+ }
+
+ return
+}
+
// MarkReviewsAsStale marks existing reviews as stale
func MarkReviewsAsStale(issueID int64) (err error) {
_, err = x.Exec("UPDATE `review` SET stale=? WHERE issue_id=?", true, issueID)
@@ -442,3 +459,134 @@ func InsertReviews(reviews []*Review) error {
return sess.Commit()
}
+
+// AddRewiewRequest add a review request from one reviewer
+func AddRewiewRequest(issue *Issue, reviewer *User, doer *User) (comment *Comment, err error) {
+ review, err := GetReviewerByIssueIDAndUserID(issue.ID, reviewer.ID)
+ if err != nil {
+ return
+ }
+
+ // skip it when reviewer hase been request to review
+ if review != nil && review.Type == ReviewTypeRequest {
+ return nil, nil
+ }
+
+ sess := x.NewSession()
+ defer sess.Close()
+ if err := sess.Begin(); err != nil {
+ return nil, err
+ }
+
+ var official bool
+ official, err = isOfficialReviewer(sess, issue, reviewer)
+
+ if err != nil {
+ return nil, err
+ }
+
+ if !official {
+ official, err = isOfficialReviewer(sess, issue, doer)
+
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if official {
+ if _, err := sess.Exec("UPDATE `review` SET official=? WHERE issue_id=? AND reviewer_id=?", false, issue.ID, reviewer.ID); err != nil {
+ return nil, err
+ }
+ }
+
+ _, err = createReview(sess, CreateReviewOptions{
+ Type: ReviewTypeRequest,
+ Issue: issue,
+ Reviewer: reviewer,
+ Official: official,
+ Stale: false,
+ })
+
+ if err != nil {
+ return
+ }
+
+ comment, err = createComment(sess, &CreateCommentOptions{
+ Type: CommentTypeReviewRequest,
+ Doer: doer,
+ Repo: issue.Repo,
+ Issue: issue,
+ RemovedAssignee: false, // Use RemovedAssignee as !isRequest
+ AssigneeID: reviewer.ID, // Use AssigneeID as reviewer ID
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return comment, sess.Commit()
+}
+
+//RemoveRewiewRequest remove a review request from one reviewer
+func RemoveRewiewRequest(issue *Issue, reviewer *User, doer *User) (comment *Comment, err error) {
+ review, err := GetReviewerByIssueIDAndUserID(issue.ID, reviewer.ID)
+ if err != nil {
+ return
+ }
+
+ if review.Type != ReviewTypeRequest {
+ return nil, nil
+ }
+
+ sess := x.NewSession()
+ defer sess.Close()
+ if err := sess.Begin(); err != nil {
+ return nil, err
+ }
+
+ _, err = sess.Delete(review)
+ if err != nil {
+ return nil, err
+ }
+
+ var official bool
+ official, err = isOfficialReviewer(sess, issue, reviewer)
+ if err != nil {
+ return
+ }
+
+ if official {
+ // recalculate which is the latest official review from that user
+ var review *Review
+
+ review, err = GetReviewerByIssueIDAndUserID(issue.ID, reviewer.ID)
+ if err != nil {
+ return nil, err
+ }
+
+ if review != nil {
+ if _, err := sess.Exec("UPDATE `review` SET official=? WHERE id=?", true, review.ID); err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ comment, err = CreateComment(&CreateCommentOptions{
+ Type: CommentTypeReviewRequest,
+ Doer: doer,
+ Repo: issue.Repo,
+ Issue: issue,
+ RemovedAssignee: true, // Use RemovedAssignee as !isRequest
+ AssigneeID: reviewer.ID, // Use AssigneeID as reviewer ID
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return comment, sess.Commit()
+}