mirror of
https://github.com/go-gitea/gitea.git
synced 2024-12-15 17:49:20 +08:00
180 lines
5.0 KiB
Go
180 lines
5.0 KiB
Go
|
// Copyright 2021 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 (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"code.gitea.io/gitea/models/db"
|
||
|
user_model "code.gitea.io/gitea/models/user"
|
||
|
"code.gitea.io/gitea/modules/log"
|
||
|
"code.gitea.io/gitea/modules/util"
|
||
|
)
|
||
|
|
||
|
// UpdateRepositoryOwnerNames updates repository owner_names (this should only be used when the ownerName has changed case)
|
||
|
func UpdateRepositoryOwnerNames(ownerID int64, ownerName string) error {
|
||
|
if ownerID == 0 {
|
||
|
return nil
|
||
|
}
|
||
|
ctx, committer, err := db.TxContext()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer committer.Close()
|
||
|
|
||
|
if _, err := db.GetEngine(ctx).Where("owner_id = ?", ownerID).Cols("owner_name").Update(&Repository{
|
||
|
OwnerName: ownerName,
|
||
|
}); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return committer.Commit()
|
||
|
}
|
||
|
|
||
|
// UpdateRepositoryUpdatedTime updates a repository's updated time
|
||
|
func UpdateRepositoryUpdatedTime(repoID int64, updateTime time.Time) error {
|
||
|
_, err := db.GetEngine(db.DefaultContext).Exec("UPDATE repository SET updated_unix = ? WHERE id = ?", updateTime.Unix(), repoID)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// UpdateRepositoryColsCtx updates repository's columns
|
||
|
func UpdateRepositoryColsCtx(ctx context.Context, repo *Repository, cols ...string) error {
|
||
|
_, err := db.GetEngine(ctx).ID(repo.ID).Cols(cols...).Update(repo)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// UpdateRepositoryCols updates repository's columns
|
||
|
func UpdateRepositoryCols(repo *Repository, cols ...string) error {
|
||
|
return UpdateRepositoryColsCtx(db.DefaultContext, repo, cols...)
|
||
|
}
|
||
|
|
||
|
// ErrReachLimitOfRepo represents a "ReachLimitOfRepo" kind of error.
|
||
|
type ErrReachLimitOfRepo struct {
|
||
|
Limit int
|
||
|
}
|
||
|
|
||
|
// IsErrReachLimitOfRepo checks if an error is a ErrReachLimitOfRepo.
|
||
|
func IsErrReachLimitOfRepo(err error) bool {
|
||
|
_, ok := err.(ErrReachLimitOfRepo)
|
||
|
return ok
|
||
|
}
|
||
|
|
||
|
func (err ErrReachLimitOfRepo) Error() string {
|
||
|
return fmt.Sprintf("user has reached maximum limit of repositories [limit: %d]", err.Limit)
|
||
|
}
|
||
|
|
||
|
// ErrRepoAlreadyExist represents a "RepoAlreadyExist" kind of error.
|
||
|
type ErrRepoAlreadyExist struct {
|
||
|
Uname string
|
||
|
Name string
|
||
|
}
|
||
|
|
||
|
// IsErrRepoAlreadyExist checks if an error is a ErrRepoAlreadyExist.
|
||
|
func IsErrRepoAlreadyExist(err error) bool {
|
||
|
_, ok := err.(ErrRepoAlreadyExist)
|
||
|
return ok
|
||
|
}
|
||
|
|
||
|
func (err ErrRepoAlreadyExist) Error() string {
|
||
|
return fmt.Sprintf("repository already exists [uname: %s, name: %s]", err.Uname, err.Name)
|
||
|
}
|
||
|
|
||
|
// ErrRepoFilesAlreadyExist represents a "RepoFilesAlreadyExist" kind of error.
|
||
|
type ErrRepoFilesAlreadyExist struct {
|
||
|
Uname string
|
||
|
Name string
|
||
|
}
|
||
|
|
||
|
// IsErrRepoFilesAlreadyExist checks if an error is a ErrRepoAlreadyExist.
|
||
|
func IsErrRepoFilesAlreadyExist(err error) bool {
|
||
|
_, ok := err.(ErrRepoFilesAlreadyExist)
|
||
|
return ok
|
||
|
}
|
||
|
|
||
|
func (err ErrRepoFilesAlreadyExist) Error() string {
|
||
|
return fmt.Sprintf("repository files already exist [uname: %s, name: %s]", err.Uname, err.Name)
|
||
|
}
|
||
|
|
||
|
// CheckCreateRepository check if could created a repository
|
||
|
func CheckCreateRepository(doer, u *user_model.User, name string, overwriteOrAdopt bool) error {
|
||
|
if !doer.CanCreateRepo() {
|
||
|
return ErrReachLimitOfRepo{u.MaxRepoCreation}
|
||
|
}
|
||
|
|
||
|
if err := IsUsableRepoName(name); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
has, err := IsRepositoryExist(u, name)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("IsRepositoryExist: %v", err)
|
||
|
} else if has {
|
||
|
return ErrRepoAlreadyExist{u.Name, name}
|
||
|
}
|
||
|
|
||
|
repoPath := RepoPath(u.Name, name)
|
||
|
isExist, err := util.IsExist(repoPath)
|
||
|
if err != nil {
|
||
|
log.Error("Unable to check if %s exists. Error: %v", repoPath, err)
|
||
|
return err
|
||
|
}
|
||
|
if !overwriteOrAdopt && isExist {
|
||
|
return ErrRepoFilesAlreadyExist{u.Name, name}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
|
||
|
func ChangeRepositoryName(doer *user_model.User, repo *Repository, newRepoName string) (err error) {
|
||
|
oldRepoName := repo.Name
|
||
|
newRepoName = strings.ToLower(newRepoName)
|
||
|
if err = IsUsableRepoName(newRepoName); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if err := repo.GetOwner(db.DefaultContext); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
has, err := IsRepositoryExist(repo.Owner, newRepoName)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("IsRepositoryExist: %v", err)
|
||
|
} else if has {
|
||
|
return ErrRepoAlreadyExist{repo.Owner.Name, newRepoName}
|
||
|
}
|
||
|
|
||
|
newRepoPath := RepoPath(repo.Owner.Name, newRepoName)
|
||
|
if err = util.Rename(repo.RepoPath(), newRepoPath); err != nil {
|
||
|
return fmt.Errorf("rename repository directory: %v", err)
|
||
|
}
|
||
|
|
||
|
wikiPath := repo.WikiPath()
|
||
|
isExist, err := util.IsExist(wikiPath)
|
||
|
if err != nil {
|
||
|
log.Error("Unable to check if %s exists. Error: %v", wikiPath, err)
|
||
|
return err
|
||
|
}
|
||
|
if isExist {
|
||
|
if err = util.Rename(wikiPath, WikiPath(repo.Owner.Name, newRepoName)); err != nil {
|
||
|
return fmt.Errorf("rename repository wiki: %v", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ctx, committer, err := db.TxContext()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer committer.Close()
|
||
|
|
||
|
if err := NewRedirect(ctx, repo.Owner.ID, repo.ID, oldRepoName, newRepoName); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return committer.Commit()
|
||
|
}
|