summaryrefslogtreecommitdiffstats
path: root/routers/web/repo/pull_review.go
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2021-06-09 07:33:54 +0800
committerGitHub <noreply@github.com>2021-06-09 01:33:54 +0200
commit1bfb0a24d843e10d6d95c4319a84980485e584ed (patch)
treee4a736f9abee3eaad1270bf3b60ee3bb9401a9dc /routers/web/repo/pull_review.go
parente03a91a48ef7fb716cc7c8bfb411ca8f332dcfe5 (diff)
downloadgitea-1bfb0a24d843e10d6d95c4319a84980485e584ed.tar.gz
gitea-1bfb0a24d843e10d6d95c4319a84980485e584ed.zip
Refactor routers directory (#15800)
* refactor routers directory * move func used for web and api to common * make corsHandler a function to prohibit side efects * rm unused func Co-authored-by: 6543 <6543@obermui.de>
Diffstat (limited to 'routers/web/repo/pull_review.go')
-rw-r--r--routers/web/repo/pull_review.go238
1 files changed, 238 insertions, 0 deletions
diff --git a/routers/web/repo/pull_review.go b/routers/web/repo/pull_review.go
new file mode 100644
index 0000000000..9e505c3db3
--- /dev/null
+++ b/routers/web/repo/pull_review.go
@@ -0,0 +1,238 @@
+// 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"
+ "net/http"
+
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/context"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/forms"
+ pull_service "code.gitea.io/gitea/services/pull"
+)
+
+const (
+ tplConversation base.TplName = "repo/diff/conversation"
+ tplNewComment base.TplName = "repo/diff/new_comment"
+)
+
+// RenderNewCodeCommentForm will render the form for creating a new review comment
+func RenderNewCodeCommentForm(ctx *context.Context) {
+ issue := GetActionIssue(ctx)
+ if !issue.IsPull {
+ return
+ }
+ currentReview, err := models.GetCurrentReview(ctx.User, issue)
+ if err != nil && !models.IsErrReviewNotExist(err) {
+ ctx.ServerError("GetCurrentReview", err)
+ return
+ }
+ ctx.Data["PageIsPullFiles"] = true
+ ctx.Data["Issue"] = issue
+ ctx.Data["CurrentReview"] = currentReview
+ pullHeadCommitID, err := ctx.Repo.GitRepo.GetRefCommitID(issue.PullRequest.GetGitRefName())
+ if err != nil {
+ ctx.ServerError("GetRefCommitID", err)
+ return
+ }
+ ctx.Data["AfterCommitID"] = pullHeadCommitID
+ ctx.HTML(http.StatusOK, tplNewComment)
+}
+
+// CreateCodeComment will create a code comment including an pending review if required
+func CreateCodeComment(ctx *context.Context) {
+ form := web.GetForm(ctx).(*forms.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
+ }
+
+ signedLine := form.Line
+ if form.Side == "previous" {
+ signedLine *= -1
+ }
+
+ comment, err := pull_service.CreateCodeComment(
+ ctx.User,
+ ctx.Repo.GitRepo,
+ issue,
+ signedLine,
+ form.Content,
+ form.TreePath,
+ form.IsReview,
+ form.Reply,
+ form.LatestCommitID,
+ )
+ if err != nil {
+ ctx.ServerError("CreateCodeComment", err)
+ return
+ }
+
+ if comment == nil {
+ log.Trace("Comment not created: %-v #%d[%d]", ctx.Repo.Repository, issue.Index, issue.ID)
+ ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index))
+ return
+ }
+
+ log.Trace("Comment created: %-v #%d[%d] Comment[%d]", ctx.Repo.Repository, issue.Index, issue.ID, comment.ID)
+
+ if form.Origin == "diff" {
+ renderConversation(ctx, comment)
+ return
+ }
+ ctx.Redirect(comment.HTMLURL())
+}
+
+// UpdateResolveConversation add or remove an Conversation resolved mark
+func UpdateResolveConversation(ctx *context.Context) {
+ origin := ctx.Query("origin")
+ action := ctx.Query("action")
+ commentID := ctx.QueryInt64("comment_id")
+
+ comment, err := models.GetCommentByID(commentID)
+ if err != nil {
+ ctx.ServerError("GetIssueByID", err)
+ return
+ }
+
+ if err = comment.LoadIssue(); err != nil {
+ ctx.ServerError("comment.LoadIssue", err)
+ return
+ }
+
+ var permResult bool
+ if permResult, err = models.CanMarkConversation(comment.Issue, ctx.User); err != nil {
+ ctx.ServerError("CanMarkConversation", err)
+ return
+ }
+ if !permResult {
+ ctx.Error(http.StatusForbidden)
+ return
+ }
+
+ if !comment.Issue.IsPull {
+ ctx.Error(http.StatusBadRequest)
+ return
+ }
+
+ if action == "Resolve" || action == "UnResolve" {
+ err = models.MarkConversation(comment, ctx.User, action == "Resolve")
+ if err != nil {
+ ctx.ServerError("MarkConversation", err)
+ return
+ }
+ } else {
+ ctx.Error(http.StatusBadRequest)
+ return
+ }
+
+ if origin == "diff" {
+ renderConversation(ctx, comment)
+ return
+ }
+ ctx.JSON(http.StatusOK, map[string]interface{}{
+ "ok": true,
+ })
+}
+
+func renderConversation(ctx *context.Context, comment *models.Comment) {
+ comments, err := models.FetchCodeCommentsByLine(comment.Issue, ctx.User, comment.TreePath, comment.Line)
+ if err != nil {
+ ctx.ServerError("FetchCodeCommentsByLine", err)
+ return
+ }
+ ctx.Data["PageIsPullFiles"] = true
+ ctx.Data["comments"] = comments
+ ctx.Data["CanMarkConversation"] = true
+ ctx.Data["Issue"] = comment.Issue
+ if err = comment.Issue.LoadPullRequest(); err != nil {
+ ctx.ServerError("comment.Issue.LoadPullRequest", err)
+ return
+ }
+ pullHeadCommitID, err := ctx.Repo.GitRepo.GetRefCommitID(comment.Issue.PullRequest.GetGitRefName())
+ if err != nil {
+ ctx.ServerError("GetRefCommitID", err)
+ return
+ }
+ ctx.Data["AfterCommitID"] = pullHeadCommitID
+ ctx.HTML(http.StatusOK, tplConversation)
+}
+
+// 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 := web.GetForm(ctx).(*forms.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
+ }
+
+ reviewType := form.ReviewType()
+ switch reviewType {
+ case models.ReviewTypeUnknown:
+ ctx.ServerError("ReviewType", fmt.Errorf("unknown ReviewType: %s", form.Type))
+ return
+
+ // can not approve/reject your own PR
+ case models.ReviewTypeApprove, models.ReviewTypeReject:
+ if issue.IsPoster(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
+ }
+ }
+
+ _, comm, err := pull_service.SubmitReview(ctx.User, ctx.Repo.GitRepo, issue, reviewType, form.Content, form.CommitID)
+ if err != nil {
+ if models.IsContentEmptyErr(err) {
+ ctx.Flash.Error(ctx.Tr("repo.issues.review.content.empty"))
+ ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index))
+ } else {
+ ctx.ServerError("SubmitReview", err)
+ }
+ return
+ }
+
+ ctx.Redirect(fmt.Sprintf("%s/pulls/%d#%s", ctx.Repo.RepoLink, issue.Index, comm.HashTag()))
+}
+
+// DismissReview dismissing stale review by repo admin
+func DismissReview(ctx *context.Context) {
+ form := web.GetForm(ctx).(*forms.DismissReviewForm)
+ comm, err := pull_service.DismissReview(form.ReviewID, form.Message, ctx.User, true)
+ if err != nil {
+ ctx.ServerError("pull_service.DismissReview", err)
+ return
+ }
+
+ ctx.Redirect(fmt.Sprintf("%s/pulls/%d#%s", ctx.Repo.RepoLink, comm.Issue.Index, comm.HashTag()))
+}