Move RepoTransfer into models/repo sub package

This commit is contained in:
Lunny Xiao 2024-11-16 18:36:55 -08:00
parent ec9cece5fd
commit 728a6428c7
No known key found for this signature in database
GPG Key ID: C3B7C91B632F738A
11 changed files with 79 additions and 86 deletions

View File

@ -72,48 +72,6 @@ func (err ErrDeleteLastAdminUser) Error() string {
return fmt.Sprintf("can not delete the last admin user [uid: %d]", err.UID) return fmt.Sprintf("can not delete the last admin user [uid: %d]", err.UID)
} }
// ErrNoPendingRepoTransfer is an error type for repositories without a pending
// transfer request
type ErrNoPendingRepoTransfer struct {
RepoID int64
}
func (err ErrNoPendingRepoTransfer) Error() string {
return fmt.Sprintf("repository doesn't have a pending transfer [repo_id: %d]", err.RepoID)
}
// IsErrNoPendingTransfer is an error type when a repository has no pending
// transfers
func IsErrNoPendingTransfer(err error) bool {
_, ok := err.(ErrNoPendingRepoTransfer)
return ok
}
func (err ErrNoPendingRepoTransfer) Unwrap() error {
return util.ErrNotExist
}
// ErrRepoTransferInProgress represents the state of a repository that has an
// ongoing transfer
type ErrRepoTransferInProgress struct {
Uname string
Name string
}
// IsErrRepoTransferInProgress checks if an error is a ErrRepoTransferInProgress.
func IsErrRepoTransferInProgress(err error) bool {
_, ok := err.(ErrRepoTransferInProgress)
return ok
}
func (err ErrRepoTransferInProgress) Error() string {
return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name)
}
func (err ErrRepoTransferInProgress) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error. // ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error.
type ErrInvalidCloneAddr struct { type ErrInvalidCloneAddr struct {
Host string Host string

View File

@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved. // Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
package models package repo
import ( import (
"context" "context"
@ -10,16 +10,58 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/organization"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"xorm.io/builder" "xorm.io/builder"
) )
// ErrNoPendingRepoTransfer is an error type for repositories without a pending
// transfer request
type ErrNoPendingRepoTransfer struct {
RepoID int64
}
func (err ErrNoPendingRepoTransfer) Error() string {
return fmt.Sprintf("repository doesn't have a pending transfer [repo_id: %d]", err.RepoID)
}
// IsErrNoPendingTransfer is an error type when a repository has no pending
// transfers
func IsErrNoPendingTransfer(err error) bool {
_, ok := err.(ErrNoPendingRepoTransfer)
return ok
}
func (err ErrNoPendingRepoTransfer) Unwrap() error {
return util.ErrNotExist
}
// ErrRepoTransferInProgress represents the state of a repository that has an
// ongoing transfer
type ErrRepoTransferInProgress struct {
Uname string
Name string
}
// IsErrRepoTransferInProgress checks if an error is a ErrRepoTransferInProgress.
func IsErrRepoTransferInProgress(err error) bool {
_, ok := err.(ErrRepoTransferInProgress)
return ok
}
func (err ErrRepoTransferInProgress) Error() string {
return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name)
}
func (err ErrRepoTransferInProgress) Unwrap() error {
return util.ErrAlreadyExist
}
// RepoTransfer is used to manage repository transfers // RepoTransfer is used to manage repository transfers
type RepoTransfer struct { type RepoTransfer struct { //nolint
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
DoerID int64 DoerID int64
Doer *user_model.User `xorm:"-"` Doer *user_model.User `xorm:"-"`
@ -126,7 +168,7 @@ func GetPendingRepositoryTransfers(ctx context.Context, opts *PendingRepositoryT
// GetPendingRepositoryTransfer fetches the most recent and ongoing transfer // GetPendingRepositoryTransfer fetches the most recent and ongoing transfer
// process for the repository // process for the repository
func GetPendingRepositoryTransfer(ctx context.Context, repo *repo_model.Repository) (*RepoTransfer, error) { func GetPendingRepositoryTransfer(ctx context.Context, repo *Repository) (*RepoTransfer, error) {
transfers, err := GetPendingRepositoryTransfers(ctx, &PendingRepositoryTransferOptions{RepoID: repo.ID}) transfers, err := GetPendingRepositoryTransfers(ctx, &PendingRepositoryTransferOptions{RepoID: repo.ID})
if err != nil { if err != nil {
return nil, err return nil, err
@ -145,11 +187,11 @@ func DeleteRepositoryTransfer(ctx context.Context, repoID int64) error {
} }
// TestRepositoryReadyForTransfer make sure repo is ready to transfer // TestRepositoryReadyForTransfer make sure repo is ready to transfer
func TestRepositoryReadyForTransfer(status repo_model.RepositoryStatus) error { func TestRepositoryReadyForTransfer(status RepositoryStatus) error {
switch status { switch status {
case repo_model.RepositoryBeingMigrated: case RepositoryBeingMigrated:
return errors.New("repo is not ready, currently migrating") return errors.New("repo is not ready, currently migrating")
case repo_model.RepositoryPendingTransfer: case RepositoryPendingTransfer:
return ErrRepoTransferInProgress{} return ErrRepoTransferInProgress{}
} }
return nil return nil
@ -159,7 +201,7 @@ func TestRepositoryReadyForTransfer(status repo_model.RepositoryStatus) error {
// it marks the repository transfer as "pending" // it marks the repository transfer as "pending"
func CreatePendingRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.User, repoID int64, teams []*organization.Team) error { func CreatePendingRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.User, repoID int64, teams []*organization.Team) error {
return db.WithTx(ctx, func(ctx context.Context) error { return db.WithTx(ctx, func(ctx context.Context) error {
repo, err := repo_model.GetRepositoryByID(ctx, repoID) repo, err := GetRepositoryByID(ctx, repoID)
if err != nil { if err != nil {
return err return err
} }
@ -169,16 +211,16 @@ func CreatePendingRepositoryTransfer(ctx context.Context, doer, newOwner *user_m
return err return err
} }
repo.Status = repo_model.RepositoryPendingTransfer repo.Status = RepositoryPendingTransfer
if err := repo_model.UpdateRepositoryCols(ctx, repo, "status"); err != nil { if err := UpdateRepositoryCols(ctx, repo, "status"); err != nil {
return err return err
} }
// Check if new owner has repository with same name. // Check if new owner has repository with same name.
if has, err := repo_model.IsRepositoryModelExist(ctx, newOwner, repo.Name); err != nil { if has, err := IsRepositoryModelExist(ctx, newOwner, repo.Name); err != nil {
return fmt.Errorf("IsRepositoryExist: %w", err) return fmt.Errorf("IsRepositoryExist: %w", err)
} else if has { } else if has {
return repo_model.ErrRepoAlreadyExist{ return ErrRepoAlreadyExist{
Uname: newOwner.LowerName, Uname: newOwner.LowerName,
Name: repo.Name, Name: repo.Name,
} }

View File

@ -8,7 +8,6 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/perm"
access_model "code.gitea.io/gitea/models/perm/access" access_model "code.gitea.io/gitea/models/perm/access"
@ -108,7 +107,7 @@ func Transfer(ctx *context.APIContext) {
oldFullname := ctx.Repo.Repository.FullName() oldFullname := ctx.Repo.Repository.FullName()
if err := repo_service.StartRepositoryTransfer(ctx, ctx.Doer, newOwner, ctx.Repo.Repository, teams); err != nil { if err := repo_service.StartRepositoryTransfer(ctx, ctx.Doer, newOwner, ctx.Repo.Repository, teams); err != nil {
if models.IsErrRepoTransferInProgress(err) { if repo_model.IsErrRepoTransferInProgress(err) {
ctx.Error(http.StatusConflict, "StartRepositoryTransfer", err) ctx.Error(http.StatusConflict, "StartRepositoryTransfer", err)
return return
} }
@ -213,9 +212,9 @@ func RejectTransfer(ctx *context.APIContext) {
} }
func acceptOrRejectRepoTransfer(ctx *context.APIContext, accept bool) error { func acceptOrRejectRepoTransfer(ctx *context.APIContext, accept bool) error {
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository) repoTransfer, err := repo_model.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
if models.IsErrNoPendingTransfer(err) { if repo_model.IsErrNoPendingTransfer(err) {
ctx.NotFound() ctx.NotFound()
return nil return nil
} }

View File

@ -11,7 +11,6 @@ import (
"slices" "slices"
"strings" "strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git" git_model "code.gitea.io/gitea/models/git"
"code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/organization"
@ -375,7 +374,7 @@ func Action(ctx *context.Context) {
} }
func acceptOrRejectRepoTransfer(ctx *context.Context, accept bool) error { func acceptOrRejectRepoTransfer(ctx *context.Context, accept bool) error {
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository) repoTransfer, err := repo_model.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
return err return err
} }

View File

@ -787,7 +787,7 @@ func SettingsPost(ctx *context.Context) {
if err := repo_service.StartRepositoryTransfer(ctx, ctx.Doer, newOwner, repo, nil); err != nil { if err := repo_service.StartRepositoryTransfer(ctx, ctx.Doer, newOwner, repo, nil); err != nil {
if repo_model.IsErrRepoAlreadyExist(err) { if repo_model.IsErrRepoAlreadyExist(err) {
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil) ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil)
} else if models.IsErrRepoTransferInProgress(err) { } else if repo_model.IsErrRepoTransferInProgress(err) {
ctx.RenderWithErr(ctx.Tr("repo.settings.transfer_in_progress"), tplSettingsOptions, nil) ctx.RenderWithErr(ctx.Tr("repo.settings.transfer_in_progress"), tplSettingsOptions, nil)
} else if errors.Is(err, user_model.ErrBlockedUser) { } else if errors.Is(err, user_model.ErrBlockedUser) {
ctx.RenderWithErr(ctx.Tr("repo.settings.transfer.blocked_user"), tplSettingsOptions, nil) ctx.RenderWithErr(ctx.Tr("repo.settings.transfer.blocked_user"), tplSettingsOptions, nil)
@ -813,9 +813,9 @@ func SettingsPost(ctx *context.Context) {
return return
} }
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository) repoTransfer, err := repo_model.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
if models.IsErrNoPendingTransfer(err) { if repo_model.IsErrNoPendingTransfer(err) {
ctx.Flash.Error("repo.settings.transfer_abort_invalid") ctx.Flash.Error("repo.settings.transfer_abort_invalid")
ctx.Redirect(repo.Link() + "/settings") ctx.Redirect(repo.Link() + "/settings")
} else { } else {

View File

@ -14,7 +14,6 @@ import (
"path" "path"
"strings" "strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git" git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
@ -725,7 +724,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest
if ctx.Repo.Repository.Status == repo_model.RepositoryPendingTransfer { if ctx.Repo.Repository.Status == repo_model.RepositoryPendingTransfer {
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository) repoTransfer, err := repo_model.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
ctx.ServerError("GetPendingRepositoryTransfer", err) ctx.ServerError("GetPendingRepositoryTransfer", err)
return cancel return cancel

View File

@ -7,7 +7,6 @@ import (
"context" "context"
"time" "time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/perm"
access_model "code.gitea.io/gitea/models/perm/access" access_model "code.gitea.io/gitea/models/perm/access"
@ -158,8 +157,8 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR
var transfer *api.RepoTransfer var transfer *api.RepoTransfer
if repo.Status == repo_model.RepositoryPendingTransfer { if repo.Status == repo_model.RepositoryPendingTransfer {
t, err := models.GetPendingRepositoryTransfer(ctx, repo) t, err := repo_model.GetPendingRepositoryTransfer(ctx, repo)
if err != nil && !models.IsErrNoPendingTransfer(err) { if err != nil && !repo_model.IsErrNoPendingTransfer(err) {
log.Warn("GetPendingRepositoryTransfer: %v", err) log.Warn("GetPendingRepositoryTransfer: %v", err)
} else { } else {
if err := t.LoadAttributes(ctx); err != nil { if err := t.LoadAttributes(ctx); err != nil {
@ -248,7 +247,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR
} }
// ToRepoTransfer convert a models.RepoTransfer to a structs.RepeTransfer // ToRepoTransfer convert a models.RepoTransfer to a structs.RepeTransfer
func ToRepoTransfer(ctx context.Context, t *models.RepoTransfer) *api.RepoTransfer { func ToRepoTransfer(ctx context.Context, t *repo_model.RepoTransfer) *api.RepoTransfer {
teams, _ := ToTeams(ctx, t.Teams, false) teams, _ := ToTeams(ctx, t.Teams, false)
return &api.RepoTransfer{ return &api.RepoTransfer{

View File

@ -285,7 +285,7 @@ func transferOwnership(ctx context.Context, doer *user_model.User, newOwnerName
wikiRenamed = true wikiRenamed = true
} }
if err := models.DeleteRepositoryTransfer(ctx, repo.ID); err != nil { if err := repo_model.DeleteRepositoryTransfer(ctx, repo.ID); err != nil {
return fmt.Errorf("deleteRepositoryTransfer: %w", err) return fmt.Errorf("deleteRepositoryTransfer: %w", err)
} }
repo.Status = repo_model.RepositoryReady repo.Status = repo_model.RepositoryReady
@ -388,7 +388,7 @@ func ChangeRepositoryName(ctx context.Context, doer *user_model.User, repo *repo
// StartRepositoryTransfer transfer a repo from one owner to a new one. // StartRepositoryTransfer transfer a repo from one owner to a new one.
// it make repository into pending transfer state, if doer can not create repo for new owner. // it make repository into pending transfer state, if doer can not create repo for new owner.
func StartRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository, teams []*organization.Team) error { func StartRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository, teams []*organization.Team) error {
if err := models.TestRepositoryReadyForTransfer(repo.Status); err != nil { if err := repo_model.TestRepositoryReadyForTransfer(repo.Status); err != nil {
return err return err
} }
@ -425,7 +425,7 @@ func StartRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.Use
// Make repo as pending for transfer // Make repo as pending for transfer
repo.Status = repo_model.RepositoryPendingTransfer repo.Status = repo_model.RepositoryPendingTransfer
if err := models.CreatePendingRepositoryTransfer(ctx, doer, newOwner, repo.ID, teams); err != nil { if err := repo_model.CreatePendingRepositoryTransfer(ctx, doer, newOwner, repo.ID, teams); err != nil {
return err return err
} }
@ -449,7 +449,7 @@ func CancelRepositoryTransfer(ctx context.Context, repo *repo_model.Repository)
return err return err
} }
if err := models.DeleteRepositoryTransfer(ctx, repo.ID); err != nil { if err := repo_model.DeleteRepositoryTransfer(ctx, repo.ID); err != nil {
return err return err
} }

View File

@ -7,7 +7,6 @@ import (
"sync" "sync"
"testing" "testing"
"code.gitea.io/gitea/models"
activities_model "code.gitea.io/gitea/models/activities" activities_model "code.gitea.io/gitea/models/activities"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/organization"
@ -86,23 +85,23 @@ func TestRepositoryTransfer(t *testing.T) {
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
transfer, err := models.GetPendingRepositoryTransfer(db.DefaultContext, repo) transfer, err := repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, transfer) assert.NotNil(t, transfer)
// Cancel transfer // Cancel transfer
assert.NoError(t, CancelRepositoryTransfer(db.DefaultContext, repo)) assert.NoError(t, CancelRepositoryTransfer(db.DefaultContext, repo))
transfer, err = models.GetPendingRepositoryTransfer(db.DefaultContext, repo) transfer, err = repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo)
assert.Error(t, err) assert.Error(t, err)
assert.Nil(t, transfer) assert.Nil(t, transfer)
assert.True(t, models.IsErrNoPendingTransfer(err)) assert.True(t, repo_model.IsErrNoPendingTransfer(err))
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.NoError(t, models.CreatePendingRepositoryTransfer(db.DefaultContext, doer, user2, repo.ID, nil)) assert.NoError(t, repo_model.CreatePendingRepositoryTransfer(db.DefaultContext, doer, user2, repo.ID, nil))
transfer, err = models.GetPendingRepositoryTransfer(db.DefaultContext, repo) transfer, err = repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo)
assert.Nil(t, err) assert.Nil(t, err)
assert.NoError(t, transfer.LoadAttributes(db.DefaultContext)) assert.NoError(t, transfer.LoadAttributes(db.DefaultContext))
assert.Equal(t, "user2", transfer.Recipient.Name) assert.Equal(t, "user2", transfer.Recipient.Name)
@ -110,12 +109,12 @@ func TestRepositoryTransfer(t *testing.T) {
org6 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) org6 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Only transfer can be started at any given time // Only transfer can be started at any given time
err = models.CreatePendingRepositoryTransfer(db.DefaultContext, doer, org6, repo.ID, nil) err = repo_model.CreatePendingRepositoryTransfer(db.DefaultContext, doer, org6, repo.ID, nil)
assert.Error(t, err) assert.Error(t, err)
assert.True(t, models.IsErrRepoTransferInProgress(err)) assert.True(t, repo_model.IsErrRepoTransferInProgress(err))
// Unknown user // Unknown user
err = models.CreatePendingRepositoryTransfer(db.DefaultContext, doer, &user_model.User{ID: 1000, LowerName: "user1000"}, repo.ID, nil) err = repo_model.CreatePendingRepositoryTransfer(db.DefaultContext, doer, &user_model.User{ID: 1000, LowerName: "user1000"}, repo.ID, nil)
assert.Error(t, err) assert.Error(t, err)
// Cancel transfer // Cancel transfer

View File

@ -6,7 +6,6 @@ package user
import ( import (
"context" "context"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
org_model "code.gitea.io/gitea/models/organization" org_model "code.gitea.io/gitea/models/organization"
@ -194,7 +193,7 @@ func unwatchRepos(ctx context.Context, watcher, repoOwner *user_model.User) erro
} }
func cancelRepositoryTransfers(ctx context.Context, sender, recipient *user_model.User) error { func cancelRepositoryTransfers(ctx context.Context, sender, recipient *user_model.User) error {
transfers, err := models.GetPendingRepositoryTransfers(ctx, &models.PendingRepositoryTransferOptions{ transfers, err := repo_model.GetPendingRepositoryTransfers(ctx, &repo_model.PendingRepositoryTransferOptions{
SenderID: sender.ID, SenderID: sender.ID,
RecipientID: recipient.ID, RecipientID: recipient.ID,
}) })

View File

@ -8,7 +8,6 @@ import (
"net/http" "net/http"
"testing" "testing"
"code.gitea.io/gitea/models"
auth_model "code.gitea.io/gitea/models/auth" auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
@ -42,7 +41,7 @@ func TestBlockUser(t *testing.T) {
} }
countRepositoryTransfers := func(t *testing.T, senderID, recipientID int64) int64 { countRepositoryTransfers := func(t *testing.T, senderID, recipientID int64) int64 {
transfers, err := models.GetPendingRepositoryTransfers(db.DefaultContext, &models.PendingRepositoryTransferOptions{ transfers, err := repo_model.GetPendingRepositoryTransfers(db.DefaultContext, &repo_model.PendingRepositoryTransferOptions{
SenderID: senderID, SenderID: senderID,
RecipientID: recipientID, RecipientID: recipientID,
}) })