mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 08:02:36 +09:00 
			
		
		
		
	Simplified create and find functions for review
Signed-off-by: Jonas Franz <info@jonasfranz.software>
This commit is contained in:
		@@ -360,6 +360,7 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
 | 
				
			|||||||
		OldTitle:       opts.OldTitle,
 | 
							OldTitle:       opts.OldTitle,
 | 
				
			||||||
		NewTitle:       opts.NewTitle,
 | 
							NewTitle:       opts.NewTitle,
 | 
				
			||||||
		TreePath:       opts.TreePath,
 | 
							TreePath:       opts.TreePath,
 | 
				
			||||||
 | 
							ReviewID:       opts.ReviewID,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, err = e.Insert(comment); err != nil {
 | 
						if _, err = e.Insert(comment); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
@@ -579,6 +580,7 @@ type CreateCommentOptions struct {
 | 
				
			|||||||
	CommitSHA      string
 | 
						CommitSHA      string
 | 
				
			||||||
	LineNum        int64
 | 
						LineNum        int64
 | 
				
			||||||
	TreePath       string
 | 
						TreePath       string
 | 
				
			||||||
 | 
						ReviewID       int64
 | 
				
			||||||
	Content        string
 | 
						Content        string
 | 
				
			||||||
	Attachments    []string // UUIDs of attachments
 | 
						Attachments    []string // UUIDs of attachments
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -619,7 +621,7 @@ func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content stri
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreateCodeComment creates a plain code comment at the specified line / path
 | 
					// CreateCodeComment creates a plain code comment at the specified line / path
 | 
				
			||||||
func CreateCodeComment(doer *User, repo *Repository, issue *Issue, commitSHA, content, treePath string, line int64) (*Comment, error) {
 | 
					func CreateCodeComment(doer *User, repo *Repository, issue *Issue, commitSHA, content, treePath string, line, reviewID int64) (*Comment, error) {
 | 
				
			||||||
	return CreateComment(&CreateCommentOptions{
 | 
						return CreateComment(&CreateCommentOptions{
 | 
				
			||||||
		Type:      CommentTypeCode,
 | 
							Type:      CommentTypeCode,
 | 
				
			||||||
		Doer:      doer,
 | 
							Doer:      doer,
 | 
				
			||||||
@@ -629,6 +631,7 @@ func CreateCodeComment(doer *User, repo *Repository, issue *Issue, commitSHA, co
 | 
				
			|||||||
		LineNum:   line,
 | 
							LineNum:   line,
 | 
				
			||||||
		TreePath:  treePath,
 | 
							TreePath:  treePath,
 | 
				
			||||||
		CommitSHA: commitSHA,
 | 
							CommitSHA: commitSHA,
 | 
				
			||||||
 | 
							ReviewID:  reviewID,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,11 +4,17 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package models
 | 
					package models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "code.gitea.io/gitea/modules/util"
 | 
					import (
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
 | 
						"github.com/go-xorm/builder"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ReviewType defines the sort of feedback a review gives
 | 
					// ReviewType defines the sort of feedback a review gives
 | 
				
			||||||
type ReviewType int
 | 
					type ReviewType int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ReviewTypeUnknown unknown review type
 | 
				
			||||||
 | 
					const ReviewTypeUnknown ReviewType = -1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	// ReviewTypeApprove approves changes
 | 
						// ReviewTypeApprove approves changes
 | 
				
			||||||
	ReviewTypeApprove ReviewType = iota
 | 
						ReviewTypeApprove ReviewType = iota
 | 
				
			||||||
@@ -88,33 +94,65 @@ func GetReviewByID(id int64) (*Review, error) {
 | 
				
			|||||||
	return getReviewByID(x, id)
 | 
						return getReviewByID(x, id)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getPendingReviewByReviewerID(e Engine, reviewer *User, issue *Issue) (review *Review, err error) {
 | 
					// FindReviewOptions represent possible filters to find reviews
 | 
				
			||||||
	var exists bool
 | 
					type FindReviewOptions struct {
 | 
				
			||||||
	if exists, err = e.Table("review").Where("reviewer_id = ? and issue_id = ? and type = ?", reviewer.ID, issue.ID, ReviewTypePending).
 | 
						Type       ReviewType
 | 
				
			||||||
		Get(review); !exists && err == nil {
 | 
						IssueID    int64
 | 
				
			||||||
		return nil, nil
 | 
						ReviewerID int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (opts *FindReviewOptions) toCond() builder.Cond {
 | 
				
			||||||
 | 
						var cond = builder.NewCond()
 | 
				
			||||||
 | 
						if opts.IssueID > 0 {
 | 
				
			||||||
 | 
							cond = cond.And(builder.Eq{"issue_id": opts.IssueID})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						if opts.ReviewerID > 0 {
 | 
				
			||||||
 | 
							cond = cond.And(builder.Eq{"reviewer_id": opts.ReviewerID})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if opts.Type != ReviewTypeUnknown {
 | 
				
			||||||
 | 
							cond = cond.And(builder.Eq{"type": opts.Type})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return cond
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetPendingReviewByReviewer returns the latest pending review of reviewer at PR issue
 | 
					func findReviews(e Engine, opts FindReviewOptions) ([]*Review, error) {
 | 
				
			||||||
func GetPendingReviewByReviewer(reviewer *User, issue *Issue) (*Review, error) {
 | 
						reviews := make([]*Review, 0, 10)
 | 
				
			||||||
	return getPendingReviewByReviewerID(x, reviewer, issue)
 | 
						sess := e.Where(opts.toCond())
 | 
				
			||||||
 | 
						return reviews, sess.
 | 
				
			||||||
 | 
							Asc("created_unix").
 | 
				
			||||||
 | 
							Asc("id").
 | 
				
			||||||
 | 
							Find(&reviews)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func createPendingReview(e Engine, reviewer *User, issue *Issue) (*Review, error) {
 | 
					// FindReviews returns reviews passing FindReviewOptions
 | 
				
			||||||
 | 
					func FindReviews(opts FindReviewOptions) ([]*Review, error) {
 | 
				
			||||||
 | 
						return findReviews(x, opts)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CreateReviewOptions represent the options to create a review. Type, Issue and Reviewer are required.
 | 
				
			||||||
 | 
					type CreateReviewOptions struct {
 | 
				
			||||||
 | 
						Content  string
 | 
				
			||||||
 | 
						Type     ReviewType
 | 
				
			||||||
 | 
						Issue    *Issue
 | 
				
			||||||
 | 
						Reviewer *User
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func createReview(e Engine, opts CreateReviewOptions) (*Review, error) {
 | 
				
			||||||
	review := &Review{
 | 
						review := &Review{
 | 
				
			||||||
		Type:       ReviewTypePending,
 | 
							Type:       opts.Type,
 | 
				
			||||||
		Issue:      issue,
 | 
							Issue:      opts.Issue,
 | 
				
			||||||
		IssueID:    issue.ID,
 | 
							IssueID:    opts.Issue.ID,
 | 
				
			||||||
		Reviewer:   reviewer,
 | 
							Reviewer:   opts.Reviewer,
 | 
				
			||||||
		ReviewerID: reviewer.ID,
 | 
							ReviewerID: opts.Reviewer.ID,
 | 
				
			||||||
 | 
							Content:    opts.Content,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	_, err := e.Insert(review)
 | 
						if _, err := e.Insert(review); err != nil {
 | 
				
			||||||
	return review, err
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return review, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreatePendingReview creates an empty pending review
 | 
					// CreateReview creates a new review based on opts
 | 
				
			||||||
func CreatePendingReview(reviewer *User, issue *Issue) (*Review, error) {
 | 
					func CreateReview(opts CreateReviewOptions) (*Review, error) {
 | 
				
			||||||
	return createPendingReview(x, reviewer, issue)
 | 
						return createReview(x, opts)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,7 +42,35 @@ func CreateCodeComment(ctx *context.Context, form auth.CodeCommentForm) {
 | 
				
			|||||||
	if form.Side == "previous" {
 | 
						if form.Side == "previous" {
 | 
				
			||||||
		signedLine *= -1
 | 
							signedLine *= -1
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	//FIXME check if line and treepath exist
 | 
					
 | 
				
			||||||
 | 
						review := new(models.Review)
 | 
				
			||||||
 | 
						if form.IsReview {
 | 
				
			||||||
 | 
							// Check if the user has already a pending review for this issue
 | 
				
			||||||
 | 
							reviews, err := models.FindReviews(models.FindReviewOptions{
 | 
				
			||||||
 | 
								ReviewerID: ctx.User.ID,
 | 
				
			||||||
 | 
								IssueID:    issue.ID,
 | 
				
			||||||
 | 
								Type:       models.ReviewTypePending,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								ctx.ServerError("CreateCodeComment", err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if len(reviews) == 0 {
 | 
				
			||||||
 | 
								// 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
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								review = reviews[0]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//FIXME check if line, commit and treepath exist
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	comment, err = models.CreateCodeComment(
 | 
						comment, err = models.CreateCodeComment(
 | 
				
			||||||
		ctx.User,
 | 
							ctx.User,
 | 
				
			||||||
@@ -52,31 +80,14 @@ func CreateCodeComment(ctx *context.Context, form auth.CodeCommentForm) {
 | 
				
			|||||||
		form.Content,
 | 
							form.Content,
 | 
				
			||||||
		form.TreePath,
 | 
							form.TreePath,
 | 
				
			||||||
		signedLine,
 | 
							signedLine,
 | 
				
			||||||
 | 
							review.ID,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		ctx.ServerError("CreateCodeComment", err)
 | 
							ctx.ServerError("CreateCodeComment", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						// Send no notification if comment is pending
 | 
				
			||||||
	if form.IsReview {
 | 
						if !form.IsReview {
 | 
				
			||||||
		review, err := models.GetPendingReviewByReviewer(ctx.User, issue)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			ctx.ServerError("CreateCodeComment", err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if review == nil {
 | 
					 | 
				
			||||||
			if review, err = models.CreatePendingReview(ctx.User, issue); err != nil {
 | 
					 | 
				
			||||||
				ctx.ServerError("CreateCodeComment", err)
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		comment.Review = review
 | 
					 | 
				
			||||||
		comment.ReviewID = review.ID
 | 
					 | 
				
			||||||
		if err = models.UpdateComment(comment); err != nil {
 | 
					 | 
				
			||||||
			ctx.ServerError("CreateCodeComment", err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		notification.Service.NotifyIssue(issue, ctx.User.ID)
 | 
							notification.Service.NotifyIssue(issue, ctx.User.ID)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user