Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package comments
  5. import (
  6. "bytes"
  7. "fmt"
  8. "strings"
  9. "code.gitea.io/gitea/models"
  10. "code.gitea.io/gitea/modules/git"
  11. "code.gitea.io/gitea/modules/notification"
  12. "code.gitea.io/gitea/modules/setting"
  13. "code.gitea.io/gitea/services/gitdiff"
  14. )
  15. // CreateIssueComment creates a plain issue comment.
  16. func CreateIssueComment(doer *models.User, repo *models.Repository, issue *models.Issue, content string, attachments []string) (*models.Comment, error) {
  17. comment, err := models.CreateComment(&models.CreateCommentOptions{
  18. Type: models.CommentTypeComment,
  19. Doer: doer,
  20. Repo: repo,
  21. Issue: issue,
  22. Content: content,
  23. Attachments: attachments,
  24. })
  25. if err != nil {
  26. return nil, err
  27. }
  28. notification.NotifyCreateIssueComment(doer, repo, issue, comment)
  29. return comment, nil
  30. }
  31. // CreateCodeComment creates a plain code comment at the specified line / path
  32. func CreateCodeComment(doer *models.User, repo *models.Repository, issue *models.Issue, content, treePath string, line, reviewID int64) (*models.Comment, error) {
  33. var commitID, patch string
  34. pr, err := models.GetPullRequestByIssueID(issue.ID)
  35. if err != nil {
  36. return nil, fmt.Errorf("GetPullRequestByIssueID: %v", err)
  37. }
  38. if err := pr.GetBaseRepo(); err != nil {
  39. return nil, fmt.Errorf("GetHeadRepo: %v", err)
  40. }
  41. gitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath())
  42. if err != nil {
  43. return nil, fmt.Errorf("OpenRepository: %v", err)
  44. }
  45. defer gitRepo.Close()
  46. // FIXME validate treePath
  47. // Get latest commit referencing the commented line
  48. // No need for get commit for base branch changes
  49. if line > 0 {
  50. commit, err := gitRepo.LineBlame(pr.GetGitRefName(), gitRepo.Path, treePath, uint(line))
  51. if err == nil {
  52. commitID = commit.ID.String()
  53. } else if !strings.Contains(err.Error(), "exit status 128 - fatal: no such path") {
  54. return nil, fmt.Errorf("LineBlame[%s, %s, %s, %d]: %v", pr.GetGitRefName(), gitRepo.Path, treePath, line, err)
  55. }
  56. }
  57. // Only fetch diff if comment is review comment
  58. if reviewID != 0 {
  59. headCommitID, err := gitRepo.GetRefCommitID(pr.GetGitRefName())
  60. if err != nil {
  61. return nil, fmt.Errorf("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err)
  62. }
  63. patchBuf := new(bytes.Buffer)
  64. if err := gitdiff.GetRawDiffForFile(gitRepo.Path, pr.MergeBase, headCommitID, gitdiff.RawDiffNormal, treePath, patchBuf); err != nil {
  65. return nil, fmt.Errorf("GetRawDiffForLine[%s, %s, %s, %s]: %v", err, gitRepo.Path, pr.MergeBase, headCommitID, treePath)
  66. }
  67. patch = gitdiff.CutDiffAroundLine(patchBuf, int64((&models.Comment{Line: line}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines)
  68. }
  69. return models.CreateComment(&models.CreateCommentOptions{
  70. Type: models.CommentTypeCode,
  71. Doer: doer,
  72. Repo: repo,
  73. Issue: issue,
  74. Content: content,
  75. LineNum: line,
  76. TreePath: treePath,
  77. CommitSHA: commitID,
  78. ReviewID: reviewID,
  79. Patch: patch,
  80. })
  81. }
  82. // UpdateComment updates information of comment.
  83. func UpdateComment(c *models.Comment, doer *models.User, oldContent string) error {
  84. if err := models.UpdateComment(c, doer); err != nil {
  85. return err
  86. }
  87. notification.NotifyUpdateComment(doer, c, oldContent)
  88. return nil
  89. }
  90. // DeleteComment deletes the comment
  91. func DeleteComment(comment *models.Comment, doer *models.User) error {
  92. if err := models.DeleteComment(comment, doer); err != nil {
  93. return err
  94. }
  95. notification.NotifyDeleteComment(doer, comment)
  96. return nil
  97. }