summaryrefslogtreecommitdiffstats
path: root/routers
diff options
context:
space:
mode:
Diffstat (limited to 'routers')
-rw-r--r--routers/repo/issue.go20
-rw-r--r--routers/repo/pull.go17
-rw-r--r--routers/repo/pull_review.go151
-rw-r--r--routers/routes/routes.go8
4 files changed, 192 insertions, 4 deletions
diff --git a/routers/repo/issue.go b/routers/repo/issue.go
index 27c95cd9dc..585d2f67ba 100644
--- a/routers/repo/issue.go
+++ b/routers/repo/issue.go
@@ -733,6 +733,22 @@ func ViewIssue(ctx *context.Context) {
ctx.ServerError("LoadDepIssueDetails", err)
return
}
+ } else if comment.Type == models.CommentTypeCode || comment.Type == models.CommentTypeReview {
+ if err = comment.LoadReview(); err != nil && !models.IsErrReviewNotExist(err) {
+ ctx.ServerError("LoadReview", err)
+ return
+ }
+ if comment.Review == nil {
+ continue
+ }
+ if err = comment.Review.LoadAttributes(); err != nil {
+ ctx.ServerError("Review.LoadAttributes", err)
+ return
+ }
+ if err = comment.Review.LoadCodeComments(); err != nil {
+ ctx.ServerError("Review.LoadCodeComments", err)
+ return
+ }
}
}
@@ -1114,7 +1130,7 @@ func UpdateCommentContent(ctx *context.Context) {
if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.IsAdmin()) {
ctx.Error(403)
return
- } else if comment.Type != models.CommentTypeComment {
+ } else if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeCode {
ctx.Error(204)
return
}
@@ -1148,7 +1164,7 @@ func DeleteComment(ctx *context.Context) {
if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.IsAdmin()) {
ctx.Error(403)
return
- } else if comment.Type != models.CommentTypeComment {
+ } else if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeCode {
ctx.Error(204)
return
}
diff --git a/routers/repo/pull.go b/routers/repo/pull.go
index 1d7747450b..e6592e1f57 100644
--- a/routers/repo/pull.go
+++ b/routers/repo/pull.go
@@ -456,6 +456,12 @@ func ViewPullFiles(ctx *context.Context) {
ctx.ServerError("GetDiffRange", err)
return
}
+
+ if err = diff.LoadComments(issue, ctx.User); err != nil {
+ ctx.ServerError("LoadComments", err)
+ return
+ }
+
ctx.Data["Diff"] = diff
ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
@@ -470,7 +476,16 @@ func ViewPullFiles(ctx *context.Context) {
ctx.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(headTarget, "src", "commit", startCommitID)
ctx.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(headTarget, "raw", "commit", endCommitID)
ctx.Data["RequireHighlightJS"] = true
-
+ ctx.Data["RequireTribute"] = true
+ if ctx.Data["Assignees"], err = ctx.Repo.Repository.GetAssignees(); err != nil {
+ ctx.ServerError("GetAssignees", err)
+ return
+ }
+ ctx.Data["CurrentReview"], err = models.GetCurrentReview(ctx.User, issue)
+ if err != nil && !models.IsErrReviewNotExist(err) {
+ ctx.ServerError("GetCurrentReview", err)
+ return
+ }
ctx.HTML(200, tplPullFiles)
}
diff --git a/routers/repo/pull_review.go b/routers/repo/pull_review.go
new file mode 100644
index 0000000000..fa13cacfd3
--- /dev/null
+++ b/routers/repo/pull_review.go
@@ -0,0 +1,151 @@
+// 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
+ }
+ }
+ }
+ //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
+ if !form.IsReview {
+ notification.Service.NotifyIssue(issue, ctx.User.ID)
+ }
+
+ 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()
+ if reviewType == models.ReviewTypeUnknown {
+ ctx.ServerError("GetCurrentReview", fmt.Errorf("unknown ReviewType: %s", form.Type))
+ return
+ }
+ review, err = models.GetCurrentReview(ctx.User, issue)
+ 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
+ }
+ ctx.Redirect(fmt.Sprintf("%s/pulls/%d#%s", ctx.Repo.RepoLink, issue.Index, comm.HashTag()))
+}
diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index 8c196d8bb2..c108eb3ff2 100644
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -671,9 +671,15 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get(".diff", repo.DownloadPullDiff)
m.Get(".patch", repo.DownloadPullPatch)
m.Get("/commits", context.RepoRef(), repo.ViewPullCommits)
- m.Get("/files", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ViewPullFiles)
m.Post("/merge", reqRepoWriter, bindIgnErr(auth.MergePullRequestForm{}), repo.MergePullRequest)
m.Post("/cleanup", context.RepoRef(), repo.CleanUpPullRequest)
+ m.Group("/files", func() {
+ m.Get("", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ViewPullFiles)
+ m.Group("/reviews", func() {
+ m.Post("/comments", bindIgnErr(auth.CodeCommentForm{}), repo.CreateCodeComment)
+ m.Post("/submit", bindIgnErr(auth.SubmitReviewForm{}), repo.SubmitReview)
+ })
+ })
}, repo.MustAllowPulls)
m.Group("/raw", func() {