Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

commits.go 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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 repository
  5. import (
  6. "container/list"
  7. "fmt"
  8. "time"
  9. "code.gitea.io/gitea/models"
  10. "code.gitea.io/gitea/modules/base"
  11. "code.gitea.io/gitea/modules/git"
  12. "code.gitea.io/gitea/modules/log"
  13. api "code.gitea.io/gitea/modules/structs"
  14. )
  15. // PushCommit represents a commit in a push operation.
  16. type PushCommit struct {
  17. Sha1 string
  18. Message string
  19. AuthorEmail string
  20. AuthorName string
  21. CommitterEmail string
  22. CommitterName string
  23. Timestamp time.Time
  24. }
  25. // PushCommits represents list of commits in a push operation.
  26. type PushCommits struct {
  27. Len int
  28. Commits []*PushCommit
  29. CompareURL string
  30. avatars map[string]string
  31. emailUsers map[string]*models.User
  32. }
  33. // NewPushCommits creates a new PushCommits object.
  34. func NewPushCommits() *PushCommits {
  35. return &PushCommits{
  36. avatars: make(map[string]string),
  37. emailUsers: make(map[string]*models.User),
  38. }
  39. }
  40. // ToAPIPayloadCommits converts a PushCommits object to
  41. // api.PayloadCommit format.
  42. func (pc *PushCommits) ToAPIPayloadCommits(repoPath, repoLink string) ([]*api.PayloadCommit, error) {
  43. commits := make([]*api.PayloadCommit, len(pc.Commits))
  44. if pc.emailUsers == nil {
  45. pc.emailUsers = make(map[string]*models.User)
  46. }
  47. var err error
  48. for i, commit := range pc.Commits {
  49. authorUsername := ""
  50. author, ok := pc.emailUsers[commit.AuthorEmail]
  51. if !ok {
  52. author, err = models.GetUserByEmail(commit.AuthorEmail)
  53. if err == nil {
  54. authorUsername = author.Name
  55. pc.emailUsers[commit.AuthorEmail] = author
  56. }
  57. } else {
  58. authorUsername = author.Name
  59. }
  60. committerUsername := ""
  61. committer, ok := pc.emailUsers[commit.CommitterEmail]
  62. if !ok {
  63. committer, err = models.GetUserByEmail(commit.CommitterEmail)
  64. if err == nil {
  65. // TODO: check errors other than email not found.
  66. committerUsername = committer.Name
  67. pc.emailUsers[commit.CommitterEmail] = committer
  68. }
  69. } else {
  70. committerUsername = committer.Name
  71. }
  72. fileStatus, err := git.GetCommitFileStatus(repoPath, commit.Sha1)
  73. if err != nil {
  74. return nil, fmt.Errorf("FileStatus [commit_sha1: %s]: %v", commit.Sha1, err)
  75. }
  76. commits[i] = &api.PayloadCommit{
  77. ID: commit.Sha1,
  78. Message: commit.Message,
  79. URL: fmt.Sprintf("%s/commit/%s", repoLink, commit.Sha1),
  80. Author: &api.PayloadUser{
  81. Name: commit.AuthorName,
  82. Email: commit.AuthorEmail,
  83. UserName: authorUsername,
  84. },
  85. Committer: &api.PayloadUser{
  86. Name: commit.CommitterName,
  87. Email: commit.CommitterEmail,
  88. UserName: committerUsername,
  89. },
  90. Added: fileStatus.Added,
  91. Removed: fileStatus.Removed,
  92. Modified: fileStatus.Modified,
  93. Timestamp: commit.Timestamp,
  94. }
  95. }
  96. return commits, nil
  97. }
  98. // AvatarLink tries to match user in database with e-mail
  99. // in order to show custom avatar, and falls back to general avatar link.
  100. func (pc *PushCommits) AvatarLink(email string) string {
  101. if pc.avatars == nil {
  102. pc.avatars = make(map[string]string)
  103. }
  104. avatar, ok := pc.avatars[email]
  105. if ok {
  106. return avatar
  107. }
  108. u, ok := pc.emailUsers[email]
  109. if !ok {
  110. var err error
  111. u, err = models.GetUserByEmail(email)
  112. if err != nil {
  113. pc.avatars[email] = base.AvatarLink(email)
  114. if !models.IsErrUserNotExist(err) {
  115. log.Error("GetUserByEmail: %v", err)
  116. return ""
  117. }
  118. } else {
  119. pc.emailUsers[email] = u
  120. }
  121. }
  122. if u != nil {
  123. pc.avatars[email] = u.RelAvatarLink()
  124. }
  125. return pc.avatars[email]
  126. }
  127. // CommitToPushCommit transforms a git.Commit to PushCommit type.
  128. func CommitToPushCommit(commit *git.Commit) *PushCommit {
  129. return &PushCommit{
  130. Sha1: commit.ID.String(),
  131. Message: commit.Message(),
  132. AuthorEmail: commit.Author.Email,
  133. AuthorName: commit.Author.Name,
  134. CommitterEmail: commit.Committer.Email,
  135. CommitterName: commit.Committer.Name,
  136. Timestamp: commit.Author.When,
  137. }
  138. }
  139. // ListToPushCommits transforms a list.List to PushCommits type.
  140. func ListToPushCommits(l *list.List) *PushCommits {
  141. var commits []*PushCommit
  142. var actEmail string
  143. for e := l.Front(); e != nil; e = e.Next() {
  144. commit := e.Value.(*git.Commit)
  145. if actEmail == "" {
  146. actEmail = commit.Committer.Email
  147. }
  148. commits = append(commits, CommitToPushCommit(commit))
  149. }
  150. return &PushCommits{l.Len(), commits, "", make(map[string]string), make(map[string]*models.User)}
  151. }