You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

update.go 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Copyright 2021 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 repo
  5. import (
  6. "context"
  7. "fmt"
  8. "strings"
  9. "time"
  10. "code.gitea.io/gitea/models/db"
  11. user_model "code.gitea.io/gitea/models/user"
  12. "code.gitea.io/gitea/modules/log"
  13. "code.gitea.io/gitea/modules/util"
  14. )
  15. // UpdateRepositoryOwnerNames updates repository owner_names (this should only be used when the ownerName has changed case)
  16. func UpdateRepositoryOwnerNames(ownerID int64, ownerName string) error {
  17. if ownerID == 0 {
  18. return nil
  19. }
  20. ctx, committer, err := db.TxContext()
  21. if err != nil {
  22. return err
  23. }
  24. defer committer.Close()
  25. if _, err := db.GetEngine(ctx).Where("owner_id = ?", ownerID).Cols("owner_name").Update(&Repository{
  26. OwnerName: ownerName,
  27. }); err != nil {
  28. return err
  29. }
  30. return committer.Commit()
  31. }
  32. // UpdateRepositoryUpdatedTime updates a repository's updated time
  33. func UpdateRepositoryUpdatedTime(repoID int64, updateTime time.Time) error {
  34. _, err := db.GetEngine(db.DefaultContext).Exec("UPDATE repository SET updated_unix = ? WHERE id = ?", updateTime.Unix(), repoID)
  35. return err
  36. }
  37. // UpdateRepositoryCols updates repository's columns
  38. func UpdateRepositoryCols(ctx context.Context, repo *Repository, cols ...string) error {
  39. _, err := db.GetEngine(ctx).ID(repo.ID).Cols(cols...).Update(repo)
  40. return err
  41. }
  42. // ErrReachLimitOfRepo represents a "ReachLimitOfRepo" kind of error.
  43. type ErrReachLimitOfRepo struct {
  44. Limit int
  45. }
  46. // IsErrReachLimitOfRepo checks if an error is a ErrReachLimitOfRepo.
  47. func IsErrReachLimitOfRepo(err error) bool {
  48. _, ok := err.(ErrReachLimitOfRepo)
  49. return ok
  50. }
  51. func (err ErrReachLimitOfRepo) Error() string {
  52. return fmt.Sprintf("user has reached maximum limit of repositories [limit: %d]", err.Limit)
  53. }
  54. // ErrRepoAlreadyExist represents a "RepoAlreadyExist" kind of error.
  55. type ErrRepoAlreadyExist struct {
  56. Uname string
  57. Name string
  58. }
  59. // IsErrRepoAlreadyExist checks if an error is a ErrRepoAlreadyExist.
  60. func IsErrRepoAlreadyExist(err error) bool {
  61. _, ok := err.(ErrRepoAlreadyExist)
  62. return ok
  63. }
  64. func (err ErrRepoAlreadyExist) Error() string {
  65. return fmt.Sprintf("repository already exists [uname: %s, name: %s]", err.Uname, err.Name)
  66. }
  67. // ErrRepoFilesAlreadyExist represents a "RepoFilesAlreadyExist" kind of error.
  68. type ErrRepoFilesAlreadyExist struct {
  69. Uname string
  70. Name string
  71. }
  72. // IsErrRepoFilesAlreadyExist checks if an error is a ErrRepoAlreadyExist.
  73. func IsErrRepoFilesAlreadyExist(err error) bool {
  74. _, ok := err.(ErrRepoFilesAlreadyExist)
  75. return ok
  76. }
  77. func (err ErrRepoFilesAlreadyExist) Error() string {
  78. return fmt.Sprintf("repository files already exist [uname: %s, name: %s]", err.Uname, err.Name)
  79. }
  80. // CheckCreateRepository check if could created a repository
  81. func CheckCreateRepository(doer, u *user_model.User, name string, overwriteOrAdopt bool) error {
  82. if !doer.CanCreateRepo() {
  83. return ErrReachLimitOfRepo{u.MaxRepoCreation}
  84. }
  85. if err := IsUsableRepoName(name); err != nil {
  86. return err
  87. }
  88. has, err := IsRepositoryExist(db.DefaultContext, u, name)
  89. if err != nil {
  90. return fmt.Errorf("IsRepositoryExist: %v", err)
  91. } else if has {
  92. return ErrRepoAlreadyExist{u.Name, name}
  93. }
  94. repoPath := RepoPath(u.Name, name)
  95. isExist, err := util.IsExist(repoPath)
  96. if err != nil {
  97. log.Error("Unable to check if %s exists. Error: %v", repoPath, err)
  98. return err
  99. }
  100. if !overwriteOrAdopt && isExist {
  101. return ErrRepoFilesAlreadyExist{u.Name, name}
  102. }
  103. return nil
  104. }
  105. // ChangeRepositoryName changes all corresponding setting from old repository name to new one.
  106. func ChangeRepositoryName(doer *user_model.User, repo *Repository, newRepoName string) (err error) {
  107. oldRepoName := repo.Name
  108. newRepoName = strings.ToLower(newRepoName)
  109. if err = IsUsableRepoName(newRepoName); err != nil {
  110. return err
  111. }
  112. if err := repo.GetOwner(db.DefaultContext); err != nil {
  113. return err
  114. }
  115. has, err := IsRepositoryExist(db.DefaultContext, repo.Owner, newRepoName)
  116. if err != nil {
  117. return fmt.Errorf("IsRepositoryExist: %v", err)
  118. } else if has {
  119. return ErrRepoAlreadyExist{repo.Owner.Name, newRepoName}
  120. }
  121. newRepoPath := RepoPath(repo.Owner.Name, newRepoName)
  122. if err = util.Rename(repo.RepoPath(), newRepoPath); err != nil {
  123. return fmt.Errorf("rename repository directory: %v", err)
  124. }
  125. wikiPath := repo.WikiPath()
  126. isExist, err := util.IsExist(wikiPath)
  127. if err != nil {
  128. log.Error("Unable to check if %s exists. Error: %v", wikiPath, err)
  129. return err
  130. }
  131. if isExist {
  132. if err = util.Rename(wikiPath, WikiPath(repo.Owner.Name, newRepoName)); err != nil {
  133. return fmt.Errorf("rename repository wiki: %v", err)
  134. }
  135. }
  136. ctx, committer, err := db.TxContext()
  137. if err != nil {
  138. return err
  139. }
  140. defer committer.Close()
  141. if err := NewRedirect(ctx, repo.Owner.ID, repo.ID, oldRepoName, newRepoName); err != nil {
  142. return err
  143. }
  144. return committer.Commit()
  145. }