diff options
Diffstat (limited to 'routers')
-rw-r--r-- | routers/repo/issue.go | 20 | ||||
-rw-r--r-- | routers/repo/pull.go | 17 | ||||
-rw-r--r-- | routers/repo/pull_review.go | 151 | ||||
-rw-r--r-- | routers/routes/routes.go | 8 |
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() { |