mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	* some repository refactors * remove unnecessary code * Fix test * Remove unnecessary banner
		
			
				
	
	
		
			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()
 | 
						|
}
 |