Move some repository related code into sub package (#19711)

* Move some repository related code into sub package

* Move more repository functions out of models

* Fix lint

* Some performance optimization for webhooks and others

* some refactors

* Fix lint

* Fix

* Update modules/repository/delete.go

Co-authored-by: delvh <dev.lh@web.de>

* Fix test

* Merge

* Fix test

* Fix test

* Fix test

* Fix test

Co-authored-by: delvh <dev.lh@web.de>
This commit is contained in:
Lunny Xiao 2022-06-06 16:01:49 +08:00 committed by GitHub
parent ebeb6e7c71
commit 26095115f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
76 changed files with 1756 additions and 1674 deletions

View file

@ -1220,7 +1220,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
oid := strings.TrimPrefix(line[1:], lfs.MetaFileOidPrefix)
if len(oid) == 64 {
m := &models.LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}}
count, err := db.Count(m)
count, err := db.CountByBean(db.DefaultContext, m)
if err == nil && count > 0 {
curFile.IsBin = true

View file

@ -145,7 +145,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, vi
visited[user.ID] = true
// test if this user is allowed to see the issue/pull
if !models.CheckRepoUnitUser(ctx.Issue.Repo, user, checkUnit) {
if !models.CheckRepoUnitUser(ctx, ctx.Issue.Repo, user, checkUnit) {
continue
}

View file

@ -10,7 +10,6 @@ import (
"strings"
"time"
"code.gitea.io/gitea/models"
admin_model "code.gitea.io/gitea/models/admin"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
@ -301,7 +300,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
gitRepo.Close()
log.Trace("SyncMirrors [repo: %-v]: updating size of repository", m.Repo)
if err := models.UpdateRepoSize(ctx, m.Repo); err != nil {
if err := repo_module.UpdateRepoSize(ctx, m.Repo); err != nil {
log.Error("SyncMirrors [repo: %-v]: failed to update size for mirror repository: %v", m.Repo, err)
}

View file

@ -73,7 +73,7 @@ func AdoptRepository(doer, u *user_model.User, opts models.CreateRepoOptions) (*
if err := adoptRepository(ctx, repoPath, doer, repo, opts); err != nil {
return fmt.Errorf("createDelegateHooks: %v", err)
}
if err := models.CheckDaemonExportOK(ctx, repo); err != nil {
if err := repo_module.CheckDaemonExportOK(ctx, repo); err != nil {
return fmt.Errorf("checkDaemonExportOK: %v", err)
}
@ -182,7 +182,7 @@ func adoptRepository(ctx context.Context, repoPath string, u *user_model.User, r
}
}
if err = models.UpdateRepositoryCtx(ctx, repo, false); err != nil {
if err = repo_module.UpdateRepository(ctx, repo, false); err != nil {
return fmt.Errorf("updateRepository: %v", err)
}
@ -246,7 +246,7 @@ func checkUnadoptedRepositories(userName string, repoNamesToCheck []string, unad
}
return err
}
repos, _, err := models.GetUserRepositories(&models.SearchRepoOptions{
repos, _, err := repo_model.GetUserRepositories(&repo_model.SearchRepoOptions{
Actor: ctxUser,
Private: true,
ListOptions: db.ListOptions{

View file

@ -17,6 +17,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/util"
"xorm.io/builder"
@ -89,7 +90,7 @@ func GitGcRepos(ctx context.Context, timeout time.Duration, args ...string) erro
}
// Now update the size of the repository
if err := models.UpdateRepoSize(ctx, repo); err != nil {
if err := repo_module.UpdateRepoSize(ctx, repo); err != nil {
log.Error("Updating size as part of garbage collection failed for %v. Stdout: %s\nError: %v", repo, stdout, err)
desc := fmt.Sprintf("Updating size as part of garbage collection failed for %s. Stdout: %s\nError: %v", repo.RepoPath(), stdout, err)
if err = admin_model.CreateRepositoryNotice(desc); err != nil {

View file

@ -96,7 +96,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
return err
}
if err = models.IncrementRepoForkNum(txCtx, opts.BaseRepo.ID); err != nil {
if err = repo_model.IncrementRepoForkNum(txCtx, opts.BaseRepo.ID); err != nil {
return err
}
@ -116,7 +116,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
return fmt.Errorf("git clone: %v", err)
}
if err := models.CheckDaemonExportOK(txCtx, repo); err != nil {
if err := repo_module.CheckDaemonExportOK(txCtx, repo); err != nil {
return fmt.Errorf("checkDaemonExportOK: %v", err)
}
@ -139,7 +139,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
}
// even if below operations failed, it could be ignored. And they will be retried
if err := models.UpdateRepoSize(ctx, repo); err != nil {
if err := repo_module.UpdateRepoSize(ctx, repo); err != nil {
log.Error("Failed to update size for repository: %v", err)
}
if err := repo_model.CopyLanguageStat(opts.BaseRepo, repo); err != nil {
@ -173,7 +173,7 @@ func ConvertForkToNormalRepository(repo *repo_model.Repository) error {
return nil
}
if err := models.DecrementRepoForkNum(ctx, repo.ForkID); err != nil {
if err := repo_model.DecrementRepoForkNum(ctx, repo.ForkID); err != nil {
log.Error("Unable to decrement repo fork num for old root repo %d of repository %-v whilst converting from fork. Error: %v", repo.ForkID, repo, err)
return err
}
@ -181,7 +181,7 @@ func ConvertForkToNormalRepository(repo *repo_model.Repository) error {
repo.IsFork = false
repo.ForkID = 0
if err := models.UpdateRepositoryCtx(ctx, repo, false); err != nil {
if err := repo_module.UpdateRepository(ctx, repo, false); err != nil {
log.Error("Unable to update repository %-v whilst converting from fork. Error: %v", repo, err)
return err
}

View file

@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
@ -84,3 +85,29 @@ func GenerateGitHooks(ctx context.Context, templateRepo, generateRepo *repo_mode
}
return nil
}
// GenerateWebhooks generates webhooks from a template repository
func GenerateWebhooks(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error {
templateWebhooks, err := webhook.ListWebhooksByOpts(ctx, &webhook.ListWebhookOptions{RepoID: templateRepo.ID})
if err != nil {
return err
}
ws := make([]*webhook.Webhook, 0, len(templateWebhooks))
for _, templateWebhook := range templateWebhooks {
ws = append(ws, &webhook.Webhook{
RepoID: generateRepo.ID,
URL: templateWebhook.URL,
HTTPMethod: templateWebhook.HTTPMethod,
ContentType: templateWebhook.ContentType,
Secret: templateWebhook.Secret,
HookEvent: templateWebhook.HookEvent,
IsActive: templateWebhook.IsActive,
Type: templateWebhook.Type,
OrgID: templateWebhook.OrgID,
Events: templateWebhook.Events,
Meta: templateWebhook.Meta,
})
}
return webhook.CreateWebhooks(ctx, ws)
}

View file

@ -95,7 +95,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
}
defer gitRepo.Close()
if err = models.UpdateRepoSize(ctx, repo); err != nil {
if err = repo_module.UpdateRepoSize(ctx, repo); err != nil {
log.Error("Failed to update size for repository: %v", err)
}

View file

@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/models/organization"
packages_model "code.gitea.io/gitea/models/packages"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification"
@ -85,3 +86,42 @@ func Init() error {
admin_model.RemoveAllWithNotice(db.DefaultContext, "Clean up temporary repositories", repo_module.LocalCopyPath())
return initPushQueue()
}
// UpdateRepository updates a repository
func UpdateRepository(repo *repo_model.Repository, visibilityChanged bool) (err error) {
ctx, committer, err := db.TxContext()
if err != nil {
return err
}
defer committer.Close()
if err = repo_module.UpdateRepository(ctx, repo, visibilityChanged); err != nil {
return fmt.Errorf("updateRepository: %v", err)
}
return committer.Commit()
}
// LinkedRepository returns the linked repo if any
func LinkedRepository(a *repo_model.Attachment) (*repo_model.Repository, unit.Type, error) {
if a.IssueID != 0 {
iss, err := models.GetIssueByID(a.IssueID)
if err != nil {
return nil, unit.TypeIssues, err
}
repo, err := repo_model.GetRepositoryByID(iss.RepoID)
unitType := unit.TypeIssues
if iss.IsPull {
unitType = unit.TypePullRequests
}
return repo, unitType, err
} else if a.ReleaseID != 0 {
rel, err := models.GetReleaseByID(db.DefaultContext, a.ReleaseID)
if err != nil {
return nil, unit.TypeReleases, err
}
repo, err := repo_model.GetRepositoryByID(rel.RepoID)
return repo, unit.TypeReleases, err
}
return nil, -1, nil
}

View file

@ -0,0 +1,43 @@
// Copyright 2022 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 repository
import (
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
)
func TestLinkedRepository(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testCases := []struct {
name string
attachID int64
expectedRepo *repo_model.Repository
expectedUnitType unit.Type
}{
{"LinkedIssue", 1, &repo_model.Repository{ID: 1}, unit.TypeIssues},
{"LinkedComment", 3, &repo_model.Repository{ID: 1}, unit.TypePullRequests},
{"LinkedRelease", 9, &repo_model.Repository{ID: 1}, unit.TypeReleases},
{"Notlinked", 10, nil, -1},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
attach, err := repo_model.GetAttachmentByID(db.DefaultContext, tc.attachID)
assert.NoError(t, err)
repo, unitType, err := LinkedRepository(attach)
assert.NoError(t, err)
if tc.expectedRepo != nil {
assert.Equal(t, tc.expectedRepo.ID, repo.ID)
}
assert.Equal(t, tc.expectedUnitType, unitType)
})
}
}

View file

@ -0,0 +1,24 @@
// Copyright 2022 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 repository
import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
)
// GetReviewerTeams get all teams can be requested to review
func GetReviewerTeams(repo *repo_model.Repository) ([]*organization.Team, error) {
if err := repo.GetOwner(db.DefaultContext); err != nil {
return nil, err
}
if !repo.Owner.IsOrganization() {
return nil, nil
}
return organization.GetTeamsWithAccessToRepo(db.DefaultContext, repo.OwnerID, repo.ID, perm.AccessModeRead)
}

View file

@ -0,0 +1,28 @@
// Copyright 2022 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 repository
import (
"testing"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
)
func TestRepoGetReviewerTeams(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
teams, err := GetReviewerTeams(repo2)
assert.NoError(t, err)
assert.Empty(t, teams)
repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
teams, err = GetReviewerTeams(repo3)
assert.NoError(t, err)
assert.Len(t, teams, 2)
}

View file

@ -16,8 +16,27 @@ import (
repo_module "code.gitea.io/gitea/modules/repository"
)
// GenerateIssueLabels generates issue labels from a template repository
func GenerateIssueLabels(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error {
templateLabels, err := models.GetLabelsByRepoID(ctx, templateRepo.ID, "", db.ListOptions{})
if err != nil {
return err
}
newLabels := make([]*models.Label, 0, len(templateLabels))
for _, templateLabel := range templateLabels {
newLabels = append(newLabels, &models.Label{
RepoID: generateRepo.ID,
Name: templateLabel.Name,
Description: templateLabel.Description,
Color: templateLabel.Color,
})
}
return db.Insert(ctx, newLabels)
}
// GenerateRepository generates a repository from a template
func GenerateRepository(doer, owner *user_model.User, templateRepo *repo_model.Repository, opts models.GenerateRepoOptions) (_ *repo_model.Repository, err error) {
func GenerateRepository(doer, owner *user_model.User, templateRepo *repo_model.Repository, opts repo_module.GenerateRepoOptions) (_ *repo_model.Repository, err error) {
if !doer.IsAdmin && !owner.CanCreateRepo() {
return nil, repo_model.ErrReachLimitOfRepo{
Limit: owner.MaxRepoCreation,
@ -54,7 +73,7 @@ func GenerateRepository(doer, owner *user_model.User, templateRepo *repo_model.R
// Webhooks
if opts.Webhooks {
if err = models.GenerateWebhooks(ctx, templateRepo, generateRepo); err != nil {
if err = GenerateWebhooks(ctx, templateRepo, generateRepo); err != nil {
return err
}
}
@ -68,7 +87,7 @@ func GenerateRepository(doer, owner *user_model.User, templateRepo *repo_model.R
// Issue Labels
if opts.IssueLabels {
if err = models.GenerateIssueLabels(ctx, templateRepo, generateRepo); err != nil {
if err = GenerateIssueLabels(ctx, templateRepo, generateRepo); err != nil {
return err
}
}