mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-05-25 11:22:16 +00:00
Some repository refactors (#17950)
* some repository refactors * remove unnecessary code * Fix test * Remove unnecessary banner
This commit is contained in:
parent
0a7e8327a0
commit
5723240490
88 changed files with 1363 additions and 1388 deletions
303
models/repo.go
303
models/repo.go
|
@ -14,7 +14,6 @@ import (
|
|||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
_ "image/jpeg" // Needed for jpeg support
|
||||
|
@ -218,7 +217,7 @@ func getReviewers(ctx context.Context, repo *repo_model.Repository, doerID, post
|
|||
"SELECT uid AS user_id FROM `org_user` WHERE org_id = ? "+
|
||||
") AND id NOT IN (?, ?) ORDER BY name",
|
||||
repo.ID, perm.AccessModeRead,
|
||||
repo.ID, RepoWatchModeNormal, RepoWatchModeAuto,
|
||||
repo.ID, repo_model.WatchModeNormal, repo_model.WatchModeAuto,
|
||||
repo.OwnerID,
|
||||
doerID, posterID).
|
||||
Find(&users); err != nil {
|
||||
|
@ -280,7 +279,7 @@ func CanUserForkRepo(user *user_model.User, repo *repo_model.Repository) (bool,
|
|||
if user == nil {
|
||||
return false, nil
|
||||
}
|
||||
if repo.OwnerID != user.ID && !HasForkedRepo(user.ID, repo.ID) {
|
||||
if repo.OwnerID != user.ID && !repo_model.HasForkedRepo(user.ID, repo.ID) {
|
||||
return true, nil
|
||||
}
|
||||
ownedOrgs, err := GetOrgsCanCreateRepoByUserID(user.ID)
|
||||
|
@ -288,7 +287,7 @@ func CanUserForkRepo(user *user_model.User, repo *repo_model.Repository) (bool,
|
|||
return false, err
|
||||
}
|
||||
for _, org := range ownedOrgs {
|
||||
if repo.OwnerID != org.ID && !HasForkedRepo(org.ID, repo.ID) {
|
||||
if repo.OwnerID != org.ID && !repo_model.HasForkedRepo(org.ID, repo.ID) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
@ -317,24 +316,6 @@ func CanUserDelete(repo *repo_model.Repository, user *user_model.User) (bool, er
|
|||
return false, nil
|
||||
}
|
||||
|
||||
// GetRepoReaders returns all users that have explicit read access or higher to the repository.
|
||||
func GetRepoReaders(repo *repo_model.Repository) (_ []*user_model.User, err error) {
|
||||
return getUsersWithAccessMode(db.DefaultContext, repo, perm.AccessModeRead)
|
||||
}
|
||||
|
||||
// GetRepoWriters returns all users that have write access to the repository.
|
||||
func GetRepoWriters(repo *repo_model.Repository) (_ []*user_model.User, err error) {
|
||||
return getUsersWithAccessMode(db.DefaultContext, repo, perm.AccessModeWrite)
|
||||
}
|
||||
|
||||
// IsRepoReader returns true if user has explicit read access or higher to the repository.
|
||||
func IsRepoReader(repo *repo_model.Repository, userID int64) (bool, error) {
|
||||
if repo.OwnerID == userID {
|
||||
return true, nil
|
||||
}
|
||||
return db.GetEngine(db.DefaultContext).Where("repo_id = ? AND user_id = ? AND mode >= ?", repo.ID, userID, perm.AccessModeRead).Get(&Access{})
|
||||
}
|
||||
|
||||
// getUsersWithAccessMode returns users that have at least given access mode to the repository.
|
||||
func getUsersWithAccessMode(ctx context.Context, repo *repo_model.Repository, mode perm.AccessMode) (_ []*user_model.User, err error) {
|
||||
if err = repo.GetOwner(ctx); err != nil {
|
||||
|
@ -372,35 +353,6 @@ func SetRepoReadBy(repoID, userID int64) error {
|
|||
return setRepoNotificationStatusReadIfUnread(db.GetEngine(db.DefaultContext), userID, repoID)
|
||||
}
|
||||
|
||||
// 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 := repo_model.IsRepositoryExist(u, name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("IsRepositoryExist: %v", err)
|
||||
} else if has {
|
||||
return ErrRepoAlreadyExist{u.Name, name}
|
||||
}
|
||||
|
||||
repoPath := repo_model.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
|
||||
}
|
||||
|
||||
// CreateRepoOptions contains the create repository options
|
||||
type CreateRepoOptions struct {
|
||||
Name string
|
||||
|
@ -421,13 +373,6 @@ type CreateRepoOptions struct {
|
|||
MirrorInterval string
|
||||
}
|
||||
|
||||
// ForkRepoOptions contains the fork repository options
|
||||
type ForkRepoOptions struct {
|
||||
BaseRepo *repo_model.Repository
|
||||
Name string
|
||||
Description string
|
||||
}
|
||||
|
||||
// GetRepoInitFile returns repository init files
|
||||
func GetRepoInitFile(tp, name string) ([]byte, error) {
|
||||
cleanedName := strings.TrimLeft(path.Clean("/"+name), "/")
|
||||
|
@ -457,23 +402,9 @@ func GetRepoInitFile(tp, name string) ([]byte, error) {
|
|||
}
|
||||
}
|
||||
|
||||
var (
|
||||
reservedRepoNames = []string{".", ".."}
|
||||
reservedRepoPatterns = []string{"*.git", "*.wiki", "*.rss", "*.atom"}
|
||||
)
|
||||
|
||||
// IsUsableRepoName returns true when repository is usable
|
||||
func IsUsableRepoName(name string) error {
|
||||
if db.AlphaDashDotPattern.MatchString(name) {
|
||||
// Note: usually this error is normally caught up earlier in the UI
|
||||
return db.ErrNameCharsNotAllowed{Name: name}
|
||||
}
|
||||
return db.IsUsableName(reservedRepoNames, reservedRepoPatterns, name)
|
||||
}
|
||||
|
||||
// CreateRepository creates a repository for the user/organization.
|
||||
func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository, overwriteOrAdopt bool) (err error) {
|
||||
if err = IsUsableRepoName(repo.Name); err != nil {
|
||||
if err = repo_model.IsUsableRepoName(repo.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -481,7 +412,10 @@ func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_
|
|||
if err != nil {
|
||||
return fmt.Errorf("IsRepositoryExist: %v", err)
|
||||
} else if has {
|
||||
return ErrRepoAlreadyExist{u.Name, repo.Name}
|
||||
return repo_model.ErrRepoAlreadyExist{
|
||||
Uname: u.Name,
|
||||
Name: repo.Name,
|
||||
}
|
||||
}
|
||||
|
||||
repoPath := repo_model.RepoPath(u.Name, repo.Name)
|
||||
|
@ -492,7 +426,7 @@ func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_
|
|||
}
|
||||
if !overwriteOrAdopt && isExist {
|
||||
log.Error("Files already exist in %s and we are not going to adopt or delete.", repoPath)
|
||||
return ErrRepoFilesAlreadyExist{
|
||||
return repo_model.ErrRepoFilesAlreadyExist{
|
||||
Uname: u.Name,
|
||||
Name: repo.Name,
|
||||
}
|
||||
|
@ -501,7 +435,7 @@ func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_
|
|||
if err = db.Insert(ctx, repo); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = deleteRepoRedirect(db.GetEngine(ctx), u.ID, repo.Name); err != nil {
|
||||
if err = repo_model.DeleteRedirect(ctx, u.ID, repo.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -578,7 +512,7 @@ func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_
|
|||
}
|
||||
|
||||
if setting.Service.AutoWatchNewRepos {
|
||||
if err = watchRepo(db.GetEngine(ctx), doer.ID, repo.ID, true); err != nil {
|
||||
if err = repo_model.WatchRepoCtx(ctx, doer.ID, repo.ID, true); err != nil {
|
||||
return fmt.Errorf("watchRepo: %v", err)
|
||||
}
|
||||
}
|
||||
|
@ -633,67 +567,6 @@ func DecrementRepoForkNum(ctx context.Context, repoID int64) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
|
||||
func ChangeRepositoryName(doer *user_model.User, repo *repo_model.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 := repo_model.IsRepositoryExist(repo.Owner, newRepoName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("IsRepositoryExist: %v", err)
|
||||
} else if has {
|
||||
return ErrRepoAlreadyExist{repo.Owner.Name, newRepoName}
|
||||
}
|
||||
|
||||
newRepoPath := repo_model.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, repo_model.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 := newRepoRedirect(db.GetEngine(ctx), repo.Owner.ID, repo.ID, oldRepoName, newRepoName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
}
|
||||
|
||||
func getRepositoriesByForkID(e db.Engine, forkID int64) ([]*repo_model.Repository, error) {
|
||||
repos := make([]*repo_model.Repository, 0, 10)
|
||||
return repos, e.
|
||||
Where("fork_id=?", forkID).
|
||||
Find(&repos)
|
||||
}
|
||||
|
||||
// GetRepositoriesByForkID returns all repositories with given fork ID.
|
||||
func GetRepositoriesByForkID(forkID int64) ([]*repo_model.Repository, error) {
|
||||
return getRepositoriesByForkID(db.GetEngine(db.DefaultContext), forkID)
|
||||
}
|
||||
|
||||
func updateRepository(ctx context.Context, repo *repo_model.Repository, visibilityChanged bool) (err error) {
|
||||
repo.LowerName = strings.ToLower(repo.Name)
|
||||
|
||||
|
@ -740,7 +613,7 @@ func updateRepository(ctx context.Context, repo *repo_model.Repository, visibili
|
|||
return err
|
||||
}
|
||||
|
||||
forkRepos, err := getRepositoriesByForkID(e, repo.ID)
|
||||
forkRepos, err := repo_model.GetRepositoriesByForkID(ctx, repo.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getRepositoriesByForkID: %v", err)
|
||||
}
|
||||
|
@ -775,58 +648,6 @@ func UpdateRepository(repo *repo_model.Repository, visibilityChanged bool) (err
|
|||
return committer.Commit()
|
||||
}
|
||||
|
||||
// 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(&repo_model.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
|
||||
}
|
||||
|
||||
// UpdateRepositoryUnits updates a repository's units
|
||||
func UpdateRepositoryUnits(repo *repo_model.Repository, units []repo_model.RepoUnit, deleteUnitTypes []unit.Type) (err error) {
|
||||
ctx, committer, err := db.TxContext()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
// Delete existing settings of units before adding again
|
||||
for _, u := range units {
|
||||
deleteUnitTypes = append(deleteUnitTypes, u.Type)
|
||||
}
|
||||
|
||||
if _, err = db.GetEngine(ctx).Where("repo_id = ?", repo.ID).In("type", deleteUnitTypes).Delete(new(repo_model.RepoUnit)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(units) > 0 {
|
||||
if err = db.Insert(ctx, units); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
}
|
||||
|
||||
// DeleteRepository deletes a repository for a user or organization.
|
||||
// make sure if you call this func to close open sessions (sqlite will otherwise get a deadlock)
|
||||
func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
|
||||
|
@ -927,11 +748,11 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
|
|||
&repo_model.PushMirror{RepoID: repoID},
|
||||
&Release{RepoID: repoID},
|
||||
&repo_model.RepoIndexerStatus{RepoID: repoID},
|
||||
&RepoRedirect{RedirectRepoID: repoID},
|
||||
&repo_model.Redirect{RedirectRepoID: repoID},
|
||||
&repo_model.RepoUnit{RepoID: repoID},
|
||||
&Star{RepoID: repoID},
|
||||
&repo_model.Star{RepoID: repoID},
|
||||
&Task{RepoID: repoID},
|
||||
&Watch{RepoID: repoID},
|
||||
&repo_model.Watch{RepoID: repoID},
|
||||
&webhook.Webhook{RepoID: repoID},
|
||||
); err != nil {
|
||||
return fmt.Errorf("deleteBeans: %v", err)
|
||||
|
@ -964,7 +785,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
|
|||
}
|
||||
|
||||
if len(repo.Topics) > 0 {
|
||||
if err := removeTopicsFromRepo(sess, repo.ID); err != nil {
|
||||
if err := repo_model.RemoveTopicsFromRepo(ctx, repo.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -1261,76 +1082,6 @@ func CheckRepoStats(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// SetArchiveRepoState sets if a repo is archived
|
||||
func SetArchiveRepoState(repo *repo_model.Repository, isArchived bool) (err error) {
|
||||
repo.IsArchived = isArchived
|
||||
_, err = db.GetEngine(db.DefaultContext).Where("id = ?", repo.ID).Cols("is_archived").NoAutoTime().Update(repo)
|
||||
return
|
||||
}
|
||||
|
||||
// ___________ __
|
||||
// \_ _____/__________| | __
|
||||
// | __)/ _ \_ __ \ |/ /
|
||||
// | \( <_> ) | \/ <
|
||||
// \___ / \____/|__| |__|_ \
|
||||
// \/ \/
|
||||
|
||||
// GetForkedRepo checks if given user has already forked a repository with given ID.
|
||||
func GetForkedRepo(ownerID, repoID int64) *repo_model.Repository {
|
||||
repo := new(repo_model.Repository)
|
||||
has, _ := db.GetEngine(db.DefaultContext).
|
||||
Where("owner_id=? AND fork_id=?", ownerID, repoID).
|
||||
Get(repo)
|
||||
if has {
|
||||
return repo
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasForkedRepo checks if given user has already forked a repository with given ID.
|
||||
func HasForkedRepo(ownerID, repoID int64) bool {
|
||||
has, _ := db.GetEngine(db.DefaultContext).
|
||||
Table("repository").
|
||||
Where("owner_id=? AND fork_id=?", ownerID, repoID).
|
||||
Exist()
|
||||
return has
|
||||
}
|
||||
|
||||
// GetForks returns all the forks of the repository
|
||||
func GetForks(repo *repo_model.Repository, listOptions db.ListOptions) ([]*repo_model.Repository, error) {
|
||||
if listOptions.Page == 0 {
|
||||
forks := make([]*repo_model.Repository, 0, repo.NumForks)
|
||||
return forks, db.GetEngine(db.DefaultContext).Find(&forks, &repo_model.Repository{ForkID: repo.ID})
|
||||
}
|
||||
|
||||
sess := db.GetPaginatedSession(&listOptions)
|
||||
forks := make([]*repo_model.Repository, 0, listOptions.PageSize)
|
||||
return forks, sess.Find(&forks, &repo_model.Repository{ForkID: repo.ID})
|
||||
}
|
||||
|
||||
// GetUserFork return user forked repository from this repository, if not forked return nil
|
||||
func GetUserFork(repoID, userID int64) (*repo_model.Repository, error) {
|
||||
var forkedRepo repo_model.Repository
|
||||
has, err := db.GetEngine(db.DefaultContext).Where("fork_id = ?", repoID).And("owner_id = ?", userID).Get(&forkedRepo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !has {
|
||||
return nil, nil
|
||||
}
|
||||
return &forkedRepo, nil
|
||||
}
|
||||
|
||||
func updateRepositoryCols(e db.Engine, repo *repo_model.Repository, cols ...string) error {
|
||||
_, err := e.ID(repo.ID).Cols(cols...).Update(repo)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateRepositoryCols updates repository's columns
|
||||
func UpdateRepositoryCols(repo *repo_model.Repository, cols ...string) error {
|
||||
return updateRepositoryCols(db.GetEngine(db.DefaultContext), repo, cols...)
|
||||
}
|
||||
|
||||
func updateUserStarNumbers(users []user_model.User) error {
|
||||
ctx, committer, err := db.TxContext()
|
||||
if err != nil {
|
||||
|
@ -1370,28 +1121,6 @@ func DoctorUserStarNum() (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// IterateRepository iterate repositories
|
||||
func IterateRepository(f func(repo *repo_model.Repository) error) error {
|
||||
var start int
|
||||
batchSize := setting.Database.IterateBufferSize
|
||||
for {
|
||||
repos := make([]*repo_model.Repository, 0, batchSize)
|
||||
if err := db.GetEngine(db.DefaultContext).Limit(batchSize, start).Find(&repos); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(repos) == 0 {
|
||||
return nil
|
||||
}
|
||||
start += len(repos)
|
||||
|
||||
for _, repo := range repos {
|
||||
if err := f(repo); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LinkedRepository returns the linked repo if any
|
||||
func LinkedRepository(a *repo_model.Attachment) (*repo_model.Repository, unit.Type, error) {
|
||||
if a.IssueID != 0 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue