summaryrefslogtreecommitdiffstats
path: root/routers
diff options
context:
space:
mode:
authorLauris BH <lauris@nix.lv>2018-08-06 07:43:22 +0300
committerJonas Franz <info@jonasfranz.software>2018-08-06 06:43:21 +0200
commit6e64f9db8eb889f9cc7e8c9576b2f9c89750927e (patch)
treed76b927295a1d2f69ea73a78e83d9264ce1510f2 /routers
parent9c354a539ab498ebfdebf7395cf17f95f8b24ac8 (diff)
downloadgitea-6e64f9db8eb889f9cc7e8c9576b2f9c89750927e.tar.gz
gitea-6e64f9db8eb889f9cc7e8c9576b2f9c89750927e.zip
Pull request review/approval and comment on code (#3748)
* Initial ui components for pull request review * Add Review Add IssueComment types Signed-off-by: Jonas Franz <info@jonasfranz.software> (cherry picked from commit 2b4daab) Signed-off-by: Jonas Franz <info@jonasfranz.software> * Replace ReviewComment with Content Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add load functions Add ReviewID to findComments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add create review comment implementation Add migration for review Other small changes Signed-off-by: Jonas Franz <info@jonasfranz.software> * Simplified create and find functions for review Signed-off-by: Jonas Franz <info@jonasfranz.software> * Moved "Pending" to first position Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add GetCurrentReview to simplify fetching current review Signed-off-by: Jonas Franz <info@jonasfranz.software> * Preview for listing comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Move new comment form to its own file Signed-off-by: Jonas Franz <info@jonasfranz.software> * Implement Review form Show Review comments on comment stream Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for single comments Showing buttons in context Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add pending tag to pending review comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add unit tests for Review Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fetch all review ids at once Add unit tests Signed-off-by: Jonas Franz <info@jonasfranz.software> * gofmt Signed-off-by: Jonas Franz <info@jonasfranz.software> * Improved comment rendering in "Files" view by adding Comments to DiffLine Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for invalidating comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Switched back to code.gitea.io/git Signed-off-by: Jonas Franz <info@jonasfranz.software> * Moved review migration from v64 to v65 Signed-off-by: Jonas Franz <info@jonasfranz.software> * Rebuild css Signed-off-by: Jonas Franz <info@jonasfranz.software> * gofmt Signed-off-by: Jonas Franz <info@jonasfranz.software> * Improve translations Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix unit tests by updating fixtures and updating outdated test Signed-off-by: Jonas Franz <info@jonasfranz.software> * Comments will be shown at the right place now Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for deleting CodeComments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix problems caused by files in subdirectories Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for showing code comments of reviews in conversation Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for "Show/Hide outdated" Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update code.gitea.io/git Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for new webhooks Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update comparison Signed-off-by: Jonas Franz <info@jonasfranz.software> * Resolve conflicts Signed-off-by: Jonas Franz <info@jonasfranz.software> * Minor UI improvements * update code.gitea.io/git * Fix ui bug reported by @lunny causing wrong position of add button Add functionality to "Cancel" button Add scale effects to add button Hide "Cancel" button for existing comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Prepare solving conflicts Signed-off-by: Jonas Franz <info@jonasfranz.software> * Show add button only if no comments already exist for the line Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add missing vendor files Signed-off-by: Jonas Franz <info@jonasfranz.software> * Check if reviewer is nil Signed-off-by: Jonas Franz <info@jonasfranz.software> * Show forms only to users who are logged in Signed-off-by: Jonas Franz <info@jonasfranz.software> * Revert "Show forms only to users who are logged in" This reverts commit c083682 Signed-off-by: Jonas Franz <info@jonasfranz.software> * Save patch in comment Render patch for code comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add link to comment in code Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add reply form to comment list Show forms only to signed in users Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add 'Reply' as translatable Add CODE_COMMENT_LINES setting Signed-off-by: Jonas Franz <info@jonasfranz.software> * gofmt Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix problems introduced by checking for singed in user Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add v70 Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update generated stylesheet Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix preview Beginn with new review comment patch system Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add new algo to generate diff for line range Remove old algo used for cutting big diffs (it was very buggy) * Add documentation and example for CutDiffAroundLine * Fix example of CutDiffAroundLine * Fix some comment UI rendering bugs * Add code comment edit mode * Send notifications / actions to users until review gets published Fix diff generation bug Fix wrong hashtag * Fix vet errors * Send notifications also for single comments * Fix some notification bugs, fix link * Fix: add comment icon is only shown on code lines * Add lint comment * Add unit tests for git diff * Add more error messages * Regenerated css Signed-off-by: Jonas Franz <info@jonasfranz.software> * fmt Signed-off-by: Jonas Franz <info@jonasfranz.software> * Regenerated CSS with latest less version Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix test by updating comment type to new ID Signed-off-by: Jonas Franz <info@jonasfranz.software> * Introducing CodeComments as type for map[string]map[int64][]*Comment Other minor code improvements Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix data-tab issues Signed-off-by: Jonas Franz <info@jonasfranz.software> * Remove unnecessary change Signed-off-by: Jonas Franz <info@jonasfranz.software> * refactored checkForInvalidation Signed-off-by: Jonas Franz <info@jonasfranz.software> * Append comments instead of setting Signed-off-by: Jonas Franz <info@jonasfranz.software> * Use HeadRepo instead of BaseRepo Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update migration Signed-off-by: Jonas Franz <info@jonasfranz.de> * Regenerated CSS Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add copyright Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update index.css Signed-off-by: Jonas Franz <info@jonasfranz.software>
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() {