1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-22 18:28:37 +00:00

Move RepoTransfer from models to models/repo sub package (#32506)

`RepoTransfer` now is at models, but if we want to move it into `repo`
model, it will depend on `Team`. So this PR also makes repo model depend
on org model to make it possible. Just refactor, no code change.

- [x] Move `DeleteOrganization` from `models/organization` to service
layer
- [x] Move `AccessibleTeamReposEnv` to `models/repo`
- [x] Move `RepoTransfer` from `models` to `models/repo`
- [x] Merge `getUserTeamIDs` and `GetUserTeamIDs`, Merge `GetUserTeams`
and `getUserTeams`.
- [x] Remove `Team`'s `Repos []*repo_model.Repository` to avoid dependency recycle.
This commit is contained in:
Lunny Xiao
2024-12-17 19:44:16 -08:00
committed by GitHub
parent b945742293
commit e4c4629465
30 changed files with 383 additions and 389 deletions

View File

@@ -14,7 +14,6 @@ import (
"path"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues"
@@ -709,7 +708,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest
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 {
ctx.ServerError("GetPendingRepositoryTransfer", err)
return cancel

View File

@@ -7,7 +7,6 @@ import (
"context"
"time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
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
if repo.Status == repo_model.RepositoryPendingTransfer {
t, err := models.GetPendingRepositoryTransfer(ctx, repo)
if err != nil && !models.IsErrNoPendingTransfer(err) {
t, err := repo_model.GetPendingRepositoryTransfer(ctx, repo)
if err != nil && !repo_model.IsErrNoPendingTransfer(err) {
log.Warn("GetPendingRepositoryTransfer: %v", err)
} else {
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
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)
return &api.RepoTransfer{

View File

@@ -8,16 +8,45 @@ import (
"fmt"
"code.gitea.io/gitea/models"
actions_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/db"
org_model "code.gitea.io/gitea/models/organization"
packages_model "code.gitea.io/gitea/models/packages"
repo_model "code.gitea.io/gitea/models/repo"
secret_model "code.gitea.io/gitea/models/secret"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/modules/util"
repo_service "code.gitea.io/gitea/services/repository"
)
// deleteOrganization deletes models associated to an organization.
func deleteOrganization(ctx context.Context, org *org_model.Organization) error {
if org.Type != user_model.UserTypeOrganization {
return fmt.Errorf("%s is a user not an organization", org.Name)
}
if err := db.DeleteBeans(ctx,
&org_model.Team{OrgID: org.ID},
&org_model.OrgUser{OrgID: org.ID},
&org_model.TeamUser{OrgID: org.ID},
&org_model.TeamUnit{OrgID: org.ID},
&org_model.TeamInvite{OrgID: org.ID},
&secret_model.Secret{OwnerID: org.ID},
&user_model.Blocking{BlockerID: org.ID},
&actions_model.ActionRunner{OwnerID: org.ID},
&actions_model.ActionRunnerToken{OwnerID: org.ID},
); err != nil {
return fmt.Errorf("DeleteBeans: %w", err)
}
if _, err := db.GetEngine(ctx).ID(org.ID).Delete(new(user_model.User)); err != nil {
return fmt.Errorf("Delete: %w", err)
}
return nil
}
// DeleteOrganization completely and permanently deletes everything of organization.
func DeleteOrganization(ctx context.Context, org *org_model.Organization, purge bool) error {
ctx, committer, err := db.TxContext(ctx)
@@ -48,7 +77,7 @@ func DeleteOrganization(ctx context.Context, org *org_model.Organization, purge
return models.ErrUserOwnPackages{UID: org.ID}
}
if err := org_model.DeleteOrganization(ctx, org); err != nil {
if err := deleteOrganization(ctx, org); err != nil {
return fmt.Errorf("DeleteOrganization: %w", err)
}

View File

@@ -141,11 +141,14 @@ func UpdateTeam(ctx context.Context, t *organization.Team, authChanged, includeA
// Update access for team members if needed.
if authChanged {
if err = t.LoadRepositories(ctx); err != nil {
return fmt.Errorf("LoadRepositories: %w", err)
repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{
TeamID: t.ID,
})
if err != nil {
return fmt.Errorf("GetTeamRepositories: %w", err)
}
for _, repo := range t.Repos {
for _, repo := range repos {
if err = access_model.RecalculateTeamAccesses(ctx, repo, 0); err != nil {
return fmt.Errorf("recalculateTeamAccesses: %w", err)
}
@@ -172,10 +175,6 @@ func DeleteTeam(ctx context.Context, t *organization.Team) error {
}
defer committer.Close()
if err := t.LoadRepositories(ctx); err != nil {
return err
}
if err := t.LoadMembers(ctx); err != nil {
return err
}
@@ -301,8 +300,11 @@ func AddTeamMember(ctx context.Context, team *organization.Team, user *user_mode
// FIXME: Update watch repos batchly
if setting.Service.AutoWatchNewRepos {
// Get team and its repositories.
if err := team.LoadRepositories(ctx); err != nil {
log.Error("team.LoadRepositories failed: %v", err)
repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{
TeamID: team.ID,
})
if err != nil {
log.Error("GetTeamRepositories failed: %v", err)
}
// FIXME: in the goroutine, it can't access the "ctx", it could only use db.DefaultContext at the moment
@@ -312,7 +314,7 @@ func AddTeamMember(ctx context.Context, team *organization.Team, user *user_mode
log.Error("watch repo failed: %v", err)
}
}
}(team.Repos)
}(repos)
}
return nil
@@ -332,7 +334,10 @@ func removeTeamMember(ctx context.Context, team *organization.Team, user *user_m
team.NumMembers--
if err := team.LoadRepositories(ctx); err != nil {
repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{
TeamID: team.ID,
})
if err != nil {
return err
}
@@ -350,7 +355,7 @@ func removeTeamMember(ctx context.Context, team *organization.Team, user *user_m
}
// Delete access to team repositories.
for _, repo := range team.Repos {
for _, repo := range repos {
if err := access_model.RecalculateUserAccess(ctx, repo, user.ID); err != nil {
return err
}

View File

@@ -189,9 +189,12 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) {
testTeamRepositories := func(teamID int64, repoIDs []int64) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, team.LoadRepositories(db.DefaultContext), "%s: GetRepositories", team.Name)
assert.Len(t, team.Repos, team.NumRepos, "%s: len repo", team.Name)
assert.Len(t, team.Repos, len(repoIDs), "%s: repo count", team.Name)
repos, err := repo_model.GetTeamRepositories(db.DefaultContext, &repo_model.SearchTeamRepoOptions{
TeamID: team.ID,
})
assert.NoError(t, err, "%s: GetTeamRepositories", team.Name)
assert.Len(t, repos, team.NumRepos, "%s: len repo", team.Name)
assert.Len(t, repos, len(repoIDs), "%s: repo count", team.Name)
for i, rid := range repoIDs {
if rid > 0 {
assert.True(t, repo_service.HasRepository(db.DefaultContext, team, rid), "%s: HasRepository(%d) %d", rid, i)
@@ -310,5 +313,5 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) {
assert.NoError(t, repo_service.DeleteRepositoryDirectly(db.DefaultContext, user, rid), "DeleteRepository %d", i)
}
}
assert.NoError(t, organization.DeleteOrganization(db.DefaultContext, org), "DeleteOrganization")
assert.NoError(t, DeleteOrganization(db.DefaultContext, org, false), "DeleteOrganization")
}

View File

@@ -60,7 +60,7 @@ func RemoveOrgUser(ctx context.Context, org *organization.Organization, user *us
}
// Delete all repository accesses and unwatch them.
env, err := organization.AccessibleReposEnv(ctx, org, user.ID)
env, err := repo_model.AccessibleReposEnv(ctx, org, user.ID)
if err != nil {
return fmt.Errorf("AccessibleReposEnv: %w", err)
}

View File

@@ -63,7 +63,7 @@ func addRepositoryToTeam(ctx context.Context, t *organization.Team, repo *repo_m
// If the team already has some repositories they will be left unchanged.
func AddAllRepositoriesToTeam(ctx context.Context, t *organization.Team) error {
return db.WithTx(ctx, func(ctx context.Context) error {
orgRepos, err := organization.GetOrgRepositories(ctx, t.OrgID)
orgRepos, err := repo_model.GetOrgRepositories(ctx, t.OrgID)
if err != nil {
return fmt.Errorf("get org repos: %w", err)
}
@@ -103,8 +103,15 @@ func RemoveAllRepositoriesFromTeam(ctx context.Context, t *organization.Team) (e
// Note: Shall not be called if team includes all repositories
func removeAllRepositoriesFromTeam(ctx context.Context, t *organization.Team) (err error) {
e := db.GetEngine(ctx)
repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{
TeamID: t.ID,
})
if err != nil {
return fmt.Errorf("GetTeamRepositories: %w", err)
}
// Delete all accesses.
for _, repo := range t.Repos {
for _, repo := range repos {
if err := access_model.RecalculateTeamAccesses(ctx, repo, t.ID); err != nil {
return err
}

View File

@@ -9,7 +9,6 @@ import (
"os"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/organization"
@@ -285,7 +284,7 @@ func transferOwnership(ctx context.Context, doer *user_model.User, newOwnerName
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)
}
repo.Status = repo_model.RepositoryReady
@@ -388,7 +387,7 @@ func ChangeRepositoryName(ctx context.Context, doer *user_model.User, repo *repo
// 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.
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
}
@@ -425,7 +424,7 @@ func StartRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.Use
// Make repo as pending for transfer
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
}
@@ -449,7 +448,7 @@ func CancelRepositoryTransfer(ctx context.Context, repo *repo_model.Repository)
return err
}
if err := models.DeleteRepositoryTransfer(ctx, repo.ID); err != nil {
if err := repo_model.DeleteRepositoryTransfer(ctx, repo.ID); err != nil {
return err
}

View File

@@ -7,7 +7,6 @@ import (
"sync"
"testing"
"code.gitea.io/gitea/models"
activities_model "code.gitea.io/gitea/models/activities"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
@@ -86,23 +85,23 @@ func TestRepositoryTransfer(t *testing.T) {
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{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.NotNil(t, transfer)
// Cancel transfer
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.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})
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.NoError(t, err)
assert.NoError(t, transfer.LoadAttributes(db.DefaultContext))
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})
// 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.True(t, models.IsErrRepoTransferInProgress(err))
assert.True(t, repo_model.IsErrRepoTransferInProgress(err))
// 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)
// Cancel transfer

View File

@@ -6,7 +6,6 @@ package user
import (
"context"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
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 {
transfers, err := models.GetPendingRepositoryTransfers(ctx, &models.PendingRepositoryTransferOptions{
transfers, err := repo_model.GetPendingRepositoryTransfers(ctx, &repo_model.PendingRepositoryTransferOptions{
SenderID: sender.ID,
RecipientID: recipient.ID,
})