1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo.git synced 2025-08-05 18:05:19 +02:00

Move repository model into models/repo (#17933)

* Some refactors related repository model

* Move more methods out of repository

* Move repository into models/repo

* Fix test

* Fix test

* some improvements

* Remove unnecessary function
This commit is contained in:
Lunny Xiao 2021-12-10 09:27:50 +08:00 committed by GitHub
parent fb8166c6c6
commit 719bddcd76
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
301 changed files with 3193 additions and 2919 deletions

View file

@ -6,10 +6,12 @@
package models
import (
"context"
"fmt"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
)
@ -27,7 +29,7 @@ func init() {
db.RegisterModel(new(Access))
}
func accessLevel(e db.Engine, user *user_model.User, repo *Repository) (perm.AccessMode, error) {
func accessLevel(e db.Engine, user *user_model.User, repo *repo_model.Repository) (perm.AccessMode, error) {
mode := perm.AccessModeNone
var userID int64
restricted := false
@ -81,7 +83,7 @@ func updateUserAccess(accessMap map[int64]*userAccess, user *user_model.User, mo
}
// FIXME: do cross-comparison so reduce deletions and additions to the minimum?
func (repo *Repository) refreshAccesses(e db.Engine, accessMap map[int64]*userAccess) (err error) {
func refreshAccesses(e db.Engine, repo *repo_model.Repository, accessMap map[int64]*userAccess) (err error) {
minMode := perm.AccessModeRead
if !repo.IsPrivate {
minMode = perm.AccessModeWrite
@ -115,8 +117,8 @@ func (repo *Repository) refreshAccesses(e db.Engine, accessMap map[int64]*userAc
}
// refreshCollaboratorAccesses retrieves repository collaborations with their access modes.
func (repo *Repository) refreshCollaboratorAccesses(e db.Engine, accessMap map[int64]*userAccess) error {
collaborators, err := repo.getCollaborators(e, db.ListOptions{})
func refreshCollaboratorAccesses(e db.Engine, repoID int64, accessMap map[int64]*userAccess) error {
collaborators, err := getCollaborators(e, repoID, db.ListOptions{})
if err != nil {
return fmt.Errorf("getCollaborations: %v", err)
}
@ -132,16 +134,18 @@ func (repo *Repository) refreshCollaboratorAccesses(e db.Engine, accessMap map[i
// recalculateTeamAccesses recalculates new accesses for teams of an organization
// except the team whose ID is given. It is used to assign a team ID when
// remove repository from that team.
func (repo *Repository) recalculateTeamAccesses(e db.Engine, ignTeamID int64) (err error) {
func recalculateTeamAccesses(ctx context.Context, repo *repo_model.Repository, ignTeamID int64) (err error) {
accessMap := make(map[int64]*userAccess, 20)
if err = repo.getOwner(e); err != nil {
if err = repo.GetOwner(ctx); err != nil {
return err
} else if !repo.Owner.IsOrganization() {
return fmt.Errorf("owner is not an organization: %d", repo.OwnerID)
}
if err = repo.refreshCollaboratorAccesses(e, accessMap); err != nil {
e := db.GetEngine(ctx)
if err = refreshCollaboratorAccesses(e, repo.ID, accessMap); err != nil {
return fmt.Errorf("refreshCollaboratorAccesses: %v", err)
}
@ -171,26 +175,27 @@ func (repo *Repository) recalculateTeamAccesses(e db.Engine, ignTeamID int64) (e
}
}
return repo.refreshAccesses(e, accessMap)
return refreshAccesses(e, repo, accessMap)
}
// recalculateUserAccess recalculates new access for a single user
// Usable if we know access only affected one user
func (repo *Repository) recalculateUserAccess(e db.Engine, uid int64) (err error) {
func recalculateUserAccess(ctx context.Context, repo *repo_model.Repository, uid int64) (err error) {
minMode := perm.AccessModeRead
if !repo.IsPrivate {
minMode = perm.AccessModeWrite
}
accessMode := perm.AccessModeNone
collaborator, err := repo.getCollaboration(e, uid)
e := db.GetEngine(ctx)
collaborator, err := getCollaboration(e, repo.ID, uid)
if err != nil {
return err
} else if collaborator != nil {
accessMode = collaborator.Mode
}
if err = repo.getOwner(e); err != nil {
if err = repo.GetOwner(ctx); err != nil {
return err
} else if repo.Owner.IsOrganization() {
var teams []Team
@ -223,19 +228,20 @@ func (repo *Repository) recalculateUserAccess(e db.Engine, uid int64) (err error
return nil
}
func (repo *Repository) recalculateAccesses(e db.Engine) error {
func recalculateAccesses(ctx context.Context, repo *repo_model.Repository) error {
if repo.Owner.IsOrganization() {
return repo.recalculateTeamAccesses(e, 0)
return recalculateTeamAccesses(ctx, repo, 0)
}
e := db.GetEngine(ctx)
accessMap := make(map[int64]*userAccess, 20)
if err := repo.refreshCollaboratorAccesses(e, accessMap); err != nil {
if err := refreshCollaboratorAccesses(e, repo.ID, accessMap); err != nil {
return fmt.Errorf("refreshCollaboratorAccesses: %v", err)
}
return repo.refreshAccesses(e, accessMap)
return refreshAccesses(e, repo, accessMap)
}
// RecalculateAccesses recalculates all accesses for repository.
func (repo *Repository) RecalculateAccesses() error {
return repo.recalculateAccesses(db.GetEngine(db.DefaultContext))
func RecalculateAccesses(repo *repo_model.Repository) error {
return recalculateAccesses(db.DefaultContext, repo)
}

View file

@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@ -22,17 +23,17 @@ func TestAccessLevel(t *testing.T) {
user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29}).(*user_model.User)
// A public repository owned by User 2
repo1 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
assert.False(t, repo1.IsPrivate)
// A private repository owned by Org 3
repo3 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository)
repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
assert.True(t, repo3.IsPrivate)
// Another public repository
repo4 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 4}).(*Repository)
repo4 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository)
assert.False(t, repo4.IsPrivate)
// org. owned private repo
repo24 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 24}).(*Repository)
repo24 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24}).(*repo_model.Repository)
level, err := AccessLevel(user2, repo1)
assert.NoError(t, err)
@ -72,10 +73,10 @@ func TestHasAccess(t *testing.T) {
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
// A public repository owned by User 2
repo1 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
assert.False(t, repo1.IsPrivate)
// A private repository owned by Org 3
repo2 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository)
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
assert.True(t, repo2.IsPrivate)
has, err := HasAccess(user1.ID, repo1)
@ -95,12 +96,12 @@ func TestHasAccess(t *testing.T) {
func TestRepository_RecalculateAccesses(t *testing.T) {
// test with organization repo
assert.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository)
assert.NoError(t, repo1.GetOwner())
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
assert.NoError(t, repo1.GetOwner(db.DefaultContext))
_, err := db.GetEngine(db.DefaultContext).Delete(&Collaboration{UserID: 2, RepoID: 3})
assert.NoError(t, err)
assert.NoError(t, repo1.RecalculateAccesses())
assert.NoError(t, RecalculateAccesses(repo1))
access := &Access{UserID: 2, RepoID: 3}
has, err := db.GetEngine(db.DefaultContext).Get(access)
@ -112,12 +113,12 @@ func TestRepository_RecalculateAccesses(t *testing.T) {
func TestRepository_RecalculateAccesses2(t *testing.T) {
// test with non-organization repo
assert.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 4}).(*Repository)
assert.NoError(t, repo1.GetOwner())
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository)
assert.NoError(t, repo1.GetOwner(db.DefaultContext))
_, err := db.GetEngine(db.DefaultContext).Delete(&Collaboration{UserID: 4, RepoID: 4})
assert.NoError(t, err)
assert.NoError(t, repo1.RecalculateAccesses())
assert.NoError(t, RecalculateAccesses(repo1))
has, err := db.GetEngine(db.DefaultContext).Get(&Access{UserID: 4, RepoID: 4})
assert.NoError(t, err)

View file

@ -6,6 +6,7 @@
package models
import (
"context"
"fmt"
"net/url"
"path"
@ -14,6 +15,7 @@ import (
"time"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git"
@ -64,13 +66,13 @@ type Action struct {
ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"INDEX"` // Receiver user id.
OpType ActionType
ActUserID int64 `xorm:"INDEX"` // Action user id.
ActUser *user_model.User `xorm:"-"`
RepoID int64 `xorm:"INDEX"`
Repo *Repository `xorm:"-"`
CommentID int64 `xorm:"INDEX"`
Comment *Comment `xorm:"-"`
IsDeleted bool `xorm:"INDEX NOT NULL DEFAULT false"`
ActUserID int64 `xorm:"INDEX"` // Action user id.
ActUser *user_model.User `xorm:"-"`
RepoID int64 `xorm:"INDEX"`
Repo *repo_model.Repository `xorm:"-"`
CommentID int64 `xorm:"INDEX"`
Comment *Comment `xorm:"-"`
IsDeleted bool `xorm:"INDEX NOT NULL DEFAULT false"`
RefName string
IsPrivate bool `xorm:"INDEX NOT NULL DEFAULT false"`
Content string `xorm:"TEXT"`
@ -107,9 +109,9 @@ func (a *Action) loadRepo() {
return
}
var err error
a.Repo, err = GetRepositoryByID(a.RepoID)
a.Repo, err = repo_model.GetRepositoryByID(a.RepoID)
if err != nil {
log.Error("GetRepositoryByID(%d): %v", a.RepoID, err)
log.Error("repo_model.GetRepositoryByID(%d): %v", a.RepoID, err)
}
}
@ -191,16 +193,16 @@ func (a *Action) GetRepoLink() string {
return path.Join(setting.AppSubURL, "/", url.PathEscape(a.GetRepoUserName()), url.PathEscape(a.GetRepoName()))
}
// GetRepositoryFromMatch returns a *Repository from a username and repo strings
func GetRepositoryFromMatch(ownerName, repoName string) (*Repository, error) {
// GetRepositoryFromMatch returns a *repo_model.Repository from a username and repo strings
func GetRepositoryFromMatch(ownerName, repoName string) (*repo_model.Repository, error) {
var err error
refRepo, err := GetRepositoryByOwnerAndName(ownerName, repoName)
refRepo, err := repo_model.GetRepositoryByOwnerAndName(ownerName, repoName)
if err != nil {
if IsErrRepoNotExist(err) {
if repo_model.IsErrRepoNotExist(err) {
log.Warn("Repository referenced in commit but does not exist: %v", err)
return nil, err
}
log.Error("GetRepositoryByOwnerAndName: %v", err)
log.Error("repo_model.GetRepositoryByOwnerAndName: %v", err)
return nil, err
}
return refRepo, nil
@ -208,13 +210,14 @@ func GetRepositoryFromMatch(ownerName, repoName string) (*Repository, error) {
// GetCommentLink returns link to action comment.
func (a *Action) GetCommentLink() string {
return a.getCommentLink(db.GetEngine(db.DefaultContext))
return a.getCommentLink(db.DefaultContext)
}
func (a *Action) getCommentLink(e db.Engine) string {
func (a *Action) getCommentLink(ctx context.Context) string {
if a == nil {
return "#"
}
e := db.GetEngine(ctx)
if a.Comment == nil && a.CommentID != 0 {
a.Comment, _ = getCommentByID(e, a.CommentID)
}
@ -236,7 +239,7 @@ func (a *Action) getCommentLink(e db.Engine) string {
return "#"
}
if err = issue.loadRepo(e); err != nil {
if err = issue.loadRepo(ctx); err != nil {
return "#"
}

View file

@ -8,6 +8,7 @@ import (
"fmt"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
)
@ -59,13 +60,13 @@ func (actions ActionList) getRepoIDs() []int64 {
return keysInt64(repoIDs)
}
func (actions ActionList) loadRepositories(e db.Engine) ([]*Repository, error) {
func (actions ActionList) loadRepositories(e db.Engine) ([]*repo_model.Repository, error) {
if len(actions) == 0 {
return nil, nil
}
repoIDs := actions.getRepoIDs()
repoMaps := make(map[int64]*Repository, len(repoIDs))
repoMaps := make(map[int64]*repo_model.Repository, len(repoIDs))
err := e.
In("id", repoIDs).
Find(&repoMaps)
@ -80,7 +81,7 @@ func (actions ActionList) loadRepositories(e db.Engine) ([]*Repository, error) {
}
// LoadRepositories loads actions' all repositories
func (actions ActionList) LoadRepositories() ([]*Repository, error) {
func (actions ActionList) LoadRepositories() ([]*repo_model.Repository, error) {
return actions.loadRepositories(db.GetEngine(db.DefaultContext))
}

View file

@ -8,6 +8,7 @@ import (
"path"
"testing"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
@ -17,7 +18,7 @@ import (
func TestAction_GetRepoPath(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}).(*repo_model.Repository)
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
action := &Action{RepoID: repo.ID}
assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath())
@ -25,7 +26,7 @@ func TestAction_GetRepoPath(t *testing.T) {
func TestAction_GetRepoLink(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}).(*repo_model.Repository)
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
action := &Action{RepoID: repo.ID}
setting.AppSubURL = "/suburl"

View file

@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
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/base"
@ -74,8 +75,8 @@ func (protectBranch *ProtectedBranch) CanUserPush(userID int64) bool {
if user, err := user_model.GetUserByID(userID); err != nil {
log.Error("GetUserByID: %v", err)
return false
} else if repo, err := GetRepositoryByID(protectBranch.RepoID); err != nil {
log.Error("GetRepositoryByID: %v", err)
} else if repo, err := repo_model.GetRepositoryByID(protectBranch.RepoID); err != nil {
log.Error("repo_model.GetRepositoryByID: %v", err)
return false
} else if writeAccess, err := HasAccessUnit(user, repo, unit.TypeCode, perm.AccessModeWrite); err != nil {
log.Error("HasAccessUnit: %v", err)
@ -102,7 +103,7 @@ func (protectBranch *ProtectedBranch) CanUserPush(userID int64) bool {
}
// IsUserMergeWhitelisted checks if some user is whitelisted to merge to this branch
func (protectBranch *ProtectedBranch) IsUserMergeWhitelisted(userID int64, permissionInRepo Permission) bool {
func IsUserMergeWhitelisted(protectBranch *ProtectedBranch, userID int64, permissionInRepo Permission) bool {
if !protectBranch.EnableMergeWhitelist {
// Then we need to fall back on whether the user has write permission
return permissionInRepo.CanWrite(unit.TypeCode)
@ -125,19 +126,19 @@ func (protectBranch *ProtectedBranch) IsUserMergeWhitelisted(userID int64, permi
}
// IsUserOfficialReviewer check if user is official reviewer for the branch (counts towards required approvals)
func (protectBranch *ProtectedBranch) IsUserOfficialReviewer(user *user_model.User) (bool, error) {
return protectBranch.isUserOfficialReviewer(db.GetEngine(db.DefaultContext), user)
func IsUserOfficialReviewer(protectBranch *ProtectedBranch, user *user_model.User) (bool, error) {
return isUserOfficialReviewer(db.DefaultContext, protectBranch, user)
}
func (protectBranch *ProtectedBranch) isUserOfficialReviewer(e db.Engine, user *user_model.User) (bool, error) {
repo, err := getRepositoryByID(e, protectBranch.RepoID)
func isUserOfficialReviewer(ctx context.Context, protectBranch *ProtectedBranch, user *user_model.User) (bool, error) {
repo, err := repo_model.GetRepositoryByIDCtx(ctx, protectBranch.RepoID)
if err != nil {
return false, err
}
if !protectBranch.EnableApprovalsWhitelist {
// Anyone with write access is considered official reviewer
writeAccess, err := hasAccessUnit(e, user, repo, unit.TypeCode, perm.AccessModeWrite)
writeAccess, err := hasAccessUnit(ctx, user, repo, unit.TypeCode, perm.AccessModeWrite)
if err != nil {
return false, err
}
@ -148,7 +149,7 @@ func (protectBranch *ProtectedBranch) isUserOfficialReviewer(e db.Engine, user *
return true, nil
}
inTeam, err := isUserInTeams(e, user.ID, protectBranch.ApprovalsWhitelistTeamIDs)
inTeam, err := isUserInTeams(db.GetEngine(ctx), user.ID, protectBranch.ApprovalsWhitelistTeamIDs)
if err != nil {
return false, err
}
@ -335,8 +336,8 @@ type WhitelistOptions struct {
// If ID is 0, it creates a new record. Otherwise, updates existing record.
// This function also performs check if whitelist user and team's IDs have been changed
// to avoid unnecessary whitelist delete and regenerate.
func UpdateProtectBranch(repo *Repository, protectBranch *ProtectedBranch, opts WhitelistOptions) (err error) {
if err = repo.GetOwner(); err != nil {
func UpdateProtectBranch(repo *repo_model.Repository, protectBranch *ProtectedBranch, opts WhitelistOptions) (err error) {
if err = repo.GetOwner(db.DefaultContext); err != nil {
return fmt.Errorf("GetOwner: %v", err)
}
@ -393,20 +394,15 @@ func UpdateProtectBranch(repo *Repository, protectBranch *ProtectedBranch, opts
}
// GetProtectedBranches get all protected branches
func (repo *Repository) GetProtectedBranches() ([]*ProtectedBranch, error) {
func GetProtectedBranches(repoID int64) ([]*ProtectedBranch, error) {
protectedBranches := make([]*ProtectedBranch, 0)
return protectedBranches, db.GetEngine(db.DefaultContext).Find(&protectedBranches, &ProtectedBranch{RepoID: repo.ID})
}
// GetBranchProtection get the branch protection of a branch
func (repo *Repository) GetBranchProtection(branchName string) (*ProtectedBranch, error) {
return GetProtectedBranchBy(repo.ID, branchName)
return protectedBranches, db.GetEngine(db.DefaultContext).Find(&protectedBranches, &ProtectedBranch{RepoID: repoID})
}
// IsProtectedBranch checks if branch is protected
func (repo *Repository) IsProtectedBranch(branchName string) (bool, error) {
func IsProtectedBranch(repoID int64, branchName string) (bool, error) {
protectedBranch := &ProtectedBranch{
RepoID: repo.ID,
RepoID: repoID,
BranchName: branchName,
}
@ -419,7 +415,7 @@ func (repo *Repository) IsProtectedBranch(branchName string) (bool, error) {
// updateApprovalWhitelist checks whether the user whitelist changed and returns a whitelist with
// the users from newWhitelist which have explicit read or write access to the repo.
func updateApprovalWhitelist(repo *Repository, currentWhitelist, newWhitelist []int64) (whitelist []int64, err error) {
func updateApprovalWhitelist(repo *repo_model.Repository, currentWhitelist, newWhitelist []int64) (whitelist []int64, err error) {
hasUsersChanged := !util.IsSliceInt64Eq(currentWhitelist, newWhitelist)
if !hasUsersChanged {
return currentWhitelist, nil
@ -427,7 +423,7 @@ func updateApprovalWhitelist(repo *Repository, currentWhitelist, newWhitelist []
whitelist = make([]int64, 0, len(newWhitelist))
for _, userID := range newWhitelist {
if reader, err := repo.IsReader(userID); err != nil {
if reader, err := IsRepoReader(repo, userID); err != nil {
return nil, err
} else if !reader {
continue
@ -440,7 +436,7 @@ func updateApprovalWhitelist(repo *Repository, currentWhitelist, newWhitelist []
// updateUserWhitelist checks whether the user whitelist changed and returns a whitelist with
// the users from newWhitelist which have write access to the repo.
func updateUserWhitelist(repo *Repository, currentWhitelist, newWhitelist []int64) (whitelist []int64, err error) {
func updateUserWhitelist(repo *repo_model.Repository, currentWhitelist, newWhitelist []int64) (whitelist []int64, err error) {
hasUsersChanged := !util.IsSliceInt64Eq(currentWhitelist, newWhitelist)
if !hasUsersChanged {
return currentWhitelist, nil
@ -469,7 +465,7 @@ func updateUserWhitelist(repo *Repository, currentWhitelist, newWhitelist []int6
// updateTeamWhitelist checks whether the team whitelist changed and returns a whitelist with
// the teams from newWhitelist which have write access to the repo.
func updateTeamWhitelist(repo *Repository, currentWhitelist, newWhitelist []int64) (whitelist []int64, err error) {
func updateTeamWhitelist(repo *repo_model.Repository, currentWhitelist, newWhitelist []int64) (whitelist []int64, err error) {
hasTeamsChanged := !util.IsSliceInt64Eq(currentWhitelist, newWhitelist)
if !hasTeamsChanged {
return currentWhitelist, nil
@ -491,9 +487,9 @@ func updateTeamWhitelist(repo *Repository, currentWhitelist, newWhitelist []int6
}
// DeleteProtectedBranch removes ProtectedBranch relation between the user and repository.
func (repo *Repository) DeleteProtectedBranch(id int64) (err error) {
func DeleteProtectedBranch(repoID, id int64) (err error) {
protectedBranch := &ProtectedBranch{
RepoID: repo.ID,
RepoID: repoID,
ID: id,
}
@ -518,28 +514,28 @@ type DeletedBranch struct {
}
// AddDeletedBranch adds a deleted branch to the database
func (repo *Repository) AddDeletedBranch(branchName, commit string, deletedByID int64) error {
func AddDeletedBranch(repoID int64, branchName, commit string, deletedByID int64) error {
deletedBranch := &DeletedBranch{
RepoID: repo.ID,
RepoID: repoID,
Name: branchName,
Commit: commit,
DeletedByID: deletedByID,
}
_, err := db.GetEngine(db.DefaultContext).InsertOne(deletedBranch)
_, err := db.GetEngine(db.DefaultContext).Insert(deletedBranch)
return err
}
// GetDeletedBranches returns all the deleted branches
func (repo *Repository) GetDeletedBranches() ([]*DeletedBranch, error) {
func GetDeletedBranches(repoID int64) ([]*DeletedBranch, error) {
deletedBranches := make([]*DeletedBranch, 0)
return deletedBranches, db.GetEngine(db.DefaultContext).Where("repo_id = ?", repo.ID).Desc("deleted_unix").Find(&deletedBranches)
return deletedBranches, db.GetEngine(db.DefaultContext).Where("repo_id = ?", repoID).Desc("deleted_unix").Find(&deletedBranches)
}
// GetDeletedBranchByID get a deleted branch by its ID
func (repo *Repository) GetDeletedBranchByID(id int64) (*DeletedBranch, error) {
func GetDeletedBranchByID(repoID, id int64) (*DeletedBranch, error) {
deletedBranch := &DeletedBranch{}
has, err := db.GetEngine(db.DefaultContext).Where("repo_id = ?", repo.ID).And("id = ?", id).Get(deletedBranch)
has, err := db.GetEngine(db.DefaultContext).Where("repo_id = ?", repoID).And("id = ?", id).Get(deletedBranch)
if err != nil {
return nil, err
}
@ -549,10 +545,10 @@ func (repo *Repository) GetDeletedBranchByID(id int64) (*DeletedBranch, error) {
return deletedBranch, nil
}
// RemoveDeletedBranch removes a deleted branch from the database
func (repo *Repository) RemoveDeletedBranch(id int64) (err error) {
// RemoveDeletedBranchByID removes a deleted branch from the database
func RemoveDeletedBranchByID(repoID, id int64) (err error) {
deletedBranch := &DeletedBranch{
RepoID: repo.ID,
RepoID: repoID,
ID: id,
}
@ -575,8 +571,8 @@ func (deletedBranch *DeletedBranch) LoadUser() {
deletedBranch.DeletedBy = user
}
// RemoveDeletedBranch removes all deleted branches
func RemoveDeletedBranch(repoID int64, branch string) error {
// RemoveDeletedBranchByName removes all deleted branches
func RemoveDeletedBranchByName(repoID int64, branch string) error {
_, err := db.GetEngine(db.DefaultContext).Where("repo_id=? AND name=?", repoID, branch).Delete(new(DeletedBranch))
return err
}
@ -615,7 +611,7 @@ func FindRenamedBranch(repoID int64, from string) (branch *RenamedBranch, exist
}
// RenameBranch rename a branch
func (repo *Repository) RenameBranch(from, to string, gitAction func(isDefault bool) error) (err error) {
func RenameBranch(repo *repo_model.Repository, from, to string, gitAction func(isDefault bool) error) (err error) {
ctx, committer, err := db.TxContext()
if err != nil {
return err

View file

@ -7,6 +7,7 @@ package models
import (
"testing"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
@ -14,18 +15,18 @@ import (
func TestAddDeletedBranch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
firstBranch := unittest.AssertExistsAndLoadBean(t, &DeletedBranch{ID: 1}).(*DeletedBranch)
assert.Error(t, repo.AddDeletedBranch(firstBranch.Name, firstBranch.Commit, firstBranch.DeletedByID))
assert.NoError(t, repo.AddDeletedBranch("test", "5655464564554545466464656", int64(1)))
assert.Error(t, AddDeletedBranch(repo.ID, firstBranch.Name, firstBranch.Commit, firstBranch.DeletedByID))
assert.NoError(t, AddDeletedBranch(repo.ID, "test", "5655464564554545466464656", int64(1)))
}
func TestGetDeletedBranches(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
branches, err := repo.GetDeletedBranches()
branches, err := GetDeletedBranches(repo.ID)
assert.NoError(t, err)
assert.Len(t, branches, 2)
}
@ -58,20 +59,20 @@ func TestDeletedBranchLoadUser(t *testing.T) {
func TestRemoveDeletedBranch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
firstBranch := unittest.AssertExistsAndLoadBean(t, &DeletedBranch{ID: 1}).(*DeletedBranch)
err := repo.RemoveDeletedBranch(1)
err := RemoveDeletedBranchByID(repo.ID, 1)
assert.NoError(t, err)
unittest.AssertNotExistsBean(t, firstBranch)
unittest.AssertExistsAndLoadBean(t, &DeletedBranch{ID: 2})
}
func getDeletedBranch(t *testing.T, branch *DeletedBranch) *DeletedBranch {
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
deletedBranch, err := repo.GetDeletedBranchByID(branch.ID)
deletedBranch, err := GetDeletedBranchByID(repo.ID, branch.ID)
assert.NoError(t, err)
assert.Equal(t, branch.ID, deletedBranch.ID)
assert.Equal(t, branch.Name, deletedBranch.Name)
@ -95,7 +96,7 @@ func TestFindRenamedBranch(t *testing.T) {
func TestRenameBranch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
_isDefault := false
err := UpdateProtectBranch(repo1, &ProtectedBranch{
@ -104,13 +105,13 @@ func TestRenameBranch(t *testing.T) {
}, WhitelistOptions{})
assert.NoError(t, err)
assert.NoError(t, repo1.RenameBranch("master", "main", func(isDefault bool) error {
assert.NoError(t, RenameBranch(repo1, "master", "main", func(isDefault bool) error {
_isDefault = isDefault
return nil
}))
assert.Equal(t, true, _isDefault)
repo1 = unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo1 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
assert.Equal(t, "main", repo1.DefaultBranch)
pull := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) // merged
@ -136,9 +137,9 @@ func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) {
// Get deletedBranch with ID of 1 on repo with ID 2.
// This should return a nil branch as this deleted branch
// is actually on repo with ID 1.
repo2 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
deletedBranch, err := repo2.GetDeletedBranchByID(1)
deletedBranch, err := GetDeletedBranchByID(repo2.ID, 1)
// Expect no error, and the returned branch is nil.
assert.NoError(t, err)
@ -146,9 +147,9 @@ func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) {
// Now get the deletedBranch with ID of 1 on repo with ID 1.
// This should return the deletedBranch.
repo1 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
deletedBranch, err = repo1.GetDeletedBranchByID(1)
deletedBranch, err = GetDeletedBranchByID(repo1.ID, 1)
// Expect no error, and the returned branch to be not nil.
assert.NoError(t, err)

View file

@ -5,12 +5,13 @@
package models
import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
)
// ConvertFromGitCommit converts git commits into SignCommitWithStatuses
func ConvertFromGitCommit(commits []*git.Commit, repo *Repository) []*SignCommitWithStatuses {
func ConvertFromGitCommit(commits []*git.Commit, repo *repo_model.Repository) []*SignCommitWithStatuses {
return ParseCommitsWithStatus(
ParseCommitsWithSignature(
user_model.ValidateCommitsWithEmails(commits),

View file

@ -5,6 +5,7 @@
package models
import (
"context"
"crypto/sha1"
"fmt"
"net/url"
@ -12,6 +13,7 @@ import (
"time"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
@ -23,17 +25,17 @@ import (
// CommitStatus holds a single Status of a single Commit
type CommitStatus struct {
ID int64 `xorm:"pk autoincr"`
Index int64 `xorm:"INDEX UNIQUE(repo_sha_index)"`
RepoID int64 `xorm:"INDEX UNIQUE(repo_sha_index)"`
Repo *Repository `xorm:"-"`
State api.CommitStatusState `xorm:"VARCHAR(7) NOT NULL"`
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"`
TargetURL string `xorm:"TEXT"`
Description string `xorm:"TEXT"`
ContextHash string `xorm:"char(40) index"`
Context string `xorm:"TEXT"`
Creator *user_model.User `xorm:"-"`
ID int64 `xorm:"pk autoincr"`
Index int64 `xorm:"INDEX UNIQUE(repo_sha_index)"`
RepoID int64 `xorm:"INDEX UNIQUE(repo_sha_index)"`
Repo *repo_model.Repository `xorm:"-"`
State api.CommitStatusState `xorm:"VARCHAR(7) NOT NULL"`
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"`
TargetURL string `xorm:"TEXT"`
Description string `xorm:"TEXT"`
ContextHash string `xorm:"char(40) index"`
Context string `xorm:"TEXT"`
Creator *user_model.User `xorm:"-"`
CreatorID int64
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
@ -120,15 +122,15 @@ func getNextCommitStatusIndex(repoID int64, sha string) (int64, error) {
return curIdx, nil
}
func (status *CommitStatus) loadAttributes(e db.Engine) (err error) {
func (status *CommitStatus) loadAttributes(ctx context.Context) (err error) {
if status.Repo == nil {
status.Repo, err = getRepositoryByID(e, status.RepoID)
status.Repo, err = repo_model.GetRepositoryByIDCtx(ctx, status.RepoID)
if err != nil {
return fmt.Errorf("getRepositoryByID [%d]: %v", status.RepoID, err)
}
}
if status.Creator == nil && status.CreatorID > 0 {
status.Creator, err = user_model.GetUserByIDEngine(e, status.CreatorID)
status.Creator, err = user_model.GetUserByIDEngine(db.GetEngine(ctx), status.CreatorID)
if err != nil {
return fmt.Errorf("getUserByID [%d]: %v", status.CreatorID, err)
}
@ -138,7 +140,7 @@ func (status *CommitStatus) loadAttributes(e db.Engine) (err error) {
// APIURL returns the absolute APIURL to this commit-status.
func (status *CommitStatus) APIURL() string {
_ = status.loadAttributes(db.GetEngine(db.DefaultContext))
_ = status.loadAttributes(db.DefaultContext)
return status.Repo.APIURL() + "/statuses/" + url.PathEscape(status.SHA)
}
@ -170,7 +172,7 @@ type CommitStatusOptions struct {
}
// GetCommitStatuses returns all statuses for a given commit.
func GetCommitStatuses(repo *Repository, sha string, opts *CommitStatusOptions) ([]*CommitStatus, int64, error) {
func GetCommitStatuses(repo *repo_model.Repository, sha string, opts *CommitStatusOptions) ([]*CommitStatus, int64, error) {
if opts.Page <= 0 {
opts.Page = 1
}
@ -193,7 +195,7 @@ func GetCommitStatuses(repo *Repository, sha string, opts *CommitStatusOptions)
return statuses, maxResults, findSession.Find(&statuses)
}
func listCommitStatusesStatement(repo *Repository, sha string, opts *CommitStatusOptions) *xorm.Session {
func listCommitStatusesStatement(repo *repo_model.Repository, sha string, opts *CommitStatusOptions) *xorm.Session {
sess := db.GetEngine(db.DefaultContext).Where("repo_id = ?", repo.ID).And("sha = ?", sha)
switch opts.State {
case "pending", "success", "error", "failure", "warning":
@ -274,7 +276,7 @@ func FindRepoRecentCommitStatusContexts(repoID int64, before time.Duration) ([]s
// NewCommitStatusOptions holds options for creating a CommitStatus
type NewCommitStatusOptions struct {
Repo *Repository
Repo *repo_model.Repository
Creator *user_model.User
SHA string
CommitStatus *CommitStatus
@ -330,7 +332,7 @@ type SignCommitWithStatuses struct {
}
// ParseCommitsWithStatus checks commits latest statuses and calculates its worst status state
func ParseCommitsWithStatus(oldCommits []*SignCommit, repo *Repository) []*SignCommitWithStatuses {
func ParseCommitsWithStatus(oldCommits []*SignCommit, repo *repo_model.Repository) []*SignCommitWithStatuses {
newCommits := make([]*SignCommitWithStatuses, 0, len(oldCommits))
for _, c := range oldCommits {

View file

@ -8,6 +8,7 @@ import (
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/structs"
@ -17,7 +18,7 @@ import (
func TestGetCommitStatuses(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
sha1 := "1234123412341234123412341234123412341234"

View file

@ -7,6 +7,7 @@ package models
import (
admin_model "code.gitea.io/gitea/models/admin"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"xorm.io/builder"
@ -158,12 +159,12 @@ func DeleteOrphanedObjects(subject, refobject, joinCond string) error {
// CountNullArchivedRepository counts the number of repositories with is_archived is null
func CountNullArchivedRepository() (int64, error) {
return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Count(new(Repository))
return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Count(new(repo_model.Repository))
}
// FixNullArchivedRepository sets is_archived to false where it is null
func FixNullArchivedRepository() (int64, error) {
return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Cols("is_archived").NoAutoTime().Update(&Repository{
return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Cols("is_archived").NoAutoTime().Update(&repo_model.Repository{
IsArchived: false,
})
}

View file

@ -9,6 +9,7 @@ import (
"fmt"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
)
@ -548,32 +549,6 @@ func (err ErrLFSFileLocked) Error() string {
return fmt.Sprintf("File is lfs locked [repo: %d, locked by: %s, path: %s]", err.RepoID, err.UserName, err.Path)
}
// __________ .__ __
// \______ \ ____ ______ ____ _____|__|/ |_ ___________ ___.__.
// | _// __ \\____ \ / _ \/ ___/ \ __\/ _ \_ __ < | |
// | | \ ___/| |_> > <_> )___ \| || | ( <_> ) | \/\___ |
// |____|_ /\___ > __/ \____/____ >__||__| \____/|__| / ____|
// \/ \/|__| \/ \/
// ErrRepoNotExist represents a "RepoNotExist" kind of error.
type ErrRepoNotExist struct {
ID int64
UID int64
OwnerName string
Name string
}
// IsErrRepoNotExist checks if an error is a ErrRepoNotExist.
func IsErrRepoNotExist(err error) bool {
_, ok := err.(ErrRepoNotExist)
return ok
}
func (err ErrRepoNotExist) Error() string {
return fmt.Sprintf("repository does not exist [id: %d, uid: %d, owner_name: %s, name: %s]",
err.ID, err.UID, err.OwnerName, err.Name)
}
// ErrNoPendingRepoTransfer is an error type for repositories without a pending
// transfer request
type ErrNoPendingRepoTransfer struct {
@ -1283,7 +1258,7 @@ func (err ErrPullRequestHeadRepoMissing) Error() string {
// ErrInvalidMergeStyle represents an error if merging with disabled merge strategy
type ErrInvalidMergeStyle struct {
ID int64
Style MergeStyle
Style repo_model.MergeStyle
}
// IsErrInvalidMergeStyle checks if an error is a ErrInvalidMergeStyle.
@ -1299,7 +1274,7 @@ func (err ErrInvalidMergeStyle) Error() string {
// ErrMergeConflicts represents an error if merging fails with a conflict
type ErrMergeConflicts struct {
Style MergeStyle
Style repo_model.MergeStyle
StdOut string
StdErr string
Err error
@ -1317,7 +1292,7 @@ func (err ErrMergeConflicts) Error() string {
// ErrMergeUnrelatedHistories represents an error if merging fails due to unrelated histories
type ErrMergeUnrelatedHistories struct {
Style MergeStyle
Style repo_model.MergeStyle
StdOut string
StdErr string
Err error
@ -1335,7 +1310,7 @@ func (err ErrMergeUnrelatedHistories) Error() string {
// ErrRebaseConflicts represents an error if rebase fails with a conflict
type ErrRebaseConflicts struct {
Style MergeStyle
Style repo_model.MergeStyle
CommitSHA string
StdOut string
StdErr string

View file

@ -9,19 +9,20 @@ import (
"strings"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
)
// GetYamlFixturesAccess returns a string containing the contents
// for the access table, as recalculated using repo.RecalculateAccesses()
func GetYamlFixturesAccess() (string, error) {
repos := make([]*Repository, 0, 50)
repos := make([]*repo_model.Repository, 0, 50)
if err := db.GetEngine(db.DefaultContext).Find(&repos); err != nil {
return "", err
}
for _, repo := range repos {
repo.MustOwner()
if err := repo.RecalculateAccesses(); err != nil {
if err := RecalculateAccesses(repo); err != nil {
return "", err
}
}

View file

@ -10,6 +10,7 @@ import (
"strings"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
@ -69,7 +70,7 @@ const (
)
// ParseCommitsWithSignature checks if signaute of commits are corresponding to users gpg keys.
func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repository *Repository) []*SignCommit {
func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repository *repo_model.Repository) []*SignCommit {
newCommits := make([]*SignCommit, 0, len(oldCommits))
keyMap := map[string]bool{}
@ -447,7 +448,7 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *use
}
// CalculateTrustStatus will calculate the TrustStatus for a commit verification within a repository
func CalculateTrustStatus(verification *CommitVerification, repository *Repository, keyMap *map[string]bool) (err error) {
func CalculateTrustStatus(verification *CommitVerification, repository *repo_model.Repository, keyMap *map[string]bool) (err error) {
if !verification.Verified {
return
}
@ -458,7 +459,7 @@ func CalculateTrustStatus(verification *CommitVerification, repository *Reposito
// In the Committer trust model a signature is trusted if it matches the committer
// - it doesn't matter if they're a collaborator, the owner, Gitea or Github
// NB: This model is commit verification only
if trustModel == CommitterTrustModel {
if trustModel == repo_model.CommitterTrustModel {
// default to "unmatched"
verification.TrustStatus = "unmatched"
@ -479,9 +480,9 @@ func CalculateTrustStatus(verification *CommitVerification, repository *Reposito
if verification.SigningUser.ID == 0 {
// This commit is signed by the default key - but this key is not assigned to a user in the DB.
// However in the CollaboratorCommitterTrustModel we cannot mark this as trusted
// However in the repo_model.CollaboratorCommitterTrustModel we cannot mark this as trusted
// unless the default key matches the email of a non-user.
if trustModel == CollaboratorCommitterTrustModel && (verification.CommittingUser.ID != 0 ||
if trustModel == repo_model.CollaboratorCommitterTrustModel && (verification.CommittingUser.ID != 0 ||
verification.SigningUser.Email != verification.CommittingUser.Email) {
verification.TrustStatus = "untrusted"
}
@ -493,11 +494,11 @@ func CalculateTrustStatus(verification *CommitVerification, repository *Reposito
var has bool
isMember, has = (*keyMap)[verification.SigningKey.KeyID]
if !has {
isMember, err = repository.IsOwnerMemberCollaborator(verification.SigningUser.ID)
isMember, err = IsOwnerMemberCollaborator(repository, verification.SigningUser.ID)
(*keyMap)[verification.SigningKey.KeyID] = isMember
}
} else {
isMember, err = repository.IsOwnerMemberCollaborator(verification.SigningUser.ID)
isMember, err = IsOwnerMemberCollaborator(repository, verification.SigningUser.ID)
}
if !isMember {
@ -507,7 +508,7 @@ func CalculateTrustStatus(verification *CommitVerification, repository *Reposito
// This should be marked as questionable unless the signing user is a collaborator/team member etc.
verification.TrustStatus = "unmatched"
}
} else if trustModel == CollaboratorCommitterTrustModel && verification.CommittingUser.ID != verification.SigningUser.ID {
} else if trustModel == repo_model.CollaboratorCommitterTrustModel && verification.CommittingUser.ID != verification.SigningUser.ID {
// The committing user and the signing user are not the same and our trustmodel states that they must match
verification.TrustStatus = "unmatched"
}

View file

@ -5,10 +5,8 @@
package models
import (
"encoding/binary"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/json"
)
func keysInt64(m map[int64]struct{}) []int64 {
@ -19,8 +17,8 @@ func keysInt64(m map[int64]struct{}) []int64 {
return keys
}
func valuesRepository(m map[int64]*Repository) []*Repository {
values := make([]*Repository, 0, len(m))
func valuesRepository(m map[int64]*repo_model.Repository) []*repo_model.Repository {
values := make([]*repo_model.Repository, 0, len(m))
for _, v := range m {
values = append(values, v)
}
@ -34,32 +32,3 @@ func valuesUser(m map[int64]*user_model.User) []*user_model.User {
}
return values
}
// JSONUnmarshalHandleDoubleEncode - due to a bug in xorm (see https://gitea.com/xorm/xorm/pulls/1957) - it's
// possible that a Blob may be double encoded or gain an unwanted prefix of 0xff 0xfe.
func JSONUnmarshalHandleDoubleEncode(bs []byte, v interface{}) error {
err := json.Unmarshal(bs, v)
if err != nil {
ok := true
rs := []byte{}
temp := make([]byte, 2)
for _, rn := range string(bs) {
if rn > 0xffff {
ok = false
break
}
binary.LittleEndian.PutUint16(temp, uint16(rn))
rs = append(rs, temp...)
}
if ok {
if len(rs) > 1 && rs[0] == 0xff && rs[1] == 0xfe {
rs = rs[2:]
}
err = json.Unmarshal(rs, v)
}
}
if err != nil && len(bs) > 2 && bs[0] == 0xff && bs[1] == 0xfe {
err = json.Unmarshal(bs[2:], v)
}
return err
}

View file

@ -9,6 +9,7 @@ import (
"os"
"strings"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
)
@ -33,19 +34,19 @@ const (
// It is recommended to avoid using this unless you are pushing within a transaction
// or if you absolutely are sure that post-receive and pre-receive will do nothing
// We provide the full pushing-environment for other hook providers
func InternalPushingEnvironment(doer *user_model.User, repo *Repository) []string {
func InternalPushingEnvironment(doer *user_model.User, repo *repo_model.Repository) []string {
return append(PushingEnvironment(doer, repo),
EnvIsInternal+"=true",
)
}
// PushingEnvironment returns an os environment to allow hooks to work on push
func PushingEnvironment(doer *user_model.User, repo *Repository) []string {
func PushingEnvironment(doer *user_model.User, repo *repo_model.Repository) []string {
return FullPushingEnvironment(doer, doer, repo, repo.Name, 0)
}
// FullPushingEnvironment returns an os environment to allow hooks to work on push
func FullPushingEnvironment(author, committer *user_model.User, repo *Repository, repoName string, prID int64) []string {
func FullPushingEnvironment(author, committer *user_model.User, repo *repo_model.Repository, repoName string, prID int64) []string {
isWiki := "false"
if strings.HasSuffix(repoName, ".wiki") {
isWiki = "true"

View file

@ -33,12 +33,12 @@ import (
// Issue represents an issue or pull request of repository.
type Issue struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX UNIQUE(repo_index)"`
Repo *Repository `xorm:"-"`
Index int64 `xorm:"UNIQUE(repo_index)"` // Index in one repository.
PosterID int64 `xorm:"INDEX"`
Poster *user_model.User `xorm:"-"`
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX UNIQUE(repo_index)"`
Repo *repo_model.Repository `xorm:"-"`
Index int64 `xorm:"UNIQUE(repo_index)"` // Index in one repository.
PosterID int64 `xorm:"INDEX"`
Poster *user_model.User `xorm:"-"`
OriginalAuthor string
OriginalAuthorID int64 `xorm:"index"`
Title string `xorm:"name"`
@ -118,12 +118,12 @@ func (issue *Issue) IsOverdue() bool {
// LoadRepo loads issue's repository
func (issue *Issue) LoadRepo() error {
return issue.loadRepo(db.GetEngine(db.DefaultContext))
return issue.loadRepo(db.DefaultContext)
}
func (issue *Issue) loadRepo(e db.Engine) (err error) {
func (issue *Issue) loadRepo(ctx context.Context) (err error) {
if issue.Repo == nil {
issue.Repo, err = getRepositoryByID(e, issue.RepoID)
issue.Repo, err = repo_model.GetRepositoryByIDCtx(ctx, issue.RepoID)
if err != nil {
return fmt.Errorf("getRepositoryByID [%d]: %v", issue.RepoID, err)
}
@ -133,11 +133,11 @@ func (issue *Issue) loadRepo(e db.Engine) (err error) {
// IsTimetrackerEnabled returns true if the repo enables timetracking
func (issue *Issue) IsTimetrackerEnabled() bool {
return issue.isTimetrackerEnabled(db.GetEngine(db.DefaultContext))
return issue.isTimetrackerEnabled(db.DefaultContext)
}
func (issue *Issue) isTimetrackerEnabled(e db.Engine) bool {
if err := issue.loadRepo(e); err != nil {
func (issue *Issue) isTimetrackerEnabled(ctx context.Context) bool {
if err := issue.loadRepo(ctx); err != nil {
log.Error(fmt.Sprintf("loadRepo: %v", err))
return false
}
@ -233,17 +233,18 @@ func (issue *Issue) loadCommentsByType(e db.Engine, tp CommentType) (err error)
return err
}
func (issue *Issue) loadReactions(e db.Engine) (err error) {
func (issue *Issue) loadReactions(ctx context.Context) (err error) {
if issue.Reactions != nil {
return nil
}
e := db.GetEngine(ctx)
reactions, err := findReactions(e, FindReactionsOptions{
IssueID: issue.ID,
})
if err != nil {
return err
}
if err = issue.loadRepo(e); err != nil {
if err = issue.loadRepo(ctx); err != nil {
return err
}
// Load reaction user data
@ -279,7 +280,7 @@ func (issue *Issue) loadMilestone(e db.Engine) (err error) {
func (issue *Issue) loadAttributes(ctx context.Context) (err error) {
e := db.GetEngine(ctx)
if err = issue.loadRepo(e); err != nil {
if err = issue.loadRepo(ctx); err != nil {
return
}
@ -319,16 +320,16 @@ func (issue *Issue) loadAttributes(ctx context.Context) (err error) {
return err
}
if err = CommentList(issue.Comments).loadAttributes(e); err != nil {
if err = CommentList(issue.Comments).loadAttributes(ctx); err != nil {
return err
}
if issue.isTimetrackerEnabled(e) {
if issue.isTimetrackerEnabled(ctx) {
if err = issue.loadTotalTimes(e); err != nil {
return err
}
}
return issue.loadReactions(e)
return issue.loadReactions(ctx)
}
// LoadAttributes loads the attribute of this issue.
@ -478,13 +479,13 @@ func (issue *Issue) ClearLabels(doer *user_model.User) (err error) {
}
defer committer.Close()
if err := issue.loadRepo(db.GetEngine(ctx)); err != nil {
if err := issue.loadRepo(ctx); err != nil {
return err
} else if err = issue.loadPullRequest(db.GetEngine(ctx)); err != nil {
return err
}
perm, err := getUserRepoPermission(db.GetEngine(ctx), issue.Repo, doer)
perm, err := getUserRepoPermission(ctx, issue.Repo, doer)
if err != nil {
return err
}
@ -526,7 +527,7 @@ func (issue *Issue) ReplaceLabels(labels []*Label, doer *user_model.User) (err e
}
defer committer.Close()
if err = issue.loadRepo(db.GetEngine(ctx)); err != nil {
if err = issue.loadRepo(ctx); err != nil {
return err
}
@ -627,7 +628,7 @@ func (issue *Issue) changeStatus(ctx context.Context, doer *user_model.User, isC
func (issue *Issue) doChangeStatus(ctx context.Context, doer *user_model.User, isMergePull bool) (*Comment, error) {
e := db.GetEngine(ctx)
// Check for open dependencies
if issue.IsClosed && issue.Repo.isDependenciesEnabled(e) {
if issue.IsClosed && issue.Repo.IsDependenciesEnabledCtx(ctx) {
// only check if dependencies are enabled and we're about to close an issue, otherwise reopening an issue would fail when there are unsatisfied dependencies
noDeps, err := issueNoDependenciesLeft(e, issue)
if err != nil {
@ -694,7 +695,7 @@ func (issue *Issue) ChangeStatus(doer *user_model.User, isClosed bool) (*Comment
}
defer committer.Close()
if err := issue.loadRepo(db.GetEngine(ctx)); err != nil {
if err := issue.loadRepo(ctx); err != nil {
return nil, err
}
if err := issue.loadPoster(db.GetEngine(ctx)); err != nil {
@ -725,7 +726,7 @@ func (issue *Issue) ChangeTitle(doer *user_model.User, oldTitle string) (err err
return fmt.Errorf("updateIssueCols: %v", err)
}
if err = issue.loadRepo(db.GetEngine(ctx)); err != nil {
if err = issue.loadRepo(ctx); err != nil {
return fmt.Errorf("loadRepo: %v", err)
}
@ -759,7 +760,7 @@ func (issue *Issue) ChangeRef(doer *user_model.User, oldRef string) (err error)
return fmt.Errorf("updateIssueCols: %v", err)
}
if err = issue.loadRepo(db.GetEngine(ctx)); err != nil {
if err = issue.loadRepo(ctx); err != nil {
return fmt.Errorf("loadRepo: %v", err)
}
oldRefFriendly := strings.TrimPrefix(oldRef, git.BranchPrefix)
@ -781,7 +782,7 @@ func (issue *Issue) ChangeRef(doer *user_model.User, oldRef string) (err error)
}
// AddDeletePRBranchComment adds delete branch comment for pull request issue
func AddDeletePRBranchComment(doer *user_model.User, repo *Repository, issueID int64, branchName string) error {
func AddDeletePRBranchComment(doer *user_model.User, repo *repo_model.Repository, issueID int64, branchName string) error {
issue, err := getIssueByID(db.GetEngine(db.DefaultContext), issueID)
if err != nil {
return err
@ -918,7 +919,7 @@ func (issue *Issue) GetLastEventLabelFake() string {
// NewIssueOptions represents the options of a new issue.
type NewIssueOptions struct {
Repo *Repository
Repo *repo_model.Repository
Issue *Issue
LabelIDs []int64
Attachments []string // In UUID format.
@ -1005,7 +1006,7 @@ func newIssue(ctx context.Context, doer *user_model.User, opts NewIssueOptions)
}
}
if err = newIssueUsers(e, opts.Repo, opts.Issue); err != nil {
if err = newIssueUsers(ctx, opts.Repo, opts.Issue); err != nil {
return err
}
@ -1055,7 +1056,7 @@ func RecalculateIssueIndexForRepo(repoID int64) error {
}
// NewIssue creates new issue with labels for repository.
func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
func NewIssue(repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
idx, err := db.GetNextResourceIndex("issue_index", repo.ID)
if err != nil {
return fmt.Errorf("generate issue index failed: %v", err)
@ -1856,7 +1857,7 @@ func UpdateIssueByAPI(issue *Issue, doer *user_model.User) (statusChangeComment
defer committer.Close()
sess := db.GetEngine(ctx)
if err := issue.loadRepo(sess); err != nil {
if err := issue.loadRepo(ctx); err != nil {
return nil, false, fmt.Errorf("loadRepo: %v", err)
}
@ -1930,8 +1931,8 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *us
// DependencyInfo represents high level information about an issue which is a dependency of another issue.
type DependencyInfo struct {
Issue `xorm:"extends"`
Repository `xorm:"extends"`
Issue `xorm:"extends"`
repo_model.Repository `xorm:"extends"`
}
// getParticipantIDsByIssue returns all userIDs who are participated in comments of an issue and issue author
@ -2040,14 +2041,14 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx context.Context, doer *user_
if len(mentions) == 0 {
return
}
if err = issue.loadRepo(db.GetEngine(ctx)); err != nil {
if err = issue.loadRepo(ctx); err != nil {
return
}
resolved := make(map[string]bool, 10)
var mentionTeams []string
if err := issue.Repo.getOwner(db.GetEngine(ctx)); err != nil {
if err := issue.Repo.GetOwner(ctx); err != nil {
return nil, err
}
@ -2155,7 +2156,7 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx context.Context, doer *user_
continue
}
// Normal users must have read access to the referencing issue
perm, err := getUserRepoPermission(db.GetEngine(ctx), issue.Repo, user)
perm, err := getUserRepoPermission(ctx, issue.Repo, user)
if err != nil {
return nil, fmt.Errorf("getUserRepoPermission [%d]: %v", user.ID, err)
}

View file

@ -120,7 +120,7 @@ func (issue *Issue) toggleAssignee(ctx context.Context, doer *user_model.User, a
}
// Repo infos
if err = issue.loadRepo(sess); err != nil {
if err = issue.loadRepo(ctx); err != nil {
return false, nil, fmt.Errorf("loadRepo: %v", err)
}

View file

@ -219,9 +219,9 @@ type Comment struct {
RefAction references.XRefAction `xorm:"SMALLINT"` // What happens if RefIssueID resolves
RefIsPull bool
RefRepo *Repository `xorm:"-"`
RefIssue *Issue `xorm:"-"`
RefComment *Comment `xorm:"-"`
RefRepo *repo_model.Repository `xorm:"-"`
RefIssue *Issue `xorm:"-"`
RefComment *Comment `xorm:"-"`
Commits []*SignCommitWithStatuses `xorm:"-"`
OldCommit string `xorm:"-"`
@ -316,7 +316,7 @@ func (c *Comment) HTMLURL() string {
log.Error("LoadIssue(%d): %v", c.IssueID, err)
return ""
}
err = c.Issue.loadRepo(db.GetEngine(db.DefaultContext))
err = c.Issue.loadRepo(db.DefaultContext)
if err != nil { // Silently dropping errors :unamused:
log.Error("loadRepo(%d): %v", c.Issue.RepoID, err)
return ""
@ -345,7 +345,7 @@ func (c *Comment) APIURL() string {
log.Error("LoadIssue(%d): %v", c.IssueID, err)
return ""
}
err = c.Issue.loadRepo(db.GetEngine(db.DefaultContext))
err = c.Issue.loadRepo(db.DefaultContext)
if err != nil { // Silently dropping errors :unamused:
log.Error("loadRepo(%d): %v", c.Issue.RepoID, err)
return ""
@ -366,7 +366,7 @@ func (c *Comment) IssueURL() string {
return ""
}
err = c.Issue.loadRepo(db.GetEngine(db.DefaultContext))
err = c.Issue.loadRepo(db.DefaultContext)
if err != nil { // Silently dropping errors :unamused:
log.Error("loadRepo(%d): %v", c.Issue.RepoID, err)
return ""
@ -382,7 +382,7 @@ func (c *Comment) PRURL() string {
return ""
}
err = c.Issue.loadRepo(db.GetEngine(db.DefaultContext))
err = c.Issue.loadRepo(db.DefaultContext)
if err != nil { // Silently dropping errors :unamused:
log.Error("loadRepo(%d): %v", c.Issue.RepoID, err)
return ""
@ -536,7 +536,7 @@ func (c *Comment) LoadAssigneeUserAndTeam() error {
return err
}
if err = c.Issue.Repo.GetOwner(); err != nil {
if err = c.Issue.Repo.GetOwner(db.DefaultContext); err != nil {
return err
}
@ -589,7 +589,7 @@ func (c *Comment) LoadTime() error {
return err
}
func (c *Comment) loadReactions(e db.Engine, repo *Repository) (err error) {
func (c *Comment) loadReactions(e db.Engine, repo *repo_model.Repository) (err error) {
if c.Reactions != nil {
return nil
}
@ -608,7 +608,7 @@ func (c *Comment) loadReactions(e db.Engine, repo *Repository) (err error) {
}
// LoadReactions loads comment reactions
func (c *Comment) LoadReactions(repo *Repository) error {
func (c *Comment) LoadReactions(repo *repo_model.Repository) error {
return c.loadReactions(db.GetEngine(db.DefaultContext), repo)
}
@ -675,7 +675,7 @@ func (c *Comment) CodeCommentURL() string {
log.Error("LoadIssue(%d): %v", c.IssueID, err)
return ""
}
err = c.Issue.loadRepo(db.GetEngine(db.DefaultContext))
err = c.Issue.loadRepo(db.DefaultContext)
if err != nil { // Silently dropping errors :unamused:
log.Error("loadRepo(%d): %v", c.Issue.RepoID, err)
return ""
@ -764,7 +764,7 @@ func createComment(ctx context.Context, opts *CreateCommentOptions) (_ *Comment,
return nil, err
}
if err = opts.Repo.getOwner(e); err != nil {
if err = opts.Repo.GetOwner(ctx); err != nil {
return nil, err
}
@ -843,7 +843,7 @@ func createDeadlineComment(ctx context.Context, doer *user_model.User, issue *Is
content = newDeadlineUnix.Format("2006-01-02") + "|" + issue.DeadlineUnix.Format("2006-01-02")
}
if err := issue.loadRepo(db.GetEngine(ctx)); err != nil {
if err := issue.loadRepo(ctx); err != nil {
return nil, err
}
@ -867,7 +867,7 @@ func createIssueDependencyComment(ctx context.Context, doer *user_model.User, is
if !add {
cType = CommentTypeRemoveDependency
}
if err = issue.loadRepo(db.GetEngine(ctx)); err != nil {
if err = issue.loadRepo(ctx); err != nil {
return
}
@ -898,7 +898,7 @@ func createIssueDependencyComment(ctx context.Context, doer *user_model.User, is
type CreateCommentOptions struct {
Type CommentType
Doer *user_model.User
Repo *Repository
Repo *repo_model.Repository
Issue *Issue
Label *Label
@ -953,7 +953,7 @@ func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) {
}
// CreateRefComment creates a commit reference comment to issue.
func CreateRefComment(doer *user_model.User, repo *Repository, issue *Issue, content, commitSHA string) error {
func CreateRefComment(doer *user_model.User, repo *repo_model.Repository, issue *Issue, content, commitSHA string) error {
if len(commitSHA) == 0 {
return fmt.Errorf("cannot create reference with empty commit SHA")
}
@ -1144,11 +1144,11 @@ func deleteComment(e db.Engine, comment *Comment) error {
// CodeComments represents comments on code by using this structure: FILENAME -> LINE (+ == proposed; - == previous) -> COMMENTS
type CodeComments map[string]map[int64][]*Comment
func fetchCodeComments(e db.Engine, issue *Issue, currentUser *user_model.User) (CodeComments, error) {
return fetchCodeCommentsByReview(e, issue, currentUser, nil)
func fetchCodeComments(ctx context.Context, issue *Issue, currentUser *user_model.User) (CodeComments, error) {
return fetchCodeCommentsByReview(ctx, issue, currentUser, nil)
}
func fetchCodeCommentsByReview(e db.Engine, issue *Issue, currentUser *user_model.User, review *Review) (CodeComments, error) {
func fetchCodeCommentsByReview(ctx context.Context, issue *Issue, currentUser *user_model.User, review *Review) (CodeComments, error) {
pathToLineToComment := make(CodeComments)
if review == nil {
review = &Review{ID: 0}
@ -1159,7 +1159,7 @@ func fetchCodeCommentsByReview(e db.Engine, issue *Issue, currentUser *user_mode
ReviewID: review.ID,
}
comments, err := findCodeComments(e, opts, issue, currentUser, review)
comments, err := findCodeComments(ctx, opts, issue, currentUser, review)
if err != nil {
return nil, err
}
@ -1173,7 +1173,7 @@ func fetchCodeCommentsByReview(e db.Engine, issue *Issue, currentUser *user_mode
return pathToLineToComment, nil
}
func findCodeComments(e db.Engine, opts FindCommentsOptions, issue *Issue, currentUser *user_model.User, review *Review) ([]*Comment, error) {
func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issue, currentUser *user_model.User, review *Review) ([]*Comment, error) {
var comments []*Comment
if review == nil {
review = &Review{ID: 0}
@ -1182,6 +1182,7 @@ func findCodeComments(e db.Engine, opts FindCommentsOptions, issue *Issue, curre
if review.ID == 0 {
conds = conds.And(builder.Eq{"invalidated": false})
}
e := db.GetEngine(ctx)
if err := e.Where(conds).
Asc("comment.created_unix").
Asc("comment.id").
@ -1189,7 +1190,7 @@ func findCodeComments(e db.Engine, opts FindCommentsOptions, issue *Issue, curre
return nil, err
}
if err := issue.loadRepo(e); err != nil {
if err := issue.loadRepo(ctx); err != nil {
return nil, err
}
@ -1249,12 +1250,12 @@ func FetchCodeCommentsByLine(issue *Issue, currentUser *user_model.User, treePat
TreePath: treePath,
Line: line,
}
return findCodeComments(db.GetEngine(db.DefaultContext), opts, issue, currentUser, nil)
return findCodeComments(db.DefaultContext, opts, issue, currentUser, nil)
}
// FetchCodeComments will return a 2d-map: ["Path"]["Line"] = Comments at line
func FetchCodeComments(issue *Issue, currentUser *user_model.User) (CodeComments, error) {
return fetchCodeComments(db.GetEngine(db.DefaultContext), issue, currentUser)
return fetchCodeComments(db.DefaultContext, issue, currentUser)
}
// UpdateCommentsMigrationsByType updates comments' migrations information via given git service type and original id and poster id
@ -1313,7 +1314,7 @@ func CreatePushPullComment(pusher *user_model.User, pr *PullRequest, oldCommitID
// getCommitsFromRepo get commit IDs from repo in between oldCommitID and newCommitID
// isForcePush will be true if oldCommit isn't on the branch
// Commit on baseBranch will skip
func getCommitIDsFromRepo(repo *Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, isForcePush bool, err error) {
func getCommitIDsFromRepo(repo *repo_model.Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, isForcePush bool, err error) {
repoPath := repo.RepoPath()
gitRepo, err := git.OpenRepository(repoPath)
if err != nil {

View file

@ -5,6 +5,8 @@
package models
import (
"context"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
@ -343,11 +345,12 @@ func (comments CommentList) getDependentIssueIDs() []int64 {
return keysInt64(ids)
}
func (comments CommentList) loadDependentIssues(e db.Engine) error {
func (comments CommentList) loadDependentIssues(ctx context.Context) error {
if len(comments) == 0 {
return nil
}
e := db.GetEngine(ctx)
issueIDs := comments.getDependentIssueIDs()
issues := make(map[int64]*Issue, len(issueIDs))
left := len(issueIDs)
@ -383,7 +386,7 @@ func (comments CommentList) loadDependentIssues(e db.Engine) error {
if comment.DependentIssue == nil {
comment.DependentIssue = issues[comment.DependentIssueID]
if comment.DependentIssue != nil {
if err := comment.DependentIssue.loadRepo(e); err != nil {
if err := comment.DependentIssue.loadRepo(ctx); err != nil {
return err
}
}
@ -487,7 +490,8 @@ func (comments CommentList) loadReviews(e db.Engine) error {
}
// loadAttributes loads all attributes
func (comments CommentList) loadAttributes(e db.Engine) (err error) {
func (comments CommentList) loadAttributes(ctx context.Context) (err error) {
e := db.GetEngine(ctx)
if err = comments.loadPosters(e); err != nil {
return
}
@ -520,7 +524,7 @@ func (comments CommentList) loadAttributes(e db.Engine) (err error) {
return
}
if err = comments.loadDependentIssues(e); err != nil {
if err = comments.loadDependentIssues(ctx); err != nil {
return
}
@ -530,7 +534,7 @@ func (comments CommentList) loadAttributes(e db.Engine) (err error) {
// LoadAttributes loads attributes of the comments, except for attachments and
// comments
func (comments CommentList) LoadAttributes() error {
return comments.loadAttributes(db.GetEngine(db.DefaultContext))
return comments.loadAttributes(db.DefaultContext)
}
// LoadAttachments loads attachments

View file

@ -8,6 +8,7 @@ import (
"testing"
"time"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@ -18,7 +19,7 @@ func TestCreateComment(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &Issue{}).(*Issue)
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: issue.RepoID}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository)
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
now := time.Now().Unix()

View file

@ -6,10 +6,7 @@ package models
import (
"code.gitea.io/gitea/models/db"
"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/setting"
"code.gitea.io/gitea/modules/timeutil"
)
@ -135,18 +132,3 @@ func issueNoDependenciesLeft(e db.Engine, issue *Issue) (bool, error) {
return !exists, err
}
// IsDependenciesEnabled returns if dependencies are enabled and returns the default setting if not set.
func (repo *Repository) IsDependenciesEnabled() bool {
return repo.isDependenciesEnabled(db.GetEngine(db.DefaultContext))
}
func (repo *Repository) isDependenciesEnabled(e db.Engine) bool {
var u *RepoUnit
var err error
if u, err = repo.getUnit(e, unit.TypeIssues); err != nil {
log.Trace("%s", err)
return setting.Service.DefaultEnableDependencies
}
return u.IssuesConfig().EnableDependencies
}

View file

@ -675,7 +675,7 @@ func newIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *user_m
return err
}
if err = issue.loadRepo(e); err != nil {
if err = issue.loadRepo(ctx); err != nil {
return
}
@ -707,7 +707,7 @@ func NewIssueLabel(issue *Issue, label *Label, doer *user_model.User) (err error
defer committer.Close()
sess := db.GetEngine(ctx)
if err = issue.loadRepo(sess); err != nil {
if err = issue.loadRepo(ctx); err != nil {
return err
}
@ -731,7 +731,7 @@ func NewIssueLabel(issue *Issue, label *Label, doer *user_model.User) (err error
// newIssueLabels add labels to an issue. It will check if the labels are valid for the issue
func newIssueLabels(ctx context.Context, issue *Issue, labels []*Label, doer *user_model.User) (err error) {
e := db.GetEngine(ctx)
if err = issue.loadRepo(e); err != nil {
if err = issue.loadRepo(ctx); err != nil {
return err
}
for _, label := range labels {
@ -780,7 +780,7 @@ func deleteIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *use
return nil
}
if err = issue.loadRepo(e); err != nil {
if err = issue.loadRepo(ctx); err != nil {
return
}

View file

@ -9,6 +9,7 @@ import (
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@ -49,7 +50,7 @@ func TestNewLabels(t *testing.T) {
for _, label := range labels {
unittest.AssertExistsAndLoadBean(t, label, unittest.Cond("id = ?", label.ID))
}
unittest.CheckConsistencyFor(t, &Label{}, &Repository{})
unittest.CheckConsistencyFor(t, &Label{}, &repo_model.Repository{})
}
func TestGetLabelByID(t *testing.T) {
@ -270,7 +271,7 @@ func TestUpdateLabel(t *testing.T) {
assert.EqualValues(t, label.Color, newLabel.Color)
assert.EqualValues(t, label.Name, newLabel.Name)
assert.EqualValues(t, label.Description, newLabel.Description)
unittest.CheckConsistencyFor(t, &Label{}, &Repository{})
unittest.CheckConsistencyFor(t, &Label{}, &repo_model.Repository{})
}
func TestDeleteLabel(t *testing.T) {
@ -283,7 +284,7 @@ func TestDeleteLabel(t *testing.T) {
unittest.AssertNotExistsBean(t, &Label{ID: label.ID})
assert.NoError(t, DeleteLabel(unittest.NonexistentID, unittest.NonexistentID))
unittest.CheckConsistencyFor(t, &Label{}, &Repository{})
unittest.CheckConsistencyFor(t, &Label{}, &repo_model.Repository{})
}
func TestHasIssueLabel(t *testing.T) {

View file

@ -32,13 +32,13 @@ func (issues IssueList) getRepoIDs() []int64 {
return keysInt64(repoIDs)
}
func (issues IssueList) loadRepositories(e db.Engine) ([]*Repository, error) {
func (issues IssueList) loadRepositories(e db.Engine) ([]*repo_model.Repository, error) {
if len(issues) == 0 {
return nil, nil
}
repoIDs := issues.getRepoIDs()
repoMaps := make(map[int64]*Repository, len(repoIDs))
repoMaps := make(map[int64]*repo_model.Repository, len(repoIDs))
left := len(repoIDs)
for left > 0 {
limit := defaultMaxInSize
@ -65,7 +65,7 @@ func (issues IssueList) loadRepositories(e db.Engine) ([]*Repository, error) {
}
// LoadRepositories loads issues' all repositories
func (issues IssueList) LoadRepositories() ([]*Repository, error) {
func (issues IssueList) LoadRepositories() ([]*repo_model.Repository, error) {
return issues.loadRepositories(db.GetEngine(db.DefaultContext))
}

View file

@ -11,6 +11,7 @@ import (
"time"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
@ -21,9 +22,9 @@ import (
// Milestone represents a milestone of repository.
type Milestone struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX"`
Repo *Repository `xorm:"-"`
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX"`
Repo *repo_model.Repository `xorm:"-"`
Name string
Content string `xorm:"TEXT"`
RenderedContent string `xorm:"-"`
@ -287,7 +288,7 @@ func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *Is
}
if oldMilestoneID > 0 || issue.MilestoneID > 0 {
if err := issue.loadRepo(e); err != nil {
if err := issue.loadRepo(ctx); err != nil {
return err
}
@ -335,7 +336,7 @@ func DeleteMilestoneByRepoID(repoID, id int64) error {
return err
}
repo, err := GetRepositoryByID(m.RepoID)
repo, err := repo_model.GetRepositoryByID(m.RepoID)
if err != nil {
return err
}

View file

@ -9,6 +9,7 @@ import (
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
@ -34,7 +35,7 @@ func TestNewMilestone(t *testing.T) {
assert.NoError(t, NewMilestone(milestone))
unittest.AssertExistsAndLoadBean(t, milestone)
unittest.CheckConsistencyFor(t, &Repository{ID: milestone.RepoID}, &Milestone{})
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &Milestone{})
}
func TestGetMilestoneByRepoID(t *testing.T) {
@ -52,7 +53,7 @@ func TestGetMilestoneByRepoID(t *testing.T) {
func TestGetMilestonesByRepoID(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64, state api.StateType) {
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
milestones, _, err := GetMilestones(GetMilestonesOption{
RepoID: repo.ID,
State: state,
@ -100,7 +101,7 @@ func TestGetMilestonesByRepoID(t *testing.T) {
func TestGetMilestones(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
test := func(sortType string, sortCond func(*Milestone) int) {
for _, page := range []int{0, 1} {
milestones, _, err := GetMilestones(GetMilestonesOption{
@ -174,7 +175,7 @@ func TestUpdateMilestone(t *testing.T) {
func TestCountRepoMilestones(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64) {
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
count, err := countRepoMilestones(db.GetEngine(db.DefaultContext), repoID)
assert.NoError(t, err)
assert.EqualValues(t, repo.NumMilestones, count)
@ -191,7 +192,7 @@ func TestCountRepoMilestones(t *testing.T) {
func TestCountRepoClosedMilestones(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64) {
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
count, err := CountRepoClosedMilestones(repoID)
assert.NoError(t, err)
assert.EqualValues(t, repo.NumClosedMilestones, count)
@ -211,11 +212,11 @@ func TestChangeMilestoneStatus(t *testing.T) {
assert.NoError(t, ChangeMilestoneStatus(milestone, true))
unittest.AssertExistsAndLoadBean(t, &Milestone{ID: 1}, "is_closed=1")
unittest.CheckConsistencyFor(t, &Repository{ID: milestone.RepoID}, &Milestone{})
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &Milestone{})
assert.NoError(t, ChangeMilestoneStatus(milestone, false))
unittest.AssertExistsAndLoadBean(t, &Milestone{ID: 1}, "is_closed=0")
unittest.CheckConsistencyFor(t, &Repository{ID: milestone.RepoID}, &Milestone{})
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &Milestone{})
}
func TestUpdateMilestoneCounters(t *testing.T) {
@ -261,7 +262,7 @@ func TestDeleteMilestoneByRepoID(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
assert.NoError(t, DeleteMilestoneByRepoID(1, 1))
unittest.AssertNotExistsBean(t, &Milestone{ID: 1})
unittest.CheckConsistencyFor(t, &Repository{ID: 1})
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: 1})
assert.NoError(t, DeleteMilestoneByRepoID(unittest.NonexistentID, unittest.NonexistentID))
}
@ -280,7 +281,7 @@ func TestMilestoneList_LoadTotalTrackedTimes(t *testing.T) {
func TestCountMilestonesByRepoIDs(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
milestonesCount := func(repoID int64) (int, int) {
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
return repo.NumOpenMilestones, repo.NumClosedMilestones
}
repo1OpenCount, repo1ClosedCount := milestonesCount(1)
@ -299,8 +300,8 @@ func TestCountMilestonesByRepoIDs(t *testing.T) {
func TestGetMilestonesByRepoIDs(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo2 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
test := func(sortType string, sortCond func(*Milestone) int) {
for _, page := range []int{0, 1} {
openMilestones, err := GetMilestonesByRepoIDs([]int64{repo1.ID, repo2.ID}, page, false, sortType)
@ -355,7 +356,7 @@ func TestGetMilestonesStats(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64) {
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
stats, err := GetMilestonesStatsByRepoCond(builder.And(builder.Eq{"repo_id": repoID}))
assert.NoError(t, err)
assert.EqualValues(t, repo.NumMilestones-repo.NumClosedMilestones, stats.OpenCount)
@ -370,8 +371,8 @@ func TestGetMilestonesStats(t *testing.T) {
assert.EqualValues(t, 0, stats.OpenCount)
assert.EqualValues(t, 0, stats.ClosedCount)
repo1 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo2 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
milestoneStats, err := GetMilestonesStatsByRepoCond(builder.In("repo_id", []int64{repo1.ID, repo2.ID}))
assert.NoError(t, err)

View file

@ -9,6 +9,7 @@ import (
"fmt"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
@ -286,7 +287,7 @@ func (list ReactionList) getUserIDs() []int64 {
return keysInt64(userIDs)
}
func (list ReactionList) loadUsers(e db.Engine, repo *Repository) ([]*user_model.User, error) {
func (list ReactionList) loadUsers(e db.Engine, repo *repo_model.Repository) ([]*user_model.User, error) {
if len(list) == 0 {
return nil, nil
}
@ -313,7 +314,7 @@ func (list ReactionList) loadUsers(e db.Engine, repo *Repository) ([]*user_model
}
// LoadUsers loads reactions' all users
func (list ReactionList) LoadUsers(repo *Repository) ([]*user_model.User, error) {
func (list ReactionList) LoadUsers(repo *repo_model.Repository) ([]*user_model.User, error) {
return list.loadUsers(db.GetEngine(db.DefaultContext), repo)
}

View file

@ -7,6 +7,7 @@ import (
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
@ -95,7 +96,7 @@ func TestIssueReactionCount(t *testing.T) {
addReaction(t, user4, issue, nil, "heart")
addReaction(t, ghost, issue, nil, "-1")
err := issue.loadReactions(db.GetEngine(db.DefaultContext))
err := issue.loadReactions(db.DefaultContext)
assert.NoError(t, err)
assert.Len(t, issue.Reactions, 7)
@ -135,7 +136,7 @@ func TestIssueCommentDeleteReaction(t *testing.T) {
user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
issue1 := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue)
repo1 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: issue1.RepoID}).(*Repository)
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue1.RepoID}).(*repo_model.Repository)
comment1 := unittest.AssertExistsAndLoadBean(t, &Comment{ID: 1}).(*Comment)

View file

@ -156,7 +156,7 @@ func FinishIssueStopwatch(ctx context.Context, user *user_model.User, issue *Iss
return err
}
if err := issue.loadRepo(db.GetEngine(ctx)); err != nil {
if err := issue.loadRepo(ctx); err != nil {
return err
}
@ -177,7 +177,7 @@ func FinishIssueStopwatch(ctx context.Context, user *user_model.User, issue *Iss
// CreateIssueStopwatch creates a stopwatch if not exist, otherwise return an error
func CreateIssueStopwatch(ctx context.Context, user *user_model.User, issue *Issue) error {
e := db.GetEngine(ctx)
if err := issue.loadRepo(e); err != nil {
if err := issue.loadRepo(ctx); err != nil {
return err
}
@ -207,7 +207,7 @@ func CreateIssueStopwatch(ctx context.Context, user *user_model.User, issue *Iss
return err
}
if err := issue.loadRepo(db.GetEngine(ctx)); err != nil {
if err := issue.loadRepo(ctx); err != nil {
return err
}
@ -248,11 +248,7 @@ func cancelStopwatch(ctx context.Context, user *user_model.User, issue *Issue) e
return err
}
if err := issue.loadRepo(e); err != nil {
return err
}
if err := issue.loadRepo(db.GetEngine(ctx)); err != nil {
if err := issue.loadRepo(ctx); err != nil {
return err
}

View file

@ -12,6 +12,7 @@ import (
"time"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@ -23,7 +24,7 @@ func TestIssue_ReplaceLabels(t *testing.T) {
testSuccess := func(issueID int64, labelIDs []int64) {
issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issueID}).(*Issue)
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: issue.RepoID}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository)
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
labels := make([]*Label, len(labelIDs))
@ -354,7 +355,7 @@ func TestGetRepoIDsForIssuesOptions(t *testing.T) {
func testInsertIssue(t *testing.T, title, content string, expectIndex int64) *Issue {
var newIssue Issue
t.Run(title, func(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
issue := Issue{
@ -398,7 +399,7 @@ func TestIssue_ResolveMentions(t *testing.T) {
testSuccess := func(owner, repo, doer string, mentions []string, expected []int64) {
o := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: owner}).(*user_model.User)
r := unittest.AssertExistsAndLoadBean(t, &Repository{OwnerID: o.ID, LowerName: repo}).(*Repository)
r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: o.ID, LowerName: repo}).(*repo_model.Repository)
issue := &Issue{RepoID: r.ID}
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: doer}).(*user_model.User)
resolved, err := issue.ResolveMentionsByVisibility(db.DefaultContext, d, mentions)

View file

@ -5,6 +5,7 @@
package models
import (
"context"
"time"
"code.gitea.io/gitea/models/db"
@ -41,16 +42,17 @@ func (t *TrackedTime) AfterLoad() {
// LoadAttributes load Issue, User
func (t *TrackedTime) LoadAttributes() (err error) {
return t.loadAttributes(db.GetEngine(db.DefaultContext))
return t.loadAttributes(db.DefaultContext)
}
func (t *TrackedTime) loadAttributes(e db.Engine) (err error) {
func (t *TrackedTime) loadAttributes(ctx context.Context) (err error) {
e := db.GetEngine(ctx)
if t.Issue == nil {
t.Issue, err = getIssueByID(e, t.IssueID)
if err != nil {
return
}
err = t.Issue.loadRepo(e)
err = t.Issue.loadRepo(ctx)
if err != nil {
return
}
@ -167,7 +169,7 @@ func AddTime(user *user_model.User, issue *Issue, amount int64, created time.Tim
return nil, err
}
if err := issue.loadRepo(sess); err != nil {
if err := issue.loadRepo(ctx); err != nil {
return nil, err
}
@ -251,7 +253,7 @@ func DeleteIssueUserTimes(issue *Issue, user *user_model.User) error {
return ErrNotExist{}
}
if err := issue.loadRepo(sess); err != nil {
if err := issue.loadRepo(ctx); err != nil {
return err
}
if _, err := createComment(ctx, &CreateCommentOptions{
@ -274,13 +276,12 @@ func DeleteTime(t *TrackedTime) error {
return err
}
defer committer.Close()
sess := db.GetEngine(ctx)
if err := t.loadAttributes(sess); err != nil {
if err := t.loadAttributes(ctx); err != nil {
return err
}
if err := deleteTime(sess, t); err != nil {
if err := deleteTime(db.GetEngine(ctx), t); err != nil {
return err
}

View file

@ -9,6 +9,7 @@ import (
"fmt"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
)
// IssueUser represents an issue-user relation.
@ -24,8 +25,8 @@ func init() {
db.RegisterModel(new(IssueUser))
}
func newIssueUsers(e db.Engine, repo *Repository, issue *Issue) error {
assignees, err := repo.getAssignees(e)
func newIssueUsers(ctx context.Context, repo *repo_model.Repository, issue *Issue) error {
assignees, err := getRepoAssignees(ctx, repo)
if err != nil {
return fmt.Errorf("getAssignees: %v", err)
}
@ -50,10 +51,7 @@ func newIssueUsers(e db.Engine, repo *Repository, issue *Issue) error {
})
}
if _, err = e.Insert(issueUsers); err != nil {
return err
}
return nil
return db.Insert(ctx, issueUsers)
}
// UpdateIssueUserByRead updates issue-user relation for reading.

View file

@ -8,6 +8,7 @@ import (
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
@ -16,7 +17,7 @@ import (
func Test_newIssueUsers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
newIssue := &Issue{
RepoID: repo.ID,
PosterID: 4,
@ -28,7 +29,7 @@ func Test_newIssueUsers(t *testing.T) {
// artificially insert new issue
unittest.AssertSuccessfulInsert(t, newIssue)
assert.NoError(t, newIssueUsers(db.GetEngine(db.DefaultContext), repo, newIssue))
assert.NoError(t, newIssueUsers(db.DefaultContext, repo, newIssue))
// issue_user table should now have entries for new issue
unittest.AssertExistsAndLoadBean(t, &IssueUser{IssueID: newIssue.ID, UID: newIssue.PosterID})

View file

@ -9,6 +9,7 @@ import (
"fmt"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/references"
@ -79,7 +80,7 @@ func (issue *Issue) addCrossReferences(stdCtx context.Context, doer *user_model.
func (issue *Issue) createCrossReferences(stdCtx context.Context, ctx *crossReferencesContext, plaincontent, mdcontent string) error {
e := db.GetEngine(stdCtx)
xreflist, err := ctx.OrigIssue.getCrossReferences(e, ctx, plaincontent, mdcontent)
xreflist, err := ctx.OrigIssue.getCrossReferences(stdCtx, ctx, plaincontent, mdcontent)
if err != nil {
return err
}
@ -136,35 +137,34 @@ func (issue *Issue) createCrossReferences(stdCtx context.Context, ctx *crossRefe
return nil
}
func (issue *Issue) getCrossReferences(e db.Engine, ctx *crossReferencesContext, plaincontent, mdcontent string) ([]*crossReference, error) {
func (issue *Issue) getCrossReferences(stdCtx context.Context, ctx *crossReferencesContext, plaincontent, mdcontent string) ([]*crossReference, error) {
xreflist := make([]*crossReference, 0, 5)
var (
refRepo *Repository
refRepo *repo_model.Repository
refIssue *Issue
refAction references.XRefAction
err error
)
allrefs := append(references.FindAllIssueReferences(plaincontent), references.FindAllIssueReferencesMarkdown(mdcontent)...)
for _, ref := range allrefs {
if ref.Owner == "" && ref.Name == "" {
// Issues in the same repository
if err := ctx.OrigIssue.loadRepo(e); err != nil {
if err := ctx.OrigIssue.loadRepo(stdCtx); err != nil {
return nil, err
}
refRepo = ctx.OrigIssue.Repo
} else {
// Issues in other repositories
refRepo, err = getRepositoryByOwnerAndName(e, ref.Owner, ref.Name)
refRepo, err = repo_model.GetRepositoryByOwnerAndNameCtx(stdCtx, ref.Owner, ref.Name)
if err != nil {
if IsErrRepoNotExist(err) {
if repo_model.IsErrRepoNotExist(err) {
continue
}
return nil, err
}
}
if refIssue, refAction, err = ctx.OrigIssue.verifyReferencedIssue(e, ctx, refRepo, ref); err != nil {
if refIssue, refAction, err = ctx.OrigIssue.verifyReferencedIssue(stdCtx, ctx, refRepo, ref); err != nil {
return nil, err
}
if refIssue != nil {
@ -194,15 +194,16 @@ func (issue *Issue) updateCrossReferenceList(list []*crossReference, xref *cross
}
// verifyReferencedIssue will check if the referenced issue exists, and whether the doer has permission to do what
func (issue *Issue) verifyReferencedIssue(e db.Engine, ctx *crossReferencesContext, repo *Repository,
func (issue *Issue) verifyReferencedIssue(stdCtx context.Context, ctx *crossReferencesContext, repo *repo_model.Repository,
ref references.IssueReference) (*Issue, references.XRefAction, error) {
refIssue := &Issue{RepoID: repo.ID, Index: ref.Index}
refAction := ref.Action
e := db.GetEngine(stdCtx)
if has, _ := e.Get(refIssue); !has {
return nil, references.XRefActionNone, nil
}
if err := refIssue.loadRepo(e); err != nil {
if err := refIssue.loadRepo(stdCtx); err != nil {
return nil, references.XRefActionNone, err
}
@ -213,7 +214,7 @@ func (issue *Issue) verifyReferencedIssue(e db.Engine, ctx *crossReferencesConte
// Check doer permissions; set action to None if the doer can't change the destination
if refIssue.RepoID != ctx.OrigIssue.RepoID || ref.Action != references.XRefActionNone {
perm, err := getUserRepoPermission(e, refIssue.Repo, ctx.Doer)
perm, err := getUserRepoPermission(stdCtx, refIssue.Repo, ctx.Doer)
if err != nil {
return nil, references.XRefActionNone, err
}
@ -280,7 +281,7 @@ func (comment *Comment) LoadRefIssue() (err error) {
}
comment.RefIssue, err = GetIssueByID(comment.RefIssueID)
if err == nil {
err = comment.RefIssue.loadRepo(db.GetEngine(db.DefaultContext))
err = comment.RefIssue.loadRepo(db.DefaultContext)
}
return
}

View file

@ -9,6 +9,7 @@ import (
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/references"
@ -126,7 +127,7 @@ func TestXRef_ResolveCrossReferences(t *testing.T) {
}
func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispull bool) *Issue {
r := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repo}).(*Repository)
r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}).(*repo_model.Repository)
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User)
idx, err := db.GetNextResourceIndex("issue_index", r.ID)
@ -157,7 +158,7 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu
}
func testCreatePR(t *testing.T, repo, doer int64, title, content string) *PullRequest {
r := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repo}).(*Repository)
r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}).(*repo_model.Repository)
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User)
i := &Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true}
pr := &PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base", Status: PullRequestStatusMergeable}

View file

@ -5,9 +5,11 @@
package models
import (
"context"
"errors"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/timeutil"
@ -71,12 +73,12 @@ func NewLFSMetaObject(m *LFSMetaObject) (*LFSMetaObject, error) {
// GetLFSMetaObjectByOid selects a LFSMetaObject entry from database by its OID.
// It may return ErrLFSObjectNotExist or a database error. If the error is nil,
// the returned pointer is a valid LFSMetaObject.
func (repo *Repository) GetLFSMetaObjectByOid(oid string) (*LFSMetaObject, error) {
func GetLFSMetaObjectByOid(repoID int64, oid string) (*LFSMetaObject, error) {
if len(oid) == 0 {
return nil, ErrLFSObjectNotExist
}
m := &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}, RepositoryID: repo.ID}
m := &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}, RepositoryID: repoID}
has, err := db.GetEngine(db.DefaultContext).Get(m)
if err != nil {
return nil, err
@ -88,7 +90,7 @@ func (repo *Repository) GetLFSMetaObjectByOid(oid string) (*LFSMetaObject, error
// RemoveLFSMetaObjectByOid removes a LFSMetaObject entry from database by its OID.
// It may return ErrLFSObjectNotExist or a database error.
func (repo *Repository) RemoveLFSMetaObjectByOid(oid string) (int64, error) {
func RemoveLFSMetaObjectByOid(repoID int64, oid string) (int64, error) {
if len(oid) == 0 {
return 0, ErrLFSObjectNotExist
}
@ -99,7 +101,7 @@ func (repo *Repository) RemoveLFSMetaObjectByOid(oid string) (int64, error) {
}
defer committer.Close()
m := &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}, RepositoryID: repo.ID}
m := &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}, RepositoryID: repoID}
if _, err := db.DeleteByBean(ctx, m); err != nil {
return -1, err
}
@ -113,7 +115,7 @@ func (repo *Repository) RemoveLFSMetaObjectByOid(oid string) (int64, error) {
}
// GetLFSMetaObjects returns all LFSMetaObjects associated with a repository
func (repo *Repository) GetLFSMetaObjects(page, pageSize int) ([]*LFSMetaObject, error) {
func GetLFSMetaObjects(repoID int64, page, pageSize int) ([]*LFSMetaObject, error) {
sess := db.GetEngine(db.DefaultContext)
if page >= 0 && pageSize > 0 {
@ -124,12 +126,12 @@ func (repo *Repository) GetLFSMetaObjects(page, pageSize int) ([]*LFSMetaObject,
sess.Limit(pageSize, start)
}
lfsObjects := make([]*LFSMetaObject, 0, pageSize)
return lfsObjects, sess.Find(&lfsObjects, &LFSMetaObject{RepositoryID: repo.ID})
return lfsObjects, sess.Find(&lfsObjects, &LFSMetaObject{RepositoryID: repoID})
}
// CountLFSMetaObjects returns a count of all LFSMetaObjects associated with a repository
func (repo *Repository) CountLFSMetaObjects() (int64, error) {
return db.GetEngine(db.DefaultContext).Count(&LFSMetaObject{RepositoryID: repo.ID})
func CountLFSMetaObjects(repoID int64) (int64, error) {
return db.GetEngine(db.DefaultContext).Count(&LFSMetaObject{RepositoryID: repoID})
}
// LFSObjectAccessible checks if a provided Oid is accessible to the user
@ -202,3 +204,21 @@ func IterateLFS(f func(mo *LFSMetaObject) error) error {
}
}
}
// CopyLFS copies LFS data from one repo to another
func CopyLFS(ctx context.Context, newRepo, oldRepo *repo_model.Repository) error {
var lfsObjects []*LFSMetaObject
if err := db.GetEngine(ctx).Where("repository_id=?", oldRepo.ID).Find(&lfsObjects); err != nil {
return err
}
for _, v := range lfsObjects {
v.ID = 0
v.RepositoryID = newRepo.ID
if _, err := db.GetEngine(ctx).Insert(v); err != nil {
return err
}
}
return nil
}

View file

@ -12,21 +12,19 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
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"
"xorm.io/xorm"
"code.gitea.io/gitea/modules/setting"
)
// LFSLock represents a git lfs lock of repository.
type LFSLock struct {
ID int64 `xorm:"pk autoincr"`
Repo *Repository `xorm:"-"`
RepoID int64 `xorm:"INDEX NOT NULL"`
OwnerID int64 `xorm:"INDEX NOT NULL"`
Path string `xorm:"TEXT"`
Created time.Time `xorm:"created"`
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX NOT NULL"`
OwnerID int64 `xorm:"INDEX NOT NULL"`
Path string `xorm:"TEXT"`
Created time.Time `xorm:"created"`
}
func init() {
@ -35,33 +33,24 @@ func init() {
// BeforeInsert is invoked from XORM before inserting an object of this type.
func (l *LFSLock) BeforeInsert() {
l.RepoID = l.Repo.ID
l.Path = cleanPath(l.Path)
}
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
func (l *LFSLock) AfterLoad(session *xorm.Session) {
var err error
l.Repo, err = getRepositoryByID(session, l.RepoID)
if err != nil {
log.Error("LFS lock AfterLoad failed RepoId[%d] not found: %v", l.RepoID, err)
}
}
func cleanPath(p string) string {
return path.Clean("/" + p)[1:]
}
// CreateLFSLock creates a new lock.
func CreateLFSLock(lock *LFSLock) (*LFSLock, error) {
err := CheckLFSAccessForRepo(lock.OwnerID, lock.Repo, perm.AccessModeWrite)
func CreateLFSLock(repo *repo_model.Repository, lock *LFSLock) (*LFSLock, error) {
err := CheckLFSAccessForRepo(lock.OwnerID, repo, perm.AccessModeWrite)
if err != nil {
return nil, err
}
lock.Path = cleanPath(lock.Path)
lock.RepoID = repo.ID
l, err := GetLFSLock(lock.Repo, lock.Path)
l, err := GetLFSLock(repo, lock.Path)
if err == nil {
return l, ErrLFSLockAlreadyExist{lock.RepoID, lock.Path}
}
@ -69,12 +58,12 @@ func CreateLFSLock(lock *LFSLock) (*LFSLock, error) {
return nil, err
}
_, err = db.GetEngine(db.DefaultContext).InsertOne(lock)
err = db.Insert(db.DefaultContext, lock)
return lock, err
}
// GetLFSLock returns release by given path.
func GetLFSLock(repo *Repository, path string) (*LFSLock, error) {
func GetLFSLock(repo *repo_model.Repository, path string) (*LFSLock, error) {
path = cleanPath(path)
rel := &LFSLock{RepoID: repo.ID}
has, err := db.GetEngine(db.DefaultContext).Where("lower(path) = ?", strings.ToLower(path)).Get(rel)
@ -113,19 +102,37 @@ func GetLFSLockByRepoID(repoID int64, page, pageSize int) ([]*LFSLock, error) {
return lfsLocks, e.Find(&lfsLocks, &LFSLock{RepoID: repoID})
}
// GetTreePathLock returns LSF lock for the treePath
func GetTreePathLock(repoID int64, treePath string) (*LFSLock, error) {
if !setting.LFS.StartServer {
return nil, nil
}
locks, err := GetLFSLockByRepoID(repoID, 0, 0)
if err != nil {
return nil, err
}
for _, lock := range locks {
if lock.Path == treePath {
return lock, nil
}
}
return nil, nil
}
// CountLFSLockByRepoID returns a count of all LFSLocks associated with a repository.
func CountLFSLockByRepoID(repoID int64) (int64, error) {
return db.GetEngine(db.DefaultContext).Count(&LFSLock{RepoID: repoID})
}
// DeleteLFSLockByID deletes a lock by given ID.
func DeleteLFSLockByID(id int64, u *user_model.User, force bool) (*LFSLock, error) {
func DeleteLFSLockByID(id int64, repo *repo_model.Repository, u *user_model.User, force bool) (*LFSLock, error) {
lock, err := GetLFSLockByID(id)
if err != nil {
return nil, err
}
err = CheckLFSAccessForRepo(u.ID, lock.Repo, perm.AccessModeWrite)
err = CheckLFSAccessForRepo(u.ID, repo, perm.AccessModeWrite)
if err != nil {
return nil, err
}
@ -139,7 +146,7 @@ func DeleteLFSLockByID(id int64, u *user_model.User, force bool) (*LFSLock, erro
}
// CheckLFSAccessForRepo check needed access mode base on action
func CheckLFSAccessForRepo(ownerID int64, repo *Repository, mode perm.AccessMode) error {
func CheckLFSAccessForRepo(ownerID int64, repo *repo_model.Repository, mode perm.AccessMode) error {
if ownerID == 0 {
return ErrLFSUnauthorizedAction{repo.ID, "undefined", mode}
}

View file

@ -7,6 +7,7 @@ package models
import (
"testing"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@ -18,7 +19,7 @@ func TestFixturesAreConsistent(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
unittest.CheckConsistencyFor(t,
&user_model.User{},
&Repository{},
&repo_model.Repository{},
&Issue{},
&PullRequest{},
&Milestone{},

View file

@ -11,6 +11,7 @@ import (
"strconv"
"code.gitea.io/gitea/models/db"
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"
@ -63,10 +64,10 @@ type Notification struct {
UpdatedBy int64 `xorm:"INDEX NOT NULL"`
Issue *Issue `xorm:"-"`
Repository *Repository `xorm:"-"`
Comment *Comment `xorm:"-"`
User *user_model.User `xorm:"-"`
Issue *Issue `xorm:"-"`
Repository *repo_model.Repository `xorm:"-"`
Comment *Comment `xorm:"-"`
User *user_model.User `xorm:"-"`
CreatedUnix timeutil.TimeStamp `xorm:"created INDEX NOT NULL"`
UpdatedUnix timeutil.TimeStamp `xorm:"updated INDEX NOT NULL"`
@ -140,7 +141,7 @@ func CountNotifications(opts *FindNotificationOptions) (int64, error) {
}
// CreateRepoTransferNotification creates notification for the user a repository was transferred to
func CreateRepoTransferNotification(doer, newOwner *user_model.User, repo *Repository) error {
func CreateRepoTransferNotification(doer, newOwner *user_model.User, repo *repo_model.Repository) error {
ctx, committer, err := db.TxContext()
if err != nil {
return err
@ -190,14 +191,15 @@ func CreateOrUpdateIssueNotifications(issueID, commentID, notificationAuthorID,
}
defer committer.Close()
if err := createOrUpdateIssueNotifications(db.GetEngine(ctx), issueID, commentID, notificationAuthorID, receiverID); err != nil {
if err := createOrUpdateIssueNotifications(ctx, issueID, commentID, notificationAuthorID, receiverID); err != nil {
return err
}
return committer.Commit()
}
func createOrUpdateIssueNotifications(e db.Engine, issueID, commentID, notificationAuthorID, receiverID int64) error {
func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, notificationAuthorID, receiverID int64) error {
e := db.GetEngine(ctx)
// init
var toNotify map[int64]struct{}
notifications, err := getNotificationsByIssueID(e, issueID)
@ -251,7 +253,7 @@ func createOrUpdateIssueNotifications(e db.Engine, issueID, commentID, notificat
}
}
err = issue.loadRepo(e)
err = issue.loadRepo(ctx)
if err != nil {
return err
}
@ -267,10 +269,10 @@ func createOrUpdateIssueNotifications(e db.Engine, issueID, commentID, notificat
return err
}
if issue.IsPull && !issue.Repo.checkUnitUser(e, user, unit.TypePullRequests) {
if issue.IsPull && !checkRepoUnitUser(ctx, issue.Repo, user, unit.TypePullRequests) {
continue
}
if !issue.IsPull && !issue.Repo.checkUnitUser(e, user, unit.TypeIssues) {
if !issue.IsPull && !checkRepoUnitUser(ctx, issue.Repo, user, unit.TypeIssues) {
continue
}
@ -399,7 +401,7 @@ func (n *Notification) LoadAttributes() (err error) {
func (n *Notification) loadAttributes(ctx context.Context) (err error) {
e := db.GetEngine(ctx)
if err = n.loadRepo(e); err != nil {
if err = n.loadRepo(ctx); err != nil {
return
}
if err = n.loadIssue(ctx); err != nil {
@ -414,9 +416,9 @@ func (n *Notification) loadAttributes(ctx context.Context) (err error) {
return
}
func (n *Notification) loadRepo(e db.Engine) (err error) {
func (n *Notification) loadRepo(ctx context.Context) (err error) {
if n.Repository == nil {
n.Repository, err = getRepositoryByID(e, n.RepoID)
n.Repository, err = repo_model.GetRepositoryByIDCtx(ctx, n.RepoID)
if err != nil {
return fmt.Errorf("getRepositoryByID [%d]: %v", n.RepoID, err)
}
@ -462,8 +464,8 @@ func (n *Notification) loadUser(e db.Engine) (err error) {
}
// GetRepo returns the repo of the notification
func (n *Notification) GetRepo() (*Repository, error) {
return n.Repository, n.loadRepo(db.GetEngine(db.DefaultContext))
func (n *Notification) GetRepo() (*repo_model.Repository, error) {
return n.Repository, n.loadRepo(db.DefaultContext)
}
// GetIssue returns the issue of the notification
@ -526,7 +528,7 @@ func (nl NotificationList) LoadRepos() (RepositoryList, []int, error) {
}
repoIDs := nl.getPendingRepoIDs()
repos := make(map[int64]*Repository, len(repoIDs))
repos := make(map[int64]*repo_model.Repository, len(repoIDs))
left := len(repoIDs)
for left > 0 {
limit := defaultMaxInSize
@ -535,13 +537,13 @@ func (nl NotificationList) LoadRepos() (RepositoryList, []int, error) {
}
rows, err := db.GetEngine(db.DefaultContext).
In("id", repoIDs[:limit]).
Rows(new(Repository))
Rows(new(repo_model.Repository))
if err != nil {
return nil, nil, err
}
for rows.Next() {
var repo Repository
var repo repo_model.Repository
err = rows.Scan(&repo)
if err != nil {
rows.Close()

View file

@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
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"
@ -904,8 +905,8 @@ func (org *Organization) GetUserTeams(userID int64) ([]*Team, error) {
type AccessibleReposEnvironment interface {
CountRepos() (int64, error)
RepoIDs(page, pageSize int) ([]int64, error)
Repos(page, pageSize int) ([]*Repository, error)
MirrorRepos() ([]*Repository, error)
Repos(page, pageSize int) ([]*repo_model.Repository, error)
MirrorRepos() ([]*repo_model.Repository, error)
AddKeyword(keyword string)
SetSort(db.SearchOrderBy)
}
@ -987,7 +988,7 @@ func (env *accessibleReposEnv) CountRepos() (int64, error) {
Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
Where(env.cond()).
Distinct("`repository`.id").
Count(&Repository{})
Count(&repo_model.Repository{})
if err != nil {
return 0, fmt.Errorf("count user repositories in organization: %v", err)
}
@ -1011,13 +1012,13 @@ func (env *accessibleReposEnv) RepoIDs(page, pageSize int) ([]int64, error) {
Find(&repoIDs)
}
func (env *accessibleReposEnv) Repos(page, pageSize int) ([]*Repository, error) {
func (env *accessibleReposEnv) Repos(page, pageSize int) ([]*repo_model.Repository, error) {
repoIDs, err := env.RepoIDs(page, pageSize)
if err != nil {
return nil, fmt.Errorf("GetUserRepositoryIDs: %v", err)
}
repos := make([]*Repository, 0, len(repoIDs))
repos := make([]*repo_model.Repository, 0, len(repoIDs))
if len(repoIDs) == 0 {
return repos, nil
}
@ -1040,13 +1041,13 @@ func (env *accessibleReposEnv) MirrorRepoIDs() ([]int64, error) {
Find(&repoIDs)
}
func (env *accessibleReposEnv) MirrorRepos() ([]*Repository, error) {
func (env *accessibleReposEnv) MirrorRepos() ([]*repo_model.Repository, error) {
repoIDs, err := env.MirrorRepoIDs()
if err != nil {
return nil, fmt.Errorf("MirrorRepoIDs: %v", err)
}
repos := make([]*Repository, 0, len(repoIDs))
repos := make([]*repo_model.Repository, 0, len(repoIDs))
if len(repoIDs) == 0 {
return repos, nil
}

View file

@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
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"
@ -32,8 +33,8 @@ type Team struct {
Name string
Description string
Authorize perm.AccessMode
Repos []*Repository `xorm:"-"`
Members []*user_model.User `xorm:"-"`
Repos []*repo_model.Repository `xorm:"-"`
Members []*user_model.User `xorm:"-"`
NumRepos int
NumMembers int
Units []*TeamUnit `xorm:"-"`
@ -215,7 +216,8 @@ func (t *Team) HasRepository(repoID int64) bool {
return t.hasRepository(db.GetEngine(db.DefaultContext), repoID)
}
func (t *Team) addRepository(e db.Engine, repo *Repository) (err error) {
func (t *Team) addRepository(ctx context.Context, repo *repo_model.Repository) (err error) {
e := db.GetEngine(ctx)
if err = addTeamRepo(e, t.OrgID, t.ID, repo.ID); err != nil {
return err
}
@ -226,7 +228,7 @@ func (t *Team) addRepository(e db.Engine, repo *Repository) (err error) {
t.NumRepos++
if err = repo.recalculateTeamAccesses(e, 0); err != nil {
if err = recalculateTeamAccesses(ctx, repo, 0); err != nil {
return fmt.Errorf("recalculateAccesses: %v", err)
}
@ -247,15 +249,16 @@ func (t *Team) addRepository(e db.Engine, repo *Repository) (err error) {
// addAllRepositories adds all repositories to the team.
// If the team already has some repositories they will be left unchanged.
func (t *Team) addAllRepositories(e db.Engine) error {
var orgRepos []Repository
func (t *Team) addAllRepositories(ctx context.Context) error {
var orgRepos []repo_model.Repository
e := db.GetEngine(ctx)
if err := e.Where("owner_id = ?", t.OrgID).Find(&orgRepos); err != nil {
return fmt.Errorf("get org repos: %v", err)
}
for _, repo := range orgRepos {
if !t.hasRepository(e, repo.ID) {
if err := t.addRepository(e, &repo); err != nil {
if err := t.addRepository(ctx, &repo); err != nil {
return fmt.Errorf("addRepository: %v", err)
}
}
@ -272,7 +275,7 @@ func (t *Team) AddAllRepositories() (err error) {
}
defer committer.Close()
if err = t.addAllRepositories(db.GetEngine(ctx)); err != nil {
if err = t.addAllRepositories(ctx); err != nil {
return err
}
@ -280,7 +283,7 @@ func (t *Team) AddAllRepositories() (err error) {
}
// AddRepository adds new repository to team of organization.
func (t *Team) AddRepository(repo *Repository) (err error) {
func (t *Team) AddRepository(repo *repo_model.Repository) (err error) {
if repo.OwnerID != t.OrgID {
return errors.New("Repository does not belong to organization")
} else if t.HasRepository(repo.ID) {
@ -293,7 +296,7 @@ func (t *Team) AddRepository(repo *Repository) (err error) {
}
defer committer.Close()
if err = t.addRepository(db.GetEngine(ctx), repo); err != nil {
if err = t.addRepository(ctx, repo); err != nil {
return err
}
@ -312,7 +315,7 @@ func (t *Team) RemoveAllRepositories() (err error) {
}
defer committer.Close()
if err = t.removeAllRepositories(db.GetEngine(ctx)); err != nil {
if err = t.removeAllRepositories(ctx); err != nil {
return err
}
@ -321,16 +324,17 @@ func (t *Team) RemoveAllRepositories() (err error) {
// removeAllRepositories removes all repositories from team and recalculates access
// Note: Shall not be called if team includes all repositories
func (t *Team) removeAllRepositories(e db.Engine) (err error) {
func (t *Team) removeAllRepositories(ctx context.Context) (err error) {
e := db.GetEngine(ctx)
// Delete all accesses.
for _, repo := range t.Repos {
if err := repo.recalculateTeamAccesses(e, t.ID); err != nil {
if err := recalculateTeamAccesses(ctx, repo, t.ID); err != nil {
return err
}
// Remove watches from all users and now unaccessible repos
for _, user := range t.Members {
has, err := hasAccess(e, user.ID, repo)
has, err := hasAccess(ctx, user.ID, repo)
if err != nil {
return err
} else if has {
@ -365,7 +369,8 @@ func (t *Team) removeAllRepositories(e db.Engine) (err error) {
// removeRepository removes a repository from a team and recalculates access
// Note: Repository shall not be removed from team if it includes all repositories (unless the repository is deleted)
func (t *Team) removeRepository(e db.Engine, repo *Repository, recalculate bool) (err error) {
func (t *Team) removeRepository(ctx context.Context, repo *repo_model.Repository, recalculate bool) (err error) {
e := db.GetEngine(ctx)
if err = removeTeamRepo(e, t.ID, repo.ID); err != nil {
return err
}
@ -377,7 +382,7 @@ func (t *Team) removeRepository(e db.Engine, repo *Repository, recalculate bool)
// Don't need to recalculate when delete a repository from organization.
if recalculate {
if err = repo.recalculateTeamAccesses(e, t.ID); err != nil {
if err = recalculateTeamAccesses(ctx, repo, t.ID); err != nil {
return err
}
}
@ -387,7 +392,7 @@ func (t *Team) removeRepository(e db.Engine, repo *Repository, recalculate bool)
return fmt.Errorf("getTeamUsersByTeamID: %v", err)
}
for _, teamUser := range teamUsers {
has, err := hasAccess(e, teamUser.UID, repo)
has, err := hasAccess(ctx, teamUser.UID, repo)
if err != nil {
return err
} else if has {
@ -418,7 +423,7 @@ func (t *Team) RemoveRepository(repoID int64) error {
return nil
}
repo, err := GetRepositoryByID(repoID)
repo, err := repo_model.GetRepositoryByID(repoID)
if err != nil {
return err
}
@ -429,7 +434,7 @@ func (t *Team) RemoveRepository(repoID int64) error {
}
defer committer.Close()
if err = t.removeRepository(db.GetEngine(ctx), repo, true); err != nil {
if err = t.removeRepository(ctx, repo, true); err != nil {
return err
}
@ -517,7 +522,7 @@ func NewTeam(t *Team) (err error) {
// Add all repositories to the team if it has access to all of them.
if t.IncludesAllRepositories {
err = t.addAllRepositories(db.GetEngine(ctx))
err = t.addAllRepositories(ctx)
if err != nil {
return fmt.Errorf("addAllRepositories: %v", err)
}
@ -660,7 +665,7 @@ func UpdateTeam(t *Team, authChanged, includeAllChanged bool) (err error) {
}
for _, repo := range t.Repos {
if err = repo.recalculateTeamAccesses(sess, 0); err != nil {
if err = recalculateTeamAccesses(ctx, repo, 0); err != nil {
return fmt.Errorf("recalculateTeamAccesses: %v", err)
}
}
@ -668,7 +673,7 @@ func UpdateTeam(t *Team, authChanged, includeAllChanged bool) (err error) {
// Add all repositories to the team if it has access to all of them.
if includeAllChanged && t.IncludesAllRepositories {
err = t.addAllRepositories(sess)
err = t.addAllRepositories(ctx)
if err != nil {
return fmt.Errorf("addAllRepositories: %v", err)
}
@ -695,7 +700,7 @@ func DeleteTeam(t *Team) error {
return err
}
if err := t.removeAllRepositories(sess); err != nil {
if err := t.removeAllRepositories(ctx); err != nil {
return err
}
@ -848,7 +853,7 @@ func AddTeamMember(team *Team, userID int64) error {
// Give access to team repositories.
for _, repo := range team.Repos {
if err := repo.recalculateUserAccess(sess, userID); err != nil {
if err := recalculateUserAccess(ctx, repo, userID); err != nil {
return err
}
if setting.Service.AutoWatchNewRepos {
@ -894,17 +899,17 @@ func removeTeamMember(ctx context.Context, team *Team, userID int64) error {
// Delete access to team repositories.
for _, repo := range team.Repos {
if err := repo.recalculateUserAccess(e, userID); err != nil {
if err := recalculateUserAccess(ctx, repo, userID); err != nil {
return err
}
// Remove watches from now unaccessible
if err := repo.reconsiderWatches(e, userID); err != nil {
if err := reconsiderWatches(ctx, repo, userID); err != nil {
return err
}
// Remove issue assignments from now unaccessible
if err := repo.reconsiderIssueAssignees(e, userID); err != nil {
if err := reconsiderRepoIssuesAssignee(ctx, repo, userID); err != nil {
return err
}
}

View file

@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@ -124,18 +125,18 @@ func TestTeam_AddRepository(t *testing.T) {
testSuccess := func(teamID, repoID int64) {
team := unittest.AssertExistsAndLoadBean(t, &Team{ID: teamID}).(*Team)
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
assert.NoError(t, team.AddRepository(repo))
unittest.AssertExistsAndLoadBean(t, &TeamRepo{TeamID: teamID, RepoID: repoID})
unittest.CheckConsistencyFor(t, &Team{ID: teamID}, &Repository{ID: repoID})
unittest.CheckConsistencyFor(t, &Team{ID: teamID}, &repo_model.Repository{ID: repoID})
}
testSuccess(2, 3)
testSuccess(2, 5)
team := unittest.AssertExistsAndLoadBean(t, &Team{ID: 1}).(*Team)
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
assert.Error(t, team.AddRepository(repo))
unittest.CheckConsistencyFor(t, &Team{ID: 1}, &Repository{ID: 1})
unittest.CheckConsistencyFor(t, &Team{ID: 1}, &repo_model.Repository{ID: 1})
}
func TestTeam_RemoveRepository(t *testing.T) {
@ -145,7 +146,7 @@ func TestTeam_RemoveRepository(t *testing.T) {
team := unittest.AssertExistsAndLoadBean(t, &Team{ID: teamID}).(*Team)
assert.NoError(t, team.RemoveRepository(repoID))
unittest.AssertNotExistsBean(t, &TeamRepo{TeamID: teamID, RepoID: repoID})
unittest.CheckConsistencyFor(t, &Team{ID: teamID}, &Repository{ID: repoID})
unittest.CheckConsistencyFor(t, &Team{ID: teamID}, &repo_model.Repository{ID: repoID})
}
testSuccess(2, 3)
testSuccess(2, 5)
@ -247,7 +248,7 @@ func TestDeleteTeam(t *testing.T) {
// check that team members don't have "leftover" access to repos
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
accessMode, err := AccessLevel(user, repo)
assert.NoError(t, err)
assert.True(t, accessMode < perm.AccessModeWrite)

View file

@ -8,6 +8,7 @@ import (
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
@ -160,13 +161,13 @@ func TestUser_RemoveMember(t *testing.T) {
func TestUser_RemoveOrgRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization)
repo := unittest.AssertExistsAndLoadBean(t, &Repository{OwnerID: org.ID}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: org.ID}).(*repo_model.Repository)
// remove a repo that does belong to org
unittest.AssertExistsAndLoadBean(t, &TeamRepo{RepoID: repo.ID, OrgID: org.ID})
assert.NoError(t, org.RemoveOrgRepo(repo.ID))
unittest.AssertNotExistsBean(t, &TeamRepo{RepoID: repo.ID, OrgID: org.ID})
unittest.AssertExistsAndLoadBean(t, &Repository{ID: repo.ID}) // repo should still exist
unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID}) // repo should still exist
// remove a repo that does not belong to org
assert.NoError(t, org.RemoveOrgRepo(repo.ID))
@ -177,7 +178,7 @@ func TestUser_RemoveOrgRepo(t *testing.T) {
unittest.CheckConsistencyFor(t,
&user_model.User{ID: org.ID},
&Team{OrgID: org.ID},
&Repository{ID: repo.ID})
&repo_model.Repository{ID: repo.ID})
}
func TestCreateOrganization(t *testing.T) {
@ -541,10 +542,10 @@ func TestAccessibleReposEnv_Repos(t *testing.T) {
assert.NoError(t, err)
repos, err := env.Repos(1, 100)
assert.NoError(t, err)
expectedRepos := make([]*Repository, len(expectedRepoIDs))
expectedRepos := make([]*repo_model.Repository, len(expectedRepoIDs))
for i, repoID := range expectedRepoIDs {
expectedRepos[i] = unittest.AssertExistsAndLoadBean(t,
&Repository{ID: repoID}).(*Repository)
&repo_model.Repository{ID: repoID}).(*repo_model.Repository)
}
assert.Equal(t, expectedRepos, repos)
}
@ -560,10 +561,10 @@ func TestAccessibleReposEnv_MirrorRepos(t *testing.T) {
assert.NoError(t, err)
repos, err := env.MirrorRepos()
assert.NoError(t, err)
expectedRepos := make([]*Repository, len(expectedRepoIDs))
expectedRepos := make([]*repo_model.Repository, len(expectedRepoIDs))
for i, repoID := range expectedRepoIDs {
expectedRepos[i] = unittest.AssertExistsAndLoadBean(t,
&Repository{ID: repoID}).(*Repository)
&repo_model.Repository{ID: repoID}).(*repo_model.Repository)
}
assert.Equal(t, expectedRepos, repos)
}

View file

@ -154,7 +154,7 @@ func addUpdateIssueProject(ctx context.Context, issue *Issue, doer *user_model.U
return err
}
if err := issue.loadRepo(e); err != nil {
if err := issue.loadRepo(ctx); err != nil {
return err
}

View file

@ -33,6 +33,28 @@ func init() {
db.RegisterModel(new(ProtectedTag))
}
// EnsureCompiledPattern ensures the glob pattern is compiled
func (pt *ProtectedTag) EnsureCompiledPattern() error {
if pt.RegexPattern != nil || pt.GlobPattern != nil {
return nil
}
var err error
if len(pt.NamePattern) >= 2 && strings.HasPrefix(pt.NamePattern, "/") && strings.HasSuffix(pt.NamePattern, "/") {
pt.RegexPattern, err = regexp.Compile(pt.NamePattern[1 : len(pt.NamePattern)-1])
} else {
pt.GlobPattern, err = glob.Compile(pt.NamePattern)
}
return err
}
func (pt *ProtectedTag) matchString(name string) bool {
if pt.RegexPattern != nil {
return pt.RegexPattern.MatchString(name)
}
return pt.GlobPattern.Match(name)
}
// InsertProtectedTag inserts a protected tag to database
func InsertProtectedTag(pt *ProtectedTag) error {
_, err := db.GetEngine(db.DefaultContext).Insert(pt)
@ -51,23 +73,8 @@ func DeleteProtectedTag(pt *ProtectedTag) error {
return err
}
// EnsureCompiledPattern ensures the glob pattern is compiled
func (pt *ProtectedTag) EnsureCompiledPattern() error {
if pt.RegexPattern != nil || pt.GlobPattern != nil {
return nil
}
var err error
if len(pt.NamePattern) >= 2 && strings.HasPrefix(pt.NamePattern, "/") && strings.HasSuffix(pt.NamePattern, "/") {
pt.RegexPattern, err = regexp.Compile(pt.NamePattern[1 : len(pt.NamePattern)-1])
} else {
pt.GlobPattern, err = glob.Compile(pt.NamePattern)
}
return err
}
// IsUserAllowed returns true if the user is allowed to modify the tag
func (pt *ProtectedTag) IsUserAllowed(userID int64) (bool, error) {
// IsUserAllowedModifyTag returns true if the user is allowed to modify the tag
func IsUserAllowedModifyTag(pt *ProtectedTag, userID int64) (bool, error) {
if base.Int64sContains(pt.AllowlistUserIDs, userID) {
return true, nil
}
@ -84,9 +91,9 @@ func (pt *ProtectedTag) IsUserAllowed(userID int64) (bool, error) {
}
// GetProtectedTags gets all protected tags of the repository
func (repo *Repository) GetProtectedTags() ([]*ProtectedTag, error) {
func GetProtectedTags(repoID int64) ([]*ProtectedTag, error) {
tags := make([]*ProtectedTag, 0)
return tags, db.GetEngine(db.DefaultContext).Find(&tags, &ProtectedTag{RepoID: repo.ID})
return tags, db.GetEngine(db.DefaultContext).Find(&tags, &ProtectedTag{RepoID: repoID})
}
// GetProtectedTagByID gets the protected tag with the specific id
@ -116,7 +123,7 @@ func IsUserAllowedToControlTag(tags []*ProtectedTag, tagName string, userID int6
continue
}
isAllowed, err = tag.IsUserAllowed(userID)
isAllowed, err = IsUserAllowedModifyTag(tag, userID)
if err != nil {
return false, err
}
@ -127,10 +134,3 @@ func IsUserAllowedToControlTag(tags []*ProtectedTag, tagName string, userID int6
return isAllowed, nil
}
func (pt *ProtectedTag) matchString(name string) bool {
if pt.RegexPattern != nil {
return pt.RegexPattern.MatchString(name)
}
return pt.GlobPattern.Match(name)
}

View file

@ -16,29 +16,29 @@ func TestIsUserAllowed(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
pt := &ProtectedTag{}
allowed, err := pt.IsUserAllowed(1)
allowed, err := IsUserAllowedModifyTag(pt, 1)
assert.NoError(t, err)
assert.False(t, allowed)
pt = &ProtectedTag{
AllowlistUserIDs: []int64{1},
}
allowed, err = pt.IsUserAllowed(1)
allowed, err = IsUserAllowedModifyTag(pt, 1)
assert.NoError(t, err)
assert.True(t, allowed)
allowed, err = pt.IsUserAllowed(2)
allowed, err = IsUserAllowedModifyTag(pt, 2)
assert.NoError(t, err)
assert.False(t, allowed)
pt = &ProtectedTag{
AllowlistTeamIDs: []int64{1},
}
allowed, err = pt.IsUserAllowed(1)
allowed, err = IsUserAllowedModifyTag(pt, 1)
assert.NoError(t, err)
assert.False(t, allowed)
allowed, err = pt.IsUserAllowed(2)
allowed, err = IsUserAllowedModifyTag(pt, 2)
assert.NoError(t, err)
assert.True(t, allowed)
@ -46,11 +46,11 @@ func TestIsUserAllowed(t *testing.T) {
AllowlistUserIDs: []int64{1},
AllowlistTeamIDs: []int64{1},
}
allowed, err = pt.IsUserAllowed(1)
allowed, err = IsUserAllowedModifyTag(pt, 1)
assert.NoError(t, err)
assert.True(t, allowed)
allowed, err = pt.IsUserAllowed(2)
allowed, err = IsUserAllowedModifyTag(pt, 2)
assert.NoError(t, err)
assert.True(t, allowed)
}

View file

@ -6,11 +6,13 @@
package models
import (
"context"
"fmt"
"io"
"strings"
"code.gitea.io/gitea/models/db"
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/git"
@ -67,10 +69,10 @@ type PullRequest struct {
Issue *Issue `xorm:"-"`
Index int64
HeadRepoID int64 `xorm:"INDEX"`
HeadRepo *Repository `xorm:"-"`
BaseRepoID int64 `xorm:"INDEX"`
BaseRepo *Repository `xorm:"-"`
HeadRepoID int64 `xorm:"INDEX"`
HeadRepo *repo_model.Repository `xorm:"-"`
BaseRepoID int64 `xorm:"INDEX"`
BaseRepo *repo_model.Repository `xorm:"-"`
HeadBranch string
HeadCommitID string `xorm:"-"`
BaseBranch string
@ -95,7 +97,7 @@ func init() {
// MustHeadUserName returns the HeadRepo's username if failed return blank
func (pr *PullRequest) MustHeadUserName() string {
if err := pr.LoadHeadRepo(); err != nil {
if !IsErrRepoNotExist(err) {
if !repo_model.IsErrRepoNotExist(err) {
log.Error("LoadHeadRepo: %v", err)
} else {
log.Warn("LoadHeadRepo %d but repository does not exist: %v", pr.HeadRepoID, err)
@ -128,7 +130,7 @@ func (pr *PullRequest) LoadAttributes() error {
return pr.loadAttributes(db.GetEngine(db.DefaultContext))
}
func (pr *PullRequest) loadHeadRepo(e db.Engine) (err error) {
func (pr *PullRequest) loadHeadRepo(ctx context.Context) (err error) {
if !pr.isHeadRepoLoaded && pr.HeadRepo == nil && pr.HeadRepoID > 0 {
if pr.HeadRepoID == pr.BaseRepoID {
if pr.BaseRepo != nil {
@ -140,8 +142,8 @@ func (pr *PullRequest) loadHeadRepo(e db.Engine) (err error) {
}
}
pr.HeadRepo, err = getRepositoryByID(e, pr.HeadRepoID)
if err != nil && !IsErrRepoNotExist(err) { // Head repo maybe deleted, but it should still work
pr.HeadRepo, err = repo_model.GetRepositoryByIDCtx(ctx, pr.HeadRepoID)
if err != nil && !repo_model.IsErrRepoNotExist(err) { // Head repo maybe deleted, but it should still work
return fmt.Errorf("getRepositoryByID(head): %v", err)
}
pr.isHeadRepoLoaded = true
@ -151,15 +153,15 @@ func (pr *PullRequest) loadHeadRepo(e db.Engine) (err error) {
// LoadHeadRepo loads the head repository
func (pr *PullRequest) LoadHeadRepo() error {
return pr.loadHeadRepo(db.GetEngine(db.DefaultContext))
return pr.loadHeadRepo(db.DefaultContext)
}
// LoadBaseRepo loads the target repository
func (pr *PullRequest) LoadBaseRepo() error {
return pr.loadBaseRepo(db.GetEngine(db.DefaultContext))
return pr.loadBaseRepo(db.DefaultContext)
}
func (pr *PullRequest) loadBaseRepo(e db.Engine) (err error) {
func (pr *PullRequest) loadBaseRepo(ctx context.Context) (err error) {
if pr.BaseRepo != nil {
return nil
}
@ -174,9 +176,9 @@ func (pr *PullRequest) loadBaseRepo(e db.Engine) (err error) {
return nil
}
pr.BaseRepo, err = getRepositoryByID(e, pr.BaseRepoID)
pr.BaseRepo, err = repo_model.GetRepositoryByIDCtx(ctx, pr.BaseRepoID)
if err != nil {
return fmt.Errorf("GetRepositoryByID(base): %v", err)
return fmt.Errorf("repo_model.GetRepositoryByID(base): %v", err)
}
return nil
}
@ -200,21 +202,21 @@ func (pr *PullRequest) loadIssue(e db.Engine) (err error) {
// LoadProtectedBranch loads the protected branch of the base branch
func (pr *PullRequest) LoadProtectedBranch() (err error) {
return pr.loadProtectedBranch(db.GetEngine(db.DefaultContext))
return pr.loadProtectedBranch(db.DefaultContext)
}
func (pr *PullRequest) loadProtectedBranch(e db.Engine) (err error) {
func (pr *PullRequest) loadProtectedBranch(ctx context.Context) (err error) {
if pr.ProtectedBranch == nil {
if pr.BaseRepo == nil {
if pr.BaseRepoID == 0 {
return nil
}
pr.BaseRepo, err = getRepositoryByID(e, pr.BaseRepoID)
pr.BaseRepo, err = repo_model.GetRepositoryByIDCtx(ctx, pr.BaseRepoID)
if err != nil {
return
}
}
pr.ProtectedBranch, err = getProtectedBranchBy(e, pr.BaseRepo.ID, pr.BaseBranch)
pr.ProtectedBranch, err = getProtectedBranchBy(db.GetEngine(ctx), pr.BaseRepo.ID, pr.BaseBranch)
}
return
}
@ -223,7 +225,7 @@ func (pr *PullRequest) loadProtectedBranch(e db.Engine) (err error) {
func (pr *PullRequest) GetDefaultMergeMessage() string {
if pr.HeadRepo == nil {
var err error
pr.HeadRepo, err = GetRepositoryByID(pr.HeadRepoID)
pr.HeadRepo, err = repo_model.GetRepositoryByID(pr.HeadRepoID)
if err != nil {
log.Error("GetRepositoryById[%d]: %v", pr.HeadRepoID, err)
return ""
@ -368,24 +370,6 @@ func (pr *PullRequest) IsEmpty() bool {
return pr.Status == PullRequestStatusEmpty
}
// MergeStyle represents the approach to merge commits into base branch.
type MergeStyle string
const (
// MergeStyleMerge create merge commit
MergeStyleMerge MergeStyle = "merge"
// MergeStyleRebase rebase before merging
MergeStyleRebase MergeStyle = "rebase"
// MergeStyleRebaseMerge rebase before merging with merge commit (--no-ff)
MergeStyleRebaseMerge MergeStyle = "rebase-merge"
// MergeStyleSquash squash commits into single commit before merging
MergeStyleSquash MergeStyle = "squash"
// MergeStyleManuallyMerged pr has been merged manually, just mark it as merged directly
MergeStyleManuallyMerged MergeStyle = "manually-merged"
// MergeStyleRebaseUpdate not a merge style, used to update pull head by rebase
MergeStyleRebaseUpdate MergeStyle = "rebase-update-only"
)
// SetMerged sets a pull request to merged and closes the corresponding issue
func (pr *PullRequest) SetMerged() (bool, error) {
if pr.HasMerged {
@ -428,11 +412,11 @@ func (pr *PullRequest) SetMerged() (bool, error) {
return false, fmt.Errorf("PullRequest[%d] already closed", pr.Index)
}
if err := pr.Issue.loadRepo(sess); err != nil {
if err := pr.Issue.loadRepo(ctx); err != nil {
return false, err
}
if err := pr.Issue.Repo.getOwner(sess); err != nil {
if err := pr.Issue.Repo.GetOwner(ctx); err != nil {
return false, err
}
@ -452,7 +436,7 @@ func (pr *PullRequest) SetMerged() (bool, error) {
}
// NewPullRequest creates new pull request with labels for repository.
func NewPullRequest(repo *Repository, issue *Issue, labelIDs []int64, uuids []string, pr *PullRequest) (err error) {
func NewPullRequest(repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string, pr *PullRequest) (err error) {
idx, err := db.GetNextResourceIndex("issue_index", repo.ID)
if err != nil {
return fmt.Errorf("generate pull request index failed: %v", err)

View file

@ -8,6 +8,7 @@ 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"
user_model "code.gitea.io/gitea/models/user"
@ -258,15 +259,15 @@ func TestPullRequest_GetDefaultMergeMessage_InternalTracker(t *testing.T) {
func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
externalTracker := RepoUnit{
externalTracker := repo_model.RepoUnit{
Type: unit.TypeExternalTracker,
Config: &ExternalTrackerConfig{
Config: &repo_model.ExternalTrackerConfig{
ExternalTrackerFormat: "https://someurl.com/{user}/{repo}/{issue}",
},
}
baseRepo := &Repository{Name: "testRepo", ID: 1}
baseRepo := &repo_model.Repository{Name: "testRepo", ID: 1}
baseRepo.Owner = &user_model.User{Name: "testOwner"}
baseRepo.Units = []*RepoUnit{&externalTracker}
baseRepo.Units = []*repo_model.RepoUnit{&externalTracker}
pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 2, BaseRepo: baseRepo}).(*PullRequest)

View file

@ -25,12 +25,12 @@ import (
// Release represents a release of repository.
type Release struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX UNIQUE(n)"`
Repo *Repository `xorm:"-"`
PublisherID int64 `xorm:"INDEX"`
Publisher *user_model.User `xorm:"-"`
TagName string `xorm:"INDEX UNIQUE(n)"`
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX UNIQUE(n)"`
Repo *repo_model.Repository `xorm:"-"`
PublisherID int64 `xorm:"INDEX"`
Publisher *user_model.User `xorm:"-"`
TagName string `xorm:"INDEX UNIQUE(n)"`
OriginalAuthor string
OriginalAuthorID int64 `xorm:"index"`
LowerTagName string
@ -55,7 +55,7 @@ func init() {
func (r *Release) loadAttributes(e db.Engine) error {
var err error
if r.Repo == nil {
r.Repo, err = GetRepositoryByID(r.RepoID)
r.Repo, err = repo_model.GetRepositoryByID(r.RepoID)
if err != nil {
return err
}

File diff suppressed because it is too large Load diff

94
models/repo/avatar.go Normal file
View file

@ -0,0 +1,94 @@
// 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 (
"fmt"
"image/png"
"io"
"net/url"
"strings"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/avatar"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
)
// CustomAvatarRelativePath returns repository custom avatar file path.
func (repo *Repository) CustomAvatarRelativePath() string {
return repo.Avatar
}
// RelAvatarLink returns a relative link to the repository's avatar.
func (repo *Repository) RelAvatarLink() string {
return repo.relAvatarLink(db.GetEngine(db.DefaultContext))
}
// generateRandomAvatar generates a random avatar for repository.
func generateRandomAvatar(e db.Engine, repo *Repository) error {
idToString := fmt.Sprintf("%d", repo.ID)
seed := idToString
img, err := avatar.RandomImage([]byte(seed))
if err != nil {
return fmt.Errorf("RandomImage: %v", err)
}
repo.Avatar = idToString
if err := storage.SaveFrom(storage.RepoAvatars, repo.CustomAvatarRelativePath(), func(w io.Writer) error {
if err := png.Encode(w, img); err != nil {
log.Error("Encode: %v", err)
}
return err
}); err != nil {
return fmt.Errorf("Failed to create dir %s: %v", repo.CustomAvatarRelativePath(), err)
}
log.Info("New random avatar created for repository: %d", repo.ID)
if _, err := e.ID(repo.ID).Cols("avatar").NoAutoTime().Update(repo); err != nil {
return err
}
return nil
}
func (repo *Repository) relAvatarLink(e db.Engine) string {
// If no avatar - path is empty
avatarPath := repo.CustomAvatarRelativePath()
if len(avatarPath) == 0 {
switch mode := setting.RepoAvatar.Fallback; mode {
case "image":
return setting.RepoAvatar.FallbackImage
case "random":
if err := generateRandomAvatar(e, repo); err != nil {
log.Error("generateRandomAvatar: %v", err)
}
default:
// default behaviour: do not display avatar
return ""
}
}
return setting.AppSubURL + "/repo-avatars/" + url.PathEscape(repo.Avatar)
}
// AvatarLink returns a link to the repository's avatar.
func (repo *Repository) AvatarLink() string {
return repo.avatarLink(db.GetEngine(db.DefaultContext))
}
// avatarLink returns user avatar absolute link.
func (repo *Repository) avatarLink(e db.Engine) string {
link := repo.relAvatarLink(e)
// we only prepend our AppURL to our known (relative, internal) avatar link to get an absolute URL
if strings.HasPrefix(link, "/") && !strings.HasPrefix(link, "//") {
return setting.AppURL + strings.TrimPrefix(link, setting.AppSubURL)[1:]
}
// otherwise, return the link as it is
return link
}

31
models/repo/git.go Normal file
View file

@ -0,0 +1,31 @@
// 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 "code.gitea.io/gitea/models/db"
// MergeStyle represents the approach to merge commits into base branch.
type MergeStyle string
const (
// MergeStyleMerge create merge commit
MergeStyleMerge MergeStyle = "merge"
// MergeStyleRebase rebase before merging
MergeStyleRebase MergeStyle = "rebase"
// MergeStyleRebaseMerge rebase before merging with merge commit (--no-ff)
MergeStyleRebaseMerge MergeStyle = "rebase-merge"
// MergeStyleSquash squash commits into single commit before merging
MergeStyleSquash MergeStyle = "squash"
// MergeStyleManuallyMerged pr has been merged manually, just mark it as merged directly
MergeStyleManuallyMerged MergeStyle = "manually-merged"
// MergeStyleRebaseUpdate not a merge style, used to update pull head by rebase
MergeStyleRebaseUpdate MergeStyle = "rebase-update-only"
)
// UpdateDefaultBranch updates the default branch
func UpdateDefaultBranch(repo *Repository) error {
_, err := db.GetEngine(db.DefaultContext).ID(repo.ID).Cols("default_branch").Update(repo)
return err
}

View file

@ -2,10 +2,14 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
package repo
import (
"context"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
@ -45,3 +49,19 @@ func (repo *Repository) AllowOnlyContributorsToTrackTime() bool {
}
return u.IssuesConfig().AllowOnlyContributorsToTrackTime
}
// IsDependenciesEnabled returns if dependencies are enabled and returns the default setting if not set.
func (repo *Repository) IsDependenciesEnabled() bool {
return repo.IsDependenciesEnabledCtx(db.DefaultContext)
}
// IsDependenciesEnabledCtx returns if dependencies are enabled and returns the default setting if not set.
func (repo *Repository) IsDependenciesEnabledCtx(ctx context.Context) bool {
var u *RepoUnit
var err error
if u, err = repo.getUnit(ctx, unit.TypeIssues); err != nil {
log.Trace("%s", err)
return setting.Service.DefaultEnableDependencies
}
return u.IssuesConfig().EnableDependencies
}

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
package repo
import (
"math"
@ -34,7 +34,8 @@ func init() {
// LanguageStatList defines a list of language statistics
type LanguageStatList []*LanguageStat
func (stats LanguageStatList) loadAttributes() {
// LoadAttributes loads attributes
func (stats LanguageStatList) LoadAttributes() {
for i := range stats {
stats[i].Color = enry.GetColor(stats[i].Language)
}
@ -65,7 +66,7 @@ func (stats LanguageStatList) getLanguagePercentages() map[string]float32 {
return langPerc
}
func (repo *Repository) getLanguageStats(e db.Engine) (LanguageStatList, error) {
func getLanguageStats(e db.Engine, repo *Repository) (LanguageStatList, error) {
stats := make(LanguageStatList, 0, 6)
if err := e.Where("`repo_id` = ?", repo.ID).Desc("`size`").Find(&stats); err != nil {
return nil, err
@ -74,13 +75,13 @@ func (repo *Repository) getLanguageStats(e db.Engine) (LanguageStatList, error)
}
// GetLanguageStats returns the language statistics for a repository
func (repo *Repository) GetLanguageStats() (LanguageStatList, error) {
return repo.getLanguageStats(db.GetEngine(db.DefaultContext))
func GetLanguageStats(repo *Repository) (LanguageStatList, error) {
return getLanguageStats(db.GetEngine(db.DefaultContext), repo)
}
// GetTopLanguageStats returns the top language statistics for a repository
func (repo *Repository) GetTopLanguageStats(limit int) (LanguageStatList, error) {
stats, err := repo.getLanguageStats(db.GetEngine(db.DefaultContext))
func GetTopLanguageStats(repo *Repository, limit int) (LanguageStatList, error) {
stats, err := getLanguageStats(db.GetEngine(db.DefaultContext), repo)
if err != nil {
return nil, err
}
@ -106,12 +107,12 @@ func (repo *Repository) GetTopLanguageStats(limit int) (LanguageStatList, error)
Percentage: float32(math.Round(float64(other)*10) / 10),
})
}
topstats.loadAttributes()
topstats.LoadAttributes()
return topstats, nil
}
// UpdateLanguageStats updates the language statistics for repository
func (repo *Repository) UpdateLanguageStats(commitID string, stats map[string]int64) error {
func UpdateLanguageStats(repo *Repository, commitID string, stats map[string]int64) error {
ctx, committer, err := db.TxContext()
if err != nil {
return err
@ -119,7 +120,7 @@ func (repo *Repository) UpdateLanguageStats(commitID string, stats map[string]in
defer committer.Close()
sess := db.GetEngine(ctx)
oldstats, err := repo.getLanguageStats(sess)
oldstats, err := getLanguageStats(sess, repo)
if err != nil {
return err
}
@ -175,7 +176,7 @@ func (repo *Repository) UpdateLanguageStats(commitID string, stats map[string]in
}
// Update indexer status
if err = repo.updateIndexerStatus(sess, RepoIndexerTypeStats, commitID); err != nil {
if err = updateIndexerStatus(sess, repo, RepoIndexerTypeStats, commitID); err != nil {
return err
}
@ -203,7 +204,7 @@ func CopyLanguageStat(originalRepo, destRepo *Repository) error {
}
// update destRepo's indexer status
tmpCommitID := RepoLang[0].CommitID
if err := destRepo.updateIndexerStatus(sess, RepoIndexerTypeStats, tmpCommitID); err != nil {
if err := updateIndexerStatus(sess, destRepo, RepoIndexerTypeStats, tmpCommitID); err != nil {
return err
}
if _, err := sess.Insert(&RepoLang); err != nil {

View file

@ -15,5 +15,8 @@ func TestMain(m *testing.M) {
unittest.MainTest(m, filepath.Join("..", ".."),
"attachment.yml",
"repo_archiver.yml",
"repository.yml",
"repo_unit.yml",
"repo_indexer_status.yml",
)
}

View file

@ -3,9 +3,11 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
package repo
import (
"errors"
"fmt"
"time"
"code.gitea.io/gitea/models/db"
@ -15,6 +17,11 @@ import (
"xorm.io/xorm"
)
var (
// ErrMirrorNotExist mirror does not exist error
ErrMirrorNotExist = errors.New("Mirror does not exist")
)
// RemoteMirrorer defines base methods for pull/push mirrors.
type RemoteMirrorer interface {
GetRepository() *Repository
@ -128,3 +135,43 @@ func InsertMirror(mirror *Mirror) error {
_, err := db.GetEngine(db.DefaultContext).Insert(mirror)
return err
}
// MirrorRepositoryList contains the mirror repositories
type MirrorRepositoryList []*Repository
func (repos MirrorRepositoryList) loadAttributes(e db.Engine) error {
if len(repos) == 0 {
return nil
}
// Load mirrors.
repoIDs := make([]int64, 0, len(repos))
for i := range repos {
if !repos[i].IsMirror {
continue
}
repoIDs = append(repoIDs, repos[i].ID)
}
mirrors := make([]*Mirror, 0, len(repoIDs))
if err := e.
Where("id > 0").
In("repo_id", repoIDs).
Find(&mirrors); err != nil {
return fmt.Errorf("find mirrors: %v", err)
}
set := make(map[int64]*Mirror)
for i := range mirrors {
set[mirrors[i].RepoID] = mirrors[i]
}
for i := range repos {
repos[i].Mirror = set[repos[i].ID]
}
return nil
}
// LoadAttributes loads the attributes for the given MirrorRepositoryList
func (repos MirrorRepositoryList) LoadAttributes() error {
return repos.loadAttributes(db.GetEngine(db.DefaultContext))
}

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
package repo
import (
"errors"

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
package repo
import (
"testing"

736
models/repo/repo.go Normal file
View file

@ -0,0 +1,736 @@
// 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"
"html/template"
"net"
"net/url"
"path/filepath"
"strconv"
"strings"
"code.gitea.io/gitea/models/db"
"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/markup"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
)
// TrustModelType defines the types of trust model for this repository
type TrustModelType int
// kinds of TrustModel
const (
DefaultTrustModel TrustModelType = iota // default trust model
CommitterTrustModel
CollaboratorTrustModel
CollaboratorCommitterTrustModel
)
// String converts a TrustModelType to a string
func (t TrustModelType) String() string {
switch t {
case DefaultTrustModel:
return "default"
case CommitterTrustModel:
return "committer"
case CollaboratorTrustModel:
return "collaborator"
case CollaboratorCommitterTrustModel:
return "collaboratorcommitter"
}
return "default"
}
// ToTrustModel converts a string to a TrustModelType
func ToTrustModel(model string) TrustModelType {
switch strings.ToLower(strings.TrimSpace(model)) {
case "default":
return DefaultTrustModel
case "collaborator":
return CollaboratorTrustModel
case "committer":
return CommitterTrustModel
case "collaboratorcommitter":
return CollaboratorCommitterTrustModel
}
return DefaultTrustModel
}
// RepositoryStatus defines the status of repository
type RepositoryStatus int
// all kinds of RepositoryStatus
const (
RepositoryReady RepositoryStatus = iota // a normal repository
RepositoryBeingMigrated // repository is migrating
RepositoryPendingTransfer // repository pending in ownership transfer state
RepositoryBroken // repository is in a permanently broken state
)
// Repository represents a git repository.
type Repository struct {
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"UNIQUE(s) index"`
OwnerName string
Owner *user_model.User `xorm:"-"`
LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
Name string `xorm:"INDEX NOT NULL"`
Description string `xorm:"TEXT"`
Website string `xorm:"VARCHAR(2048)"`
OriginalServiceType api.GitServiceType `xorm:"index"`
OriginalURL string `xorm:"VARCHAR(2048)"`
DefaultBranch string
NumWatches int
NumStars int
NumForks int
NumIssues int
NumClosedIssues int
NumOpenIssues int `xorm:"-"`
NumPulls int
NumClosedPulls int
NumOpenPulls int `xorm:"-"`
NumMilestones int `xorm:"NOT NULL DEFAULT 0"`
NumClosedMilestones int `xorm:"NOT NULL DEFAULT 0"`
NumOpenMilestones int `xorm:"-"`
NumProjects int `xorm:"NOT NULL DEFAULT 0"`
NumClosedProjects int `xorm:"NOT NULL DEFAULT 0"`
NumOpenProjects int `xorm:"-"`
IsPrivate bool `xorm:"INDEX"`
IsEmpty bool `xorm:"INDEX"`
IsArchived bool `xorm:"INDEX"`
IsMirror bool `xorm:"INDEX"`
*Mirror `xorm:"-"`
Status RepositoryStatus `xorm:"NOT NULL DEFAULT 0"`
RenderingMetas map[string]string `xorm:"-"`
DocumentRenderingMetas map[string]string `xorm:"-"`
Units []*RepoUnit `xorm:"-"`
PrimaryLanguage *LanguageStat `xorm:"-"`
IsFork bool `xorm:"INDEX NOT NULL DEFAULT false"`
ForkID int64 `xorm:"INDEX"`
BaseRepo *Repository `xorm:"-"`
IsTemplate bool `xorm:"INDEX NOT NULL DEFAULT false"`
TemplateID int64 `xorm:"INDEX"`
Size int64 `xorm:"NOT NULL DEFAULT 0"`
CodeIndexerStatus *RepoIndexerStatus `xorm:"-"`
StatsIndexerStatus *RepoIndexerStatus `xorm:"-"`
IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"`
CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"`
Topics []string `xorm:"TEXT JSON"`
TrustModel TrustModelType
// Avatar: ID(10-20)-md5(32) - must fit into 64 symbols
Avatar string `xorm:"VARCHAR(64)"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
}
func init() {
db.RegisterModel(new(Repository))
}
// SanitizedOriginalURL returns a sanitized OriginalURL
func (repo *Repository) SanitizedOriginalURL() string {
if repo.OriginalURL == "" {
return ""
}
u, err := url.Parse(repo.OriginalURL)
if err != nil {
return ""
}
u.User = nil
return u.String()
}
// ColorFormat returns a colored string to represent this repo
func (repo *Repository) ColorFormat(s fmt.State) {
log.ColorFprintf(s, "%d:%s/%s",
log.NewColoredIDValue(repo.ID),
repo.OwnerName,
repo.Name)
}
// IsBeingMigrated indicates that repository is being migrated
func (repo *Repository) IsBeingMigrated() bool {
return repo.Status == RepositoryBeingMigrated
}
// IsBeingCreated indicates that repository is being migrated or forked
func (repo *Repository) IsBeingCreated() bool {
return repo.IsBeingMigrated()
}
// IsBroken indicates that repository is broken
func (repo *Repository) IsBroken() bool {
return repo.Status == RepositoryBroken
}
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
func (repo *Repository) AfterLoad() {
// FIXME: use models migration to solve all at once.
if len(repo.DefaultBranch) == 0 {
repo.DefaultBranch = setting.Repository.DefaultBranch
}
repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
repo.NumOpenPulls = repo.NumPulls - repo.NumClosedPulls
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects
}
// MustOwner always returns a valid *user_model.User object to avoid
// conceptually impossible error handling.
// It creates a fake object that contains error details
// when error occurs.
func (repo *Repository) MustOwner() *user_model.User {
return repo.mustOwner(db.DefaultContext)
}
// FullName returns the repository full name
func (repo *Repository) FullName() string {
return repo.OwnerName + "/" + repo.Name
}
// HTMLURL returns the repository HTML URL
func (repo *Repository) HTMLURL() string {
return setting.AppURL + url.PathEscape(repo.OwnerName) + "/" + url.PathEscape(repo.Name)
}
// CommitLink make link to by commit full ID
// note: won't check whether it's an right id
func (repo *Repository) CommitLink(commitID string) (result string) {
if commitID == "" || commitID == "0000000000000000000000000000000000000000" {
result = ""
} else {
result = repo.HTMLURL() + "/commit/" + url.PathEscape(commitID)
}
return
}
// APIURL returns the repository API URL
func (repo *Repository) APIURL() string {
return setting.AppURL + "api/v1/repos/" + url.PathEscape(repo.OwnerName) + "/" + url.PathEscape(repo.Name)
}
// GetCommitsCountCacheKey returns cache key used for commits count caching.
func (repo *Repository) GetCommitsCountCacheKey(contextName string, isRef bool) string {
var prefix string
if isRef {
prefix = "ref"
} else {
prefix = "commit"
}
return fmt.Sprintf("commits-count-%d-%s-%s", repo.ID, prefix, contextName)
}
// LoadUnits loads repo units into repo.Units
func (repo *Repository) LoadUnits(ctx context.Context) (err error) {
if repo.Units != nil {
return nil
}
repo.Units, err = getUnitsByRepoID(db.GetEngine(ctx), repo.ID)
log.Trace("repo.Units: %-+v", repo.Units)
return err
}
// UnitEnabled if this repository has the given unit enabled
func (repo *Repository) UnitEnabled(tp unit.Type) bool {
if err := repo.LoadUnits(db.DefaultContext); err != nil {
log.Warn("Error loading repository (ID: %d) units: %s", repo.ID, err.Error())
}
for _, unit := range repo.Units {
if unit.Type == tp {
return true
}
}
return false
}
// MustGetUnit always returns a RepoUnit object
func (repo *Repository) MustGetUnit(tp unit.Type) *RepoUnit {
ru, err := repo.GetUnit(tp)
if err == nil {
return ru
}
if tp == unit.TypeExternalWiki {
return &RepoUnit{
Type: tp,
Config: new(ExternalWikiConfig),
}
} else if tp == unit.TypeExternalTracker {
return &RepoUnit{
Type: tp,
Config: new(ExternalTrackerConfig),
}
} else if tp == unit.TypePullRequests {
return &RepoUnit{
Type: tp,
Config: new(PullRequestsConfig),
}
} else if tp == unit.TypeIssues {
return &RepoUnit{
Type: tp,
Config: new(IssuesConfig),
}
}
return &RepoUnit{
Type: tp,
Config: new(UnitConfig),
}
}
// GetUnit returns a RepoUnit object
func (repo *Repository) GetUnit(tp unit.Type) (*RepoUnit, error) {
return repo.getUnit(db.DefaultContext, tp)
}
func (repo *Repository) getUnit(ctx context.Context, tp unit.Type) (*RepoUnit, error) {
if err := repo.LoadUnits(ctx); err != nil {
return nil, err
}
for _, unit := range repo.Units {
if unit.Type == tp {
return unit, nil
}
}
return nil, ErrUnitTypeNotExist{tp}
}
// GetOwner returns the repository owner
func (repo *Repository) GetOwner(ctx context.Context) (err error) {
if repo.Owner != nil {
return nil
}
repo.Owner, err = user_model.GetUserByIDEngine(db.GetEngine(ctx), repo.OwnerID)
return err
}
func (repo *Repository) mustOwner(ctx context.Context) *user_model.User {
if err := repo.GetOwner(ctx); err != nil {
return &user_model.User{
Name: "error",
FullName: err.Error(),
}
}
return repo.Owner
}
// ComposeMetas composes a map of metas for properly rendering issue links and external issue trackers.
func (repo *Repository) ComposeMetas() map[string]string {
if len(repo.RenderingMetas) == 0 {
metas := map[string]string{
"user": repo.OwnerName,
"repo": repo.Name,
"repoPath": repo.RepoPath(),
"mode": "comment",
}
unit, err := repo.GetUnit(unit.TypeExternalTracker)
if err == nil {
metas["format"] = unit.ExternalTrackerConfig().ExternalTrackerFormat
switch unit.ExternalTrackerConfig().ExternalTrackerStyle {
case markup.IssueNameStyleAlphanumeric:
metas["style"] = markup.IssueNameStyleAlphanumeric
default:
metas["style"] = markup.IssueNameStyleNumeric
}
}
repo.MustOwner()
if repo.Owner.IsOrganization() {
teams := make([]string, 0, 5)
_ = db.GetEngine(db.DefaultContext).Table("team_repo").
Join("INNER", "team", "team.id = team_repo.team_id").
Where("team_repo.repo_id = ?", repo.ID).
Select("team.lower_name").
OrderBy("team.lower_name").
Find(&teams)
metas["teams"] = "," + strings.Join(teams, ",") + ","
metas["org"] = strings.ToLower(repo.OwnerName)
}
repo.RenderingMetas = metas
}
return repo.RenderingMetas
}
// ComposeDocumentMetas composes a map of metas for properly rendering documents
func (repo *Repository) ComposeDocumentMetas() map[string]string {
if len(repo.DocumentRenderingMetas) == 0 {
metas := map[string]string{}
for k, v := range repo.ComposeMetas() {
metas[k] = v
}
metas["mode"] = "document"
repo.DocumentRenderingMetas = metas
}
return repo.DocumentRenderingMetas
}
// GetBaseRepo populates repo.BaseRepo for a fork repository and
// returns an error on failure (NOTE: no error is returned for
// non-fork repositories, and BaseRepo will be left untouched)
func (repo *Repository) GetBaseRepo() (err error) {
return repo.getBaseRepo(db.GetEngine(db.DefaultContext))
}
func (repo *Repository) getBaseRepo(e db.Engine) (err error) {
if !repo.IsFork {
return nil
}
repo.BaseRepo, err = getRepositoryByID(e, repo.ForkID)
return err
}
// IsGenerated returns whether _this_ repository was generated from a template
func (repo *Repository) IsGenerated() bool {
return repo.TemplateID != 0
}
// RepoPath returns repository path by given user and repository name.
func RepoPath(userName, repoName string) string { //revive:disable-line:exported
return filepath.Join(user_model.UserPath(userName), strings.ToLower(repoName)+".git")
}
// RepoPath returns the repository path
func (repo *Repository) RepoPath() string {
return RepoPath(repo.OwnerName, repo.Name)
}
// GitConfigPath returns the path to a repository's git config/ directory
func GitConfigPath(repoPath string) string {
return filepath.Join(repoPath, "config")
}
// GitConfigPath returns the repository git config path
func (repo *Repository) GitConfigPath() string {
return GitConfigPath(repo.RepoPath())
}
// Link returns the repository link
func (repo *Repository) Link() string {
return setting.AppSubURL + "/" + url.PathEscape(repo.OwnerName) + "/" + url.PathEscape(repo.Name)
}
// ComposeCompareURL returns the repository comparison URL
func (repo *Repository) ComposeCompareURL(oldCommitID, newCommitID string) string {
return fmt.Sprintf("%s/%s/compare/%s...%s", url.PathEscape(repo.OwnerName), url.PathEscape(repo.Name), util.PathEscapeSegments(oldCommitID), util.PathEscapeSegments(newCommitID))
}
// IsOwnedBy returns true when user owns this repository
func (repo *Repository) IsOwnedBy(userID int64) bool {
return repo.OwnerID == userID
}
// CanCreateBranch returns true if repository meets the requirements for creating new branches.
func (repo *Repository) CanCreateBranch() bool {
return !repo.IsMirror
}
// CanEnablePulls returns true if repository meets the requirements of accepting pulls.
func (repo *Repository) CanEnablePulls() bool {
return !repo.IsMirror && !repo.IsEmpty
}
// AllowsPulls returns true if repository meets the requirements of accepting pulls and has them enabled.
func (repo *Repository) AllowsPulls() bool {
return repo.CanEnablePulls() && repo.UnitEnabled(unit.TypePullRequests)
}
// CanEnableEditor returns true if repository meets the requirements of web editor.
func (repo *Repository) CanEnableEditor() bool {
return !repo.IsMirror
}
// DescriptionHTML does special handles to description and return HTML string.
func (repo *Repository) DescriptionHTML() template.HTML {
desc, err := markup.RenderDescriptionHTML(&markup.RenderContext{
URLPrefix: repo.HTMLURL(),
Metas: repo.ComposeMetas(),
}, repo.Description)
if err != nil {
log.Error("Failed to render description for %s (ID: %d): %v", repo.Name, repo.ID, err)
return template.HTML(markup.Sanitize(repo.Description))
}
return template.HTML(markup.Sanitize(string(desc)))
}
// CloneLink represents different types of clone URLs of repository.
type CloneLink struct {
SSH string
HTTPS string
Git string
}
// ComposeHTTPSCloneURL returns HTTPS clone URL based on given owner and repository name.
func ComposeHTTPSCloneURL(owner, repo string) string {
return fmt.Sprintf("%s%s/%s.git", setting.AppURL, url.PathEscape(owner), url.PathEscape(repo))
}
func (repo *Repository) cloneLink(isWiki bool) *CloneLink {
repoName := repo.Name
if isWiki {
repoName += ".wiki"
}
sshUser := setting.RunUser
if setting.SSH.StartBuiltinServer {
sshUser = setting.SSH.BuiltinServerUser
}
cl := new(CloneLink)
// if we have a ipv6 literal we need to put brackets around it
// for the git cloning to work.
sshDomain := setting.SSH.Domain
ip := net.ParseIP(setting.SSH.Domain)
if ip != nil && ip.To4() == nil {
sshDomain = "[" + setting.SSH.Domain + "]"
}
if setting.SSH.Port != 22 {
cl.SSH = fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, net.JoinHostPort(setting.SSH.Domain, strconv.Itoa(setting.SSH.Port)), url.PathEscape(repo.OwnerName), url.PathEscape(repoName))
} else if setting.Repository.UseCompatSSHURI {
cl.SSH = fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshDomain, url.PathEscape(repo.OwnerName), url.PathEscape(repoName))
} else {
cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", sshUser, sshDomain, url.PathEscape(repo.OwnerName), url.PathEscape(repoName))
}
cl.HTTPS = ComposeHTTPSCloneURL(repo.OwnerName, repoName)
return cl
}
// CloneLink returns clone URLs of repository.
func (repo *Repository) CloneLink() (cl *CloneLink) {
return repo.cloneLink(false)
}
// GetOriginalURLHostname returns the hostname of a URL or the URL
func (repo *Repository) GetOriginalURLHostname() string {
u, err := url.Parse(repo.OriginalURL)
if err != nil {
return repo.OriginalURL
}
return u.Host
}
// GetTrustModel will get the TrustModel for the repo or the default trust model
func (repo *Repository) GetTrustModel() TrustModelType {
trustModel := repo.TrustModel
if trustModel == DefaultTrustModel {
trustModel = ToTrustModel(setting.Repository.Signing.DefaultTrustModel)
if trustModel == DefaultTrustModel {
return CollaboratorTrustModel
}
}
return trustModel
}
// GetRepositoryByOwnerAndName returns the repository by given ownername and reponame.
func GetRepositoryByOwnerAndName(ownerName, repoName string) (*Repository, error) {
return GetRepositoryByOwnerAndNameCtx(db.DefaultContext, ownerName, repoName)
}
// __________ .__ __
// \______ \ ____ ______ ____ _____|__|/ |_ ___________ ___.__.
// | _// __ \\____ \ / _ \/ ___/ \ __\/ _ \_ __ < | |
// | | \ ___/| |_> > <_> )___ \| || | ( <_> ) | \/\___ |
// |____|_ /\___ > __/ \____/____ >__||__| \____/|__| / ____|
// \/ \/|__| \/ \/
// ErrRepoNotExist represents a "RepoNotExist" kind of error.
type ErrRepoNotExist struct {
ID int64
UID int64
OwnerName string
Name string
}
// IsErrRepoNotExist checks if an error is a ErrRepoNotExist.
func IsErrRepoNotExist(err error) bool {
_, ok := err.(ErrRepoNotExist)
return ok
}
func (err ErrRepoNotExist) Error() string {
return fmt.Sprintf("repository does not exist [id: %d, uid: %d, owner_name: %s, name: %s]",
err.ID, err.UID, err.OwnerName, err.Name)
}
// GetRepositoryByOwnerAndNameCtx returns the repository by given owner name and repo name
func GetRepositoryByOwnerAndNameCtx(ctx context.Context, ownerName, repoName string) (*Repository, error) {
var repo Repository
has, err := db.GetEngine(ctx).Table("repository").Select("repository.*").
Join("INNER", "`user`", "`user`.id = repository.owner_id").
Where("repository.lower_name = ?", strings.ToLower(repoName)).
And("`user`.lower_name = ?", strings.ToLower(ownerName)).
Get(&repo)
if err != nil {
return nil, err
} else if !has {
return nil, ErrRepoNotExist{0, 0, ownerName, repoName}
}
return &repo, nil
}
// GetRepositoryByName returns the repository by given name under user if exists.
func GetRepositoryByName(ownerID int64, name string) (*Repository, error) {
repo := &Repository{
OwnerID: ownerID,
LowerName: strings.ToLower(name),
}
has, err := db.GetEngine(db.DefaultContext).Get(repo)
if err != nil {
return nil, err
} else if !has {
return nil, ErrRepoNotExist{0, ownerID, "", name}
}
return repo, err
}
func getRepositoryByID(e db.Engine, id int64) (*Repository, error) {
repo := new(Repository)
has, err := e.ID(id).Get(repo)
if err != nil {
return nil, err
} else if !has {
return nil, ErrRepoNotExist{id, 0, "", ""}
}
return repo, nil
}
// GetRepositoryByID returns the repository by given id if exists.
func GetRepositoryByID(id int64) (*Repository, error) {
return getRepositoryByID(db.GetEngine(db.DefaultContext), id)
}
// GetRepositoryByIDCtx returns the repository by given id if exists.
func GetRepositoryByIDCtx(ctx context.Context, id int64) (*Repository, error) {
return getRepositoryByID(db.GetEngine(ctx), id)
}
// GetRepositoriesMapByIDs returns the repositories by given id slice.
func GetRepositoriesMapByIDs(ids []int64) (map[int64]*Repository, error) {
repos := make(map[int64]*Repository, len(ids))
return repos, db.GetEngine(db.DefaultContext).In("id", ids).Find(&repos)
}
// IsRepositoryExistCtx returns true if the repository with given name under user has already existed.
func IsRepositoryExistCtx(ctx context.Context, u *user_model.User, repoName string) (bool, error) {
has, err := db.GetEngine(ctx).Get(&Repository{
OwnerID: u.ID,
LowerName: strings.ToLower(repoName),
})
if err != nil {
return false, err
}
isDir, err := util.IsDir(RepoPath(u.Name, repoName))
return has && isDir, err
}
// IsRepositoryExist returns true if the repository with given name under user has already existed.
func IsRepositoryExist(u *user_model.User, repoName string) (bool, error) {
return IsRepositoryExistCtx(db.DefaultContext, u, repoName)
}
// GetTemplateRepo populates repo.TemplateRepo for a generated repository and
// returns an error on failure (NOTE: no error is returned for
// non-generated repositories, and TemplateRepo will be left untouched)
func GetTemplateRepo(repo *Repository) (*Repository, error) {
return getTemplateRepo(db.GetEngine(db.DefaultContext), repo)
}
func getTemplateRepo(e db.Engine, repo *Repository) (*Repository, error) {
if !repo.IsGenerated() {
return nil, nil
}
return getRepositoryByID(e, repo.TemplateID)
}
func countRepositories(userID int64, private bool) int64 {
sess := db.GetEngine(db.DefaultContext).Where("id > 0")
if userID > 0 {
sess.And("owner_id = ?", userID)
}
if !private {
sess.And("is_private=?", false)
}
count, err := sess.Count(new(Repository))
if err != nil {
log.Error("countRepositories: %v", err)
}
return count
}
// CountRepositories returns number of repositories.
// Argument private only takes effect when it is false,
// set it true to count all repositories.
func CountRepositories(private bool) int64 {
return countRepositories(-1, private)
}
// CountUserRepositories returns number of repositories user owns.
// Argument private only takes effect when it is false,
// set it true to count all repositories.
func CountUserRepositories(userID int64, private bool) int64 {
return countRepositories(userID, private)
}
// GetUserMirrorRepositories returns a list of mirror repositories of given user.
func GetUserMirrorRepositories(userID int64) ([]*Repository, error) {
repos := make([]*Repository, 0, 10)
return repos, db.GetEngine(db.DefaultContext).
Where("owner_id = ?", userID).
And("is_mirror = ?", true).
Find(&repos)
}
func getRepositoryCount(e db.Engine, ownerID int64) (int64, error) {
return e.Count(&Repository{OwnerID: ownerID})
}
func getPublicRepositoryCount(e db.Engine, u *user_model.User) (int64, error) {
return e.Where("is_private = ?", false).Count(&Repository{OwnerID: u.ID})
}
func getPrivateRepositoryCount(e db.Engine, u *user_model.User) (int64, error) {
return e.Where("is_private = ?", true).Count(&Repository{OwnerID: u.ID})
}
// GetRepositoryCount returns the total number of repositories of user.
func GetRepositoryCount(ctx context.Context, ownerID int64) (int64, error) {
return getRepositoryCount(db.GetEngine(ctx), ownerID)
}
// GetPublicRepositoryCount returns the total number of public repositories of user.
func GetPublicRepositoryCount(u *user_model.User) (int64, error) {
return getPublicRepositoryCount(db.GetEngine(db.DefaultContext), u)
}
// GetPrivateRepositoryCount returns the total number of private repositories of user.
func GetPrivateRepositoryCount(u *user_model.User) (int64, error) {
return getPrivateRepositoryCount(db.GetEngine(db.DefaultContext), u)
}

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
package repo
import (
"fmt"
@ -13,7 +13,7 @@ import (
)
// RepoIndexerType specifies the repository indexer type
type RepoIndexerType int
type RepoIndexerType int //revive:disable-line:exported
const (
// RepoIndexerTypeCode code indexer
@ -24,7 +24,7 @@ const (
// RepoIndexerStatus status of a repo's entry in the repo indexer
// For now, implicitly refers to default branch
type RepoIndexerStatus struct {
type RepoIndexerStatus struct { //revive:disable-line:exported
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX(s)"`
CommitSha string `xorm:"VARCHAR(40)"`
@ -63,7 +63,7 @@ func GetUnindexedRepos(indexerType RepoIndexerType, maxRepoID int64, page, pageS
}
// getIndexerStatus loads repo codes indxer status
func (repo *Repository) getIndexerStatus(e db.Engine, indexerType RepoIndexerType) (*RepoIndexerStatus, error) {
func getIndexerStatus(e db.Engine, repo *Repository, indexerType RepoIndexerType) (*RepoIndexerStatus, error) {
switch indexerType {
case RepoIndexerTypeCode:
if repo.CodeIndexerStatus != nil {
@ -91,13 +91,13 @@ func (repo *Repository) getIndexerStatus(e db.Engine, indexerType RepoIndexerTyp
}
// GetIndexerStatus loads repo codes indxer status
func (repo *Repository) GetIndexerStatus(indexerType RepoIndexerType) (*RepoIndexerStatus, error) {
return repo.getIndexerStatus(db.GetEngine(db.DefaultContext), indexerType)
func GetIndexerStatus(repo *Repository, indexerType RepoIndexerType) (*RepoIndexerStatus, error) {
return getIndexerStatus(db.GetEngine(db.DefaultContext), repo, indexerType)
}
// updateIndexerStatus updates indexer status
func (repo *Repository) updateIndexerStatus(e db.Engine, indexerType RepoIndexerType, sha string) error {
status, err := repo.getIndexerStatus(e, indexerType)
func updateIndexerStatus(e db.Engine, repo *Repository, indexerType RepoIndexerType, sha string) error {
status, err := getIndexerStatus(e, repo, indexerType)
if err != nil {
return fmt.Errorf("UpdateIndexerStatus: Unable to getIndexerStatus for repo: %s Error: %v", repo.FullName(), err)
}
@ -120,6 +120,6 @@ func (repo *Repository) updateIndexerStatus(e db.Engine, indexerType RepoIndexer
}
// UpdateIndexerStatus updates indexer status
func (repo *Repository) UpdateIndexerStatus(indexerType RepoIndexerType, sha string) error {
return repo.updateIndexerStatus(db.GetEngine(db.DefaultContext), indexerType, sha)
func UpdateIndexerStatus(repo *Repository, indexerType RepoIndexerType, sha string) error {
return updateIndexerStatus(db.GetEngine(db.DefaultContext), repo, indexerType, sha)
}

44
models/repo/repo_test.go Normal file
View file

@ -0,0 +1,44 @@
// Copyright 2017 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 (
"testing"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"github.com/stretchr/testify/assert"
)
func TestGetRepositoryCount(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
count, err1 := GetRepositoryCount(db.DefaultContext, 10)
privateCount, err2 := GetPrivateRepositoryCount(&user_model.User{ID: int64(10)})
publicCount, err3 := GetPublicRepositoryCount(&user_model.User{ID: int64(10)})
assert.NoError(t, err1)
assert.NoError(t, err2)
assert.NoError(t, err3)
assert.Equal(t, int64(3), count)
assert.Equal(t, privateCount+publicCount, count)
}
func TestGetPublicRepositoryCount(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
count, err := GetPublicRepositoryCount(&user_model.User{ID: int64(10)})
assert.NoError(t, err)
assert.Equal(t, int64(1), count)
}
func TestGetPrivateRepositoryCount(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
count, err := GetPrivateRepositoryCount(&user_model.User{ID: int64(10)})
assert.NoError(t, err)
assert.Equal(t, int64(2), count)
}

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
package repo
import (
"fmt"
@ -17,8 +17,23 @@ import (
"xorm.io/xorm/convert"
)
// ErrUnitTypeNotExist represents a "UnitTypeNotExist" kind of error.
type ErrUnitTypeNotExist struct {
UT unit.Type
}
// IsErrUnitTypeNotExist checks if an error is a ErrUnitNotExist.
func IsErrUnitTypeNotExist(err error) bool {
_, ok := err.(ErrUnitTypeNotExist)
return ok
}
func (err ErrUnitTypeNotExist) Error() string {
return fmt.Sprintf("Unit type does not exist: %s", err.UT.String())
}
// RepoUnit describes all units of a repository
type RepoUnit struct {
type RepoUnit struct { //revive:disable-line:exported
ID int64
RepoID int64 `xorm:"INDEX(s)"`
Type unit.Type `xorm:"INDEX(s)"`
@ -35,7 +50,7 @@ type UnitConfig struct{}
// FromDB fills up a UnitConfig from serialized format.
func (cfg *UnitConfig) FromDB(bs []byte) error {
return JSONUnmarshalHandleDoubleEncode(bs, &cfg)
return json.UnmarshalHandleDoubleEncode(bs, &cfg)
}
// ToDB exports a UnitConfig to a serialized format.
@ -50,7 +65,7 @@ type ExternalWikiConfig struct {
// FromDB fills up a ExternalWikiConfig from serialized format.
func (cfg *ExternalWikiConfig) FromDB(bs []byte) error {
return JSONUnmarshalHandleDoubleEncode(bs, &cfg)
return json.UnmarshalHandleDoubleEncode(bs, &cfg)
}
// ToDB exports a ExternalWikiConfig to a serialized format.
@ -67,7 +82,7 @@ type ExternalTrackerConfig struct {
// FromDB fills up a ExternalTrackerConfig from serialized format.
func (cfg *ExternalTrackerConfig) FromDB(bs []byte) error {
return JSONUnmarshalHandleDoubleEncode(bs, &cfg)
return json.UnmarshalHandleDoubleEncode(bs, &cfg)
}
// ToDB exports a ExternalTrackerConfig to a serialized format.
@ -84,7 +99,7 @@ type IssuesConfig struct {
// FromDB fills up a IssuesConfig from serialized format.
func (cfg *IssuesConfig) FromDB(bs []byte) error {
return JSONUnmarshalHandleDoubleEncode(bs, &cfg)
return json.UnmarshalHandleDoubleEncode(bs, &cfg)
}
// ToDB exports a IssuesConfig to a serialized format.
@ -107,7 +122,7 @@ type PullRequestsConfig struct {
// FromDB fills up a PullRequestsConfig from serialized format.
func (cfg *PullRequestsConfig) FromDB(bs []byte) error {
return JSONUnmarshalHandleDoubleEncode(bs, &cfg)
return json.UnmarshalHandleDoubleEncode(bs, &cfg)
}
// ToDB exports a PullRequestsConfig to a serialized format.

View file

@ -3,7 +3,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
package repo
import (
"path/filepath"

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
package repo
import (
"path/filepath"

View file

@ -10,6 +10,7 @@ import (
"time"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
@ -42,7 +43,7 @@ type ActivityStats struct {
}
// GetActivityStats return stats for repository at given time range
func GetActivityStats(repo *Repository, timeFrom time.Time, releases, issues, prs, code bool) (*ActivityStats, error) {
func GetActivityStats(repo *repo_model.Repository, timeFrom time.Time, releases, issues, prs, code bool) (*ActivityStats, error) {
stats := &ActivityStats{Code: &git.CodeActivityStats{}}
if releases {
if err := stats.FillReleases(repo.ID, timeFrom); err != nil {
@ -79,7 +80,7 @@ func GetActivityStats(repo *Repository, timeFrom time.Time, releases, issues, pr
}
// GetActivityStatsTopAuthors returns top author stats for git commits for all branches
func GetActivityStatsTopAuthors(repo *Repository, timeFrom time.Time, count int) ([]*ActivityAuthorData, error) {
func GetActivityStatsTopAuthors(repo *repo_model.Repository, timeFrom time.Time, count int) ([]*ActivityAuthorData, error) {
gitRepo, err := git.OpenRepository(repo.RepoPath())
if err != nil {
return nil, fmt.Errorf("OpenRepository: %v", err)

View file

@ -10,14 +10,14 @@ import (
)
// LoadArchiverRepo loads repository
func LoadArchiverRepo(archiver *repo_model.RepoArchiver) (*Repository, error) {
var repo Repository
func LoadArchiverRepo(archiver *repo_model.RepoArchiver) (*repo_model.Repository, error) {
var repo repo_model.Repository
has, err := db.GetEngine(db.DefaultContext).ID(archiver.RepoID).Get(&repo)
if err != nil {
return nil, err
}
if !has {
return nil, ErrRepoNotExist{
return nil, repo_model.ErrRepoNotExist{
ID: archiver.RepoID,
}
}

View file

@ -10,59 +10,23 @@ import (
"fmt"
"image/png"
"io"
"net/url"
"strconv"
"strings"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/avatar"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
)
// CustomAvatarRelativePath returns repository custom avatar file path.
func (repo *Repository) CustomAvatarRelativePath() string {
return repo.Avatar
}
// generateRandomAvatar generates a random avatar for repository.
func (repo *Repository) generateRandomAvatar(e db.Engine) error {
idToString := fmt.Sprintf("%d", repo.ID)
seed := idToString
img, err := avatar.RandomImage([]byte(seed))
if err != nil {
return fmt.Errorf("RandomImage: %v", err)
}
repo.Avatar = idToString
if err := storage.SaveFrom(storage.RepoAvatars, repo.CustomAvatarRelativePath(), func(w io.Writer) error {
if err := png.Encode(w, img); err != nil {
log.Error("Encode: %v", err)
}
return err
}); err != nil {
return fmt.Errorf("Failed to create dir %s: %v", repo.CustomAvatarRelativePath(), err)
}
log.Info("New random avatar created for repository: %d", repo.ID)
if _, err := e.ID(repo.ID).Cols("avatar").NoAutoTime().Update(repo); err != nil {
return err
}
return nil
}
// RemoveRandomAvatars removes the randomly generated avatars that were created for repositories
func RemoveRandomAvatars(ctx context.Context) error {
return db.GetEngine(db.DefaultContext).
Where("id > 0").BufferSize(setting.Database.IterateBufferSize).
Iterate(new(Repository),
Iterate(new(repo_model.Repository),
func(idx int, bean interface{}) error {
repository := bean.(*Repository)
repository := bean.(*repo_model.Repository)
select {
case <-ctx.Done():
return db.ErrCancelledf("before random avatars removed for %s", repository.FullName())
@ -70,55 +34,15 @@ func RemoveRandomAvatars(ctx context.Context) error {
}
stringifiedID := strconv.FormatInt(repository.ID, 10)
if repository.Avatar == stringifiedID {
return repository.DeleteAvatar()
return DeleteRepoAvatar(repository)
}
return nil
})
}
// RelAvatarLink returns a relative link to the repository's avatar.
func (repo *Repository) RelAvatarLink() string {
return repo.relAvatarLink(db.GetEngine(db.DefaultContext))
}
func (repo *Repository) relAvatarLink(e db.Engine) string {
// If no avatar - path is empty
avatarPath := repo.CustomAvatarRelativePath()
if len(avatarPath) == 0 {
switch mode := setting.RepoAvatar.Fallback; mode {
case "image":
return setting.RepoAvatar.FallbackImage
case "random":
if err := repo.generateRandomAvatar(e); err != nil {
log.Error("generateRandomAvatar: %v", err)
}
default:
// default behaviour: do not display avatar
return ""
}
}
return setting.AppSubURL + "/repo-avatars/" + url.PathEscape(repo.Avatar)
}
// AvatarLink returns a link to the repository's avatar.
func (repo *Repository) AvatarLink() string {
return repo.avatarLink(db.GetEngine(db.DefaultContext))
}
// avatarLink returns user avatar absolute link.
func (repo *Repository) avatarLink(e db.Engine) string {
link := repo.relAvatarLink(e)
// we only prepend our AppURL to our known (relative, internal) avatar link to get an absolute URL
if strings.HasPrefix(link, "/") && !strings.HasPrefix(link, "//") {
return setting.AppURL + strings.TrimPrefix(link, setting.AppSubURL)[1:]
}
// otherwise, return the link as it is
return link
}
// UploadAvatar saves custom avatar for repository.
// UploadRepoAvatar saves custom avatar for repository.
// FIXME: split uploads to different subdirs in case we have massive number of repos.
func (repo *Repository) UploadAvatar(data []byte) error {
func UploadRepoAvatar(repo *repo_model.Repository, data []byte) error {
m, err := avatar.Prepare(data)
if err != nil {
return err
@ -162,8 +86,8 @@ func (repo *Repository) UploadAvatar(data []byte) error {
return committer.Commit()
}
// DeleteAvatar deletes the repos's custom avatar.
func (repo *Repository) DeleteAvatar() error {
// DeleteRepoAvatar deletes the repos's custom avatar.
func DeleteRepoAvatar(repo *repo_model.Repository) error {
// Avatar not exists
if len(repo.Avatar) == 0 {
return nil

View file

@ -1,11 +0,0 @@
// Copyright 2016 The Gogs Authors. All rights reserved.
// Copyright 2019 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 models
// CanCreateBranch returns true if repository meets the requirements for creating new branches.
func (repo *Repository) CanCreateBranch() bool {
return !repo.IsMirror
}

View file

@ -6,10 +6,12 @@
package models
import (
"context"
"fmt"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
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"
@ -32,11 +34,12 @@ func init() {
db.RegisterModel(new(Collaboration))
}
func (repo *Repository) addCollaborator(e db.Engine, u *user_model.User) error {
func addCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error {
collaboration := &Collaboration{
RepoID: repo.ID,
UserID: u.ID,
}
e := db.GetEngine(ctx)
has, err := e.Get(collaboration)
if err != nil {
@ -50,34 +53,34 @@ func (repo *Repository) addCollaborator(e db.Engine, u *user_model.User) error {
return err
}
return repo.recalculateUserAccess(e, u.ID)
return recalculateUserAccess(ctx, repo, u.ID)
}
// AddCollaborator adds new collaboration to a repository with default access mode.
func (repo *Repository) AddCollaborator(u *user_model.User) error {
func AddCollaborator(repo *repo_model.Repository, u *user_model.User) error {
ctx, committer, err := db.TxContext()
if err != nil {
return err
}
defer committer.Close()
if err := repo.addCollaborator(db.GetEngine(ctx), u); err != nil {
if err := addCollaborator(ctx, repo, u); err != nil {
return err
}
return committer.Commit()
}
func (repo *Repository) getCollaborations(e db.Engine, listOptions db.ListOptions) ([]*Collaboration, error) {
func getCollaborations(e db.Engine, repoID int64, listOptions db.ListOptions) ([]*Collaboration, error) {
if listOptions.Page == 0 {
collaborations := make([]*Collaboration, 0, 8)
return collaborations, e.Find(&collaborations, &Collaboration{RepoID: repo.ID})
return collaborations, e.Find(&collaborations, &Collaboration{RepoID: repoID})
}
e = db.SetEnginePagination(e, &listOptions)
collaborations := make([]*Collaboration, 0, listOptions.PageSize)
return collaborations, e.Find(&collaborations, &Collaboration{RepoID: repo.ID})
return collaborations, e.Find(&collaborations, &Collaboration{RepoID: repoID})
}
// Collaborator represents a user with collaboration details.
@ -86,8 +89,8 @@ type Collaborator struct {
Collaboration *Collaboration
}
func (repo *Repository) getCollaborators(e db.Engine, listOptions db.ListOptions) ([]*Collaborator, error) {
collaborations, err := repo.getCollaborations(e, listOptions)
func getCollaborators(e db.Engine, repoID int64, listOptions db.ListOptions) ([]*Collaborator, error) {
collaborations, err := getCollaborations(e, repoID, listOptions)
if err != nil {
return nil, fmt.Errorf("getCollaborations: %v", err)
}
@ -97,7 +100,7 @@ func (repo *Repository) getCollaborators(e db.Engine, listOptions db.ListOptions
user, err := user_model.GetUserByIDEngine(e, c.UserID)
if err != nil {
if user_model.IsErrUserNotExist(err) {
log.Warn("Inconsistent DB: User: %d is listed as collaborator of %-v but does not exist", c.UserID, repo)
log.Warn("Inconsistent DB: User: %d is listed as collaborator of %-v but does not exist", c.UserID, repoID)
user = user_model.NewGhostUser()
} else {
return nil, err
@ -112,18 +115,18 @@ func (repo *Repository) getCollaborators(e db.Engine, listOptions db.ListOptions
}
// GetCollaborators returns the collaborators for a repository
func (repo *Repository) GetCollaborators(listOptions db.ListOptions) ([]*Collaborator, error) {
return repo.getCollaborators(db.GetEngine(db.DefaultContext), listOptions)
func GetCollaborators(repoID int64, listOptions db.ListOptions) ([]*Collaborator, error) {
return getCollaborators(db.GetEngine(db.DefaultContext), repoID, listOptions)
}
// CountCollaborators returns total number of collaborators for a repository
func (repo *Repository) CountCollaborators() (int64, error) {
return db.GetEngine(db.DefaultContext).Where("repo_id = ? ", repo.ID).Count(&Collaboration{})
func CountCollaborators(repoID int64) (int64, error) {
return db.GetEngine(db.DefaultContext).Where("repo_id = ? ", repoID).Count(&Collaboration{})
}
func (repo *Repository) getCollaboration(e db.Engine, uid int64) (*Collaboration, error) {
func getCollaboration(e db.Engine, repoID, uid int64) (*Collaboration, error) {
collaboration := &Collaboration{
RepoID: repo.ID,
RepoID: repoID,
UserID: uid,
}
has, err := e.Get(collaboration)
@ -133,16 +136,16 @@ func (repo *Repository) getCollaboration(e db.Engine, uid int64) (*Collaboration
return collaboration, err
}
func (repo *Repository) isCollaborator(e db.Engine, userID int64) (bool, error) {
return e.Get(&Collaboration{RepoID: repo.ID, UserID: userID})
func isCollaborator(e db.Engine, repoID, userID int64) (bool, error) {
return e.Get(&Collaboration{RepoID: repoID, UserID: userID})
}
// IsCollaborator check if a user is a collaborator of a repository
func (repo *Repository) IsCollaborator(userID int64) (bool, error) {
return repo.isCollaborator(db.GetEngine(db.DefaultContext), userID)
func IsCollaborator(repoID, userID int64) (bool, error) {
return isCollaborator(db.GetEngine(db.DefaultContext), repoID, userID)
}
func (repo *Repository) changeCollaborationAccessMode(e db.Engine, uid int64, mode perm.AccessMode) error {
func changeCollaborationAccessMode(e db.Engine, repo *repo_model.Repository, uid int64, mode perm.AccessMode) error {
// Discard invalid input
if mode <= perm.AccessModeNone || mode > perm.AccessModeOwner {
return nil
@ -177,14 +180,14 @@ func (repo *Repository) changeCollaborationAccessMode(e db.Engine, uid int64, mo
}
// ChangeCollaborationAccessMode sets new access mode for the collaboration.
func (repo *Repository) ChangeCollaborationAccessMode(uid int64, mode perm.AccessMode) error {
func ChangeCollaborationAccessMode(repo *repo_model.Repository, uid int64, mode perm.AccessMode) error {
ctx, committer, err := db.TxContext()
if err != nil {
return err
}
defer committer.Close()
if err := repo.changeCollaborationAccessMode(db.GetEngine(ctx), uid, mode); err != nil {
if err := changeCollaborationAccessMode(db.GetEngine(ctx), repo, uid, mode); err != nil {
return err
}
@ -192,7 +195,7 @@ func (repo *Repository) ChangeCollaborationAccessMode(uid int64, mode perm.Acces
}
// DeleteCollaboration removes collaboration relation between the user and repository.
func (repo *Repository) DeleteCollaboration(uid int64) (err error) {
func DeleteCollaboration(repo *repo_model.Repository, uid int64) (err error) {
collaboration := &Collaboration{
RepoID: repo.ID,
UserID: uid,
@ -208,7 +211,7 @@ func (repo *Repository) DeleteCollaboration(uid int64) (err error) {
if has, err := sess.Delete(collaboration); err != nil || has == 0 {
return err
} else if err = repo.recalculateAccesses(sess); err != nil {
} else if err = recalculateAccesses(ctx, repo); err != nil {
return err
}
@ -216,29 +219,29 @@ func (repo *Repository) DeleteCollaboration(uid int64) (err error) {
return err
}
if err = repo.reconsiderWatches(sess, uid); err != nil {
if err = reconsiderWatches(ctx, repo, uid); err != nil {
return err
}
// Unassign a user from any issue (s)he has been assigned to in the repository
if err := repo.reconsiderIssueAssignees(sess, uid); err != nil {
if err := reconsiderRepoIssuesAssignee(ctx, repo, uid); err != nil {
return err
}
return committer.Commit()
}
func (repo *Repository) reconsiderIssueAssignees(e db.Engine, uid int64) error {
user, err := user_model.GetUserByIDEngine(e, uid)
func reconsiderRepoIssuesAssignee(ctx context.Context, repo *repo_model.Repository, uid int64) error {
user, err := user_model.GetUserByIDEngine(db.GetEngine(ctx), uid)
if err != nil {
return err
}
if canAssigned, err := canBeAssigned(e, user, repo, true); err != nil || canAssigned {
if canAssigned, err := canBeAssigned(ctx, user, repo, true); err != nil || canAssigned {
return err
}
if _, err := e.Where(builder.Eq{"assignee_id": uid}).
if _, err := db.GetEngine(ctx).Where(builder.Eq{"assignee_id": uid}).
In("issue_id", builder.Select("id").From("issue").Where(builder.Eq{"repo_id": repo.ID})).
Delete(&IssueAssignees{}); err != nil {
return fmt.Errorf("Could not delete assignee[%d] %v", uid, err)
@ -246,11 +249,11 @@ func (repo *Repository) reconsiderIssueAssignees(e db.Engine, uid int64) error {
return nil
}
func (repo *Repository) reconsiderWatches(e db.Engine, uid int64) error {
if has, err := hasAccess(e, uid, repo); err != nil || has {
func reconsiderWatches(ctx context.Context, repo *repo_model.Repository, uid int64) error {
if has, err := hasAccess(ctx, uid, repo); err != nil || has {
return err
}
e := db.GetEngine(ctx)
if err := watchRepo(e, uid, repo.ID, false); err != nil {
return err
}
@ -259,7 +262,7 @@ func (repo *Repository) reconsiderWatches(e db.Engine, uid int64) error {
return removeIssueWatchersByRepoID(e, uid, repo.ID)
}
func (repo *Repository) getRepoTeams(e db.Engine) (teams []*Team, err error) {
func getRepoTeams(e db.Engine, repo *repo_model.Repository) (teams []*Team, err error) {
return teams, e.
Join("INNER", "team_repo", "team_repo.team_id = team.id").
Where("team.org_id = ?", repo.OwnerID).
@ -269,12 +272,12 @@ func (repo *Repository) getRepoTeams(e db.Engine) (teams []*Team, err error) {
}
// GetRepoTeams gets the list of teams that has access to the repository
func (repo *Repository) GetRepoTeams() ([]*Team, error) {
return repo.getRepoTeams(db.GetEngine(db.DefaultContext))
func GetRepoTeams(repo *repo_model.Repository) ([]*Team, error) {
return getRepoTeams(db.GetEngine(db.DefaultContext), repo)
}
// IsOwnerMemberCollaborator checks if a provided user is the owner, a collaborator or a member of a team in a repository
func (repo *Repository) IsOwnerMemberCollaborator(userID int64) (bool, error) {
func IsOwnerMemberCollaborator(repo *repo_model.Repository, userID int64) (bool, error) {
if repo.OwnerID == userID {
return true, nil
}

View file

@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@ -19,11 +20,11 @@ func TestRepository_AddCollaborator(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(repoID, userID int64) {
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository)
assert.NoError(t, repo.GetOwner())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
assert.NoError(t, repo.GetOwner(db.DefaultContext))
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}).(*user_model.User)
assert.NoError(t, repo.AddCollaborator(user))
unittest.CheckConsistencyFor(t, &Repository{ID: repoID}, &user_model.User{ID: userID})
assert.NoError(t, AddCollaborator(repo, user))
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID}, &user_model.User{ID: userID})
}
testSuccess(1, 4)
testSuccess(1, 4)
@ -33,8 +34,8 @@ func TestRepository_AddCollaborator(t *testing.T) {
func TestRepository_GetCollaborators(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64) {
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository)
collaborators, err := repo.GetCollaborators(db.ListOptions{})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
collaborators, err := GetCollaborators(repo.ID, db.ListOptions{})
assert.NoError(t, err)
expectedLen, err := db.GetEngine(db.DefaultContext).Count(&Collaboration{RepoID: repoID})
assert.NoError(t, err)
@ -54,8 +55,8 @@ func TestRepository_IsCollaborator(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID, userID int64, expected bool) {
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository)
actual, err := repo.IsCollaborator(userID)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
actual, err := IsCollaborator(repo.ID, userID)
assert.NoError(t, err)
assert.Equal(t, expected, actual)
}
@ -68,8 +69,8 @@ func TestRepository_IsCollaborator(t *testing.T) {
func TestRepository_ChangeCollaborationAccessMode(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 4}).(*Repository)
assert.NoError(t, repo.ChangeCollaborationAccessMode(4, perm.AccessModeAdmin))
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository)
assert.NoError(t, ChangeCollaborationAccessMode(repo, 4, perm.AccessModeAdmin))
collaboration := unittest.AssertExistsAndLoadBean(t, &Collaboration{RepoID: repo.ID, UserID: 4}).(*Collaboration)
assert.EqualValues(t, perm.AccessModeAdmin, collaboration.Mode)
@ -77,23 +78,23 @@ func TestRepository_ChangeCollaborationAccessMode(t *testing.T) {
access := unittest.AssertExistsAndLoadBean(t, &Access{UserID: 4, RepoID: repo.ID}).(*Access)
assert.EqualValues(t, perm.AccessModeAdmin, access.Mode)
assert.NoError(t, repo.ChangeCollaborationAccessMode(4, perm.AccessModeAdmin))
assert.NoError(t, ChangeCollaborationAccessMode(repo, 4, perm.AccessModeAdmin))
assert.NoError(t, repo.ChangeCollaborationAccessMode(unittest.NonexistentID, perm.AccessModeAdmin))
assert.NoError(t, ChangeCollaborationAccessMode(repo, unittest.NonexistentID, perm.AccessModeAdmin))
unittest.CheckConsistencyFor(t, &Repository{ID: repo.ID})
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID})
}
func TestRepository_DeleteCollaboration(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 4}).(*Repository)
assert.NoError(t, repo.GetOwner())
assert.NoError(t, repo.DeleteCollaboration(4))
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository)
assert.NoError(t, repo.GetOwner(db.DefaultContext))
assert.NoError(t, DeleteCollaboration(repo, 4))
unittest.AssertNotExistsBean(t, &Collaboration{RepoID: repo.ID, UserID: 4})
assert.NoError(t, repo.DeleteCollaboration(4))
assert.NoError(t, DeleteCollaboration(repo, 4))
unittest.AssertNotExistsBean(t, &Collaboration{RepoID: repo.ID, UserID: 4})
unittest.CheckConsistencyFor(t, &Repository{ID: repo.ID})
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID})
}

View file

@ -12,6 +12,7 @@ import (
"strings"
"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"
@ -70,7 +71,7 @@ func (gt GiteaTemplate) Globs() []glob.Glob {
}
// GenerateTopics generates topics from a template repository
func GenerateTopics(ctx context.Context, templateRepo, generateRepo *Repository) error {
func GenerateTopics(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error {
for _, topic := range templateRepo.Topics {
if _, err := addTopicByNameToRepo(db.GetEngine(ctx), generateRepo.ID, topic); err != nil {
return err
@ -80,7 +81,7 @@ func GenerateTopics(ctx context.Context, templateRepo, generateRepo *Repository)
}
// GenerateGitHooks generates git hooks from a template repository
func GenerateGitHooks(ctx context.Context, templateRepo, generateRepo *Repository) error {
func GenerateGitHooks(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error {
generateGitRepo, err := git.OpenRepository(generateRepo.RepoPath())
if err != nil {
return err
@ -113,7 +114,7 @@ func GenerateGitHooks(ctx context.Context, templateRepo, generateRepo *Repositor
}
// GenerateWebhooks generates webhooks from a template repository
func GenerateWebhooks(ctx context.Context, templateRepo, generateRepo *Repository) error {
func GenerateWebhooks(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error {
templateWebhooks, err := webhook.ListWebhooksByOpts(&webhook.ListWebhookOptions{RepoID: templateRepo.ID})
if err != nil {
return err
@ -141,7 +142,7 @@ func GenerateWebhooks(ctx context.Context, templateRepo, generateRepo *Repositor
}
// GenerateAvatar generates the avatar from a template repository
func GenerateAvatar(ctx context.Context, templateRepo, generateRepo *Repository) error {
func GenerateAvatar(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error {
generateRepo.Avatar = strings.Replace(templateRepo.Avatar, strconv.FormatInt(templateRepo.ID, 10), strconv.FormatInt(generateRepo.ID, 10), 1)
if _, err := storage.Copy(storage.RepoAvatars, generateRepo.CustomAvatarRelativePath(), storage.RepoAvatars, templateRepo.CustomAvatarRelativePath()); err != nil {
return err
@ -151,7 +152,7 @@ func GenerateAvatar(ctx context.Context, templateRepo, generateRepo *Repository)
}
// GenerateIssueLabels generates issue labels from a template repository
func GenerateIssueLabels(ctx context.Context, templateRepo, generateRepo *Repository) error {
func GenerateIssueLabels(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error {
templateLabels, err := getLabelsByRepoID(db.GetEngine(ctx), templateRepo.ID, "", db.ListOptions{})
if err != nil {
return err

View file

@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
@ -25,7 +26,7 @@ import (
const RepositoryListDefaultPageSize = 64
// RepositoryList contains a list of repositories
type RepositoryList []*Repository
type RepositoryList []*repo_model.Repository
func (repos RepositoryList) Len() int {
return len(repos)
@ -40,7 +41,7 @@ func (repos RepositoryList) Swap(i, j int) {
}
// RepositoryListOfMap make list from values of map
func RepositoryListOfMap(repoMap map[int64]*Repository) RepositoryList {
func RepositoryListOfMap(repoMap map[int64]*repo_model.Repository) RepositoryList {
return RepositoryList(valuesRepository(repoMap))
}
@ -69,14 +70,14 @@ func (repos RepositoryList) loadAttributes(e db.Engine) error {
}
// Load primary language.
stats := make(LanguageStatList, 0, len(repos))
stats := make(repo_model.LanguageStatList, 0, len(repos))
if err := e.
Where("`is_primary` = ? AND `language` != ?", true, "other").
In("`repo_id`", repoIDs).
Find(&stats); err != nil {
return fmt.Errorf("find primary languages: %v", err)
}
stats.loadAttributes()
stats.LoadAttributes()
for i := range repos {
for _, st := range stats {
if st.RepoID == repos[i].ID {
@ -94,46 +95,6 @@ func (repos RepositoryList) LoadAttributes() error {
return repos.loadAttributes(db.GetEngine(db.DefaultContext))
}
// MirrorRepositoryList contains the mirror repositories
type MirrorRepositoryList []*Repository
func (repos MirrorRepositoryList) loadAttributes(e db.Engine) error {
if len(repos) == 0 {
return nil
}
// Load mirrors.
repoIDs := make([]int64, 0, len(repos))
for i := range repos {
if !repos[i].IsMirror {
continue
}
repoIDs = append(repoIDs, repos[i].ID)
}
mirrors := make([]*Mirror, 0, len(repoIDs))
if err := e.
Where("id > 0").
In("repo_id", repoIDs).
Find(&mirrors); err != nil {
return fmt.Errorf("find mirrors: %v", err)
}
set := make(map[int64]*Mirror)
for i := range mirrors {
set[mirrors[i].RepoID] = mirrors[i]
}
for i := range repos {
repos[i].Mirror = set[repos[i].ID]
}
return nil
}
// LoadAttributes loads the attributes for the given MirrorRepositoryList
func (repos MirrorRepositoryList) LoadAttributes() error {
return repos.loadAttributes(db.GetEngine(db.DefaultContext))
}
// SearchRepoOptions holds the search options
type SearchRepoOptions struct {
db.ListOptions
@ -392,7 +353,7 @@ func searchRepositoryByCondition(opts *SearchRepoOptions, cond builder.Cond) (db
var err error
count, err = sess.
Where(cond).
Count(new(Repository))
Count(new(repo_model.Repository))
if err != nil {
return nil, 0, fmt.Errorf("Count: %v", err)
}
@ -502,3 +463,31 @@ func FindUserAccessibleRepoIDs(user *user_model.User) ([]int64, error) {
}
return repoIDs, nil
}
// GetUserRepositories returns a list of repositories of given user.
func GetUserRepositories(opts *SearchRepoOptions) ([]*repo_model.Repository, int64, error) {
if len(opts.OrderBy) == 0 {
opts.OrderBy = "updated_unix DESC"
}
cond := builder.NewCond()
cond = cond.And(builder.Eq{"owner_id": opts.Actor.ID})
if !opts.Private {
cond = cond.And(builder.Eq{"is_private": false})
}
if opts.LowerNames != nil && len(opts.LowerNames) > 0 {
cond = cond.And(builder.In("lower_name", opts.LowerNames))
}
sess := db.GetEngine(db.DefaultContext)
count, err := sess.Where(cond).Count(new(repo_model.Repository))
if err != nil {
return nil, 0, fmt.Errorf("Count: %v", err)
}
sess = sess.Where(cond).OrderBy(opts.OrderBy.String())
repos := make([]*repo_model.Repository, 0, opts.PageSize)
return repos, count, db.SetSessionPagination(sess, opts).Find(&repos)
}

View file

@ -5,10 +5,12 @@
package models
import (
"context"
"fmt"
"code.gitea.io/gitea/models/db"
perm_model "code.gitea.io/gitea/models/perm"
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"
@ -17,7 +19,7 @@ import (
// Permission contains all the permissions related variables to a repository for a user
type Permission struct {
AccessMode perm_model.AccessMode
Units []*RepoUnit
Units []*repo_model.RepoUnit
UnitsMode map[unit.Type]perm_model.AccessMode
}
@ -142,11 +144,11 @@ func (p *Permission) ColorFormat(s fmt.State) {
}
// GetUserRepoPermission returns the user permissions to the repository
func GetUserRepoPermission(repo *Repository, user *user_model.User) (Permission, error) {
return getUserRepoPermission(db.GetEngine(db.DefaultContext), repo, user)
func GetUserRepoPermission(repo *repo_model.Repository, user *user_model.User) (Permission, error) {
return getUserRepoPermission(db.DefaultContext, repo, user)
}
func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User) (perm Permission, err error) {
func getUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (perm Permission, err error) {
if log.IsTrace() {
defer func() {
if user == nil {
@ -168,26 +170,28 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User)
return
}
var isCollaborator bool
e := db.GetEngine(ctx)
var is bool
if user != nil {
isCollaborator, err = repo.isCollaborator(e, user.ID)
is, err = isCollaborator(e, repo.ID, user.ID)
if err != nil {
return perm, err
}
}
if err = repo.getOwner(e); err != nil {
if err = repo.GetOwner(ctx); err != nil {
return
}
// Prevent strangers from checking out public repo of private organization/users
// Allow user if they are collaborator of a repo within a private user or a private organization but not a member of the organization itself
if !hasOrgOrUserVisible(e, repo.Owner, user) && !isCollaborator {
if !hasOrgOrUserVisible(e, repo.Owner, user) && !is {
perm.AccessMode = perm_model.AccessModeNone
return
}
if err = repo.getUnits(e); err != nil {
if err = repo.LoadUnits(ctx); err != nil {
return
}
@ -211,7 +215,7 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User)
return
}
if err = repo.getOwner(e); err != nil {
if err = repo.GetOwner(ctx); err != nil {
return
}
if !repo.Owner.IsOrganization() {
@ -221,7 +225,7 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User)
perm.UnitsMode = make(map[unit.Type]perm_model.AccessMode)
// Collaborators on organization
if isCollaborator {
if is {
for _, u := range repo.Units {
perm.UnitsMode[u.Type] = perm.AccessMode
}
@ -263,7 +267,7 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User)
}
// remove no permission units
perm.Units = make([]*RepoUnit, 0, len(repo.Units))
perm.Units = make([]*repo_model.RepoUnit, 0, len(repo.Units))
for t := range perm.UnitsMode {
for _, u := range repo.Units {
if u.Type == t {
@ -276,18 +280,16 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User)
}
// IsUserRealRepoAdmin check if this user is real repo admin
func IsUserRealRepoAdmin(repo *Repository, user *user_model.User) (bool, error) {
func IsUserRealRepoAdmin(repo *repo_model.Repository, user *user_model.User) (bool, error) {
if repo.OwnerID == user.ID {
return true, nil
}
sess := db.GetEngine(db.DefaultContext)
if err := repo.getOwner(sess); err != nil {
if err := repo.GetOwner(db.DefaultContext); err != nil {
return false, err
}
accessMode, err := accessLevel(sess, user, repo)
accessMode, err := accessLevel(db.GetEngine(db.DefaultContext), user, repo)
if err != nil {
return false, err
}
@ -296,11 +298,11 @@ func IsUserRealRepoAdmin(repo *Repository, user *user_model.User) (bool, error)
}
// IsUserRepoAdmin return true if user has admin right of a repo
func IsUserRepoAdmin(repo *Repository, user *user_model.User) (bool, error) {
func IsUserRepoAdmin(repo *repo_model.Repository, user *user_model.User) (bool, error) {
return isUserRepoAdmin(db.GetEngine(db.DefaultContext), repo, user)
}
func isUserRepoAdmin(e db.Engine, repo *Repository, user *user_model.User) (bool, error) {
func isUserRepoAdmin(e db.Engine, repo *repo_model.Repository, user *user_model.User) (bool, error) {
if user == nil || repo == nil {
return false, nil
}
@ -331,62 +333,62 @@ func isUserRepoAdmin(e db.Engine, repo *Repository, user *user_model.User) (bool
// AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the
// user does not have access.
func AccessLevel(user *user_model.User, repo *Repository) (perm_model.AccessMode, error) {
return accessLevelUnit(db.GetEngine(db.DefaultContext), user, repo, unit.TypeCode)
func AccessLevel(user *user_model.User, repo *repo_model.Repository) (perm_model.AccessMode, error) {
return accessLevelUnit(db.DefaultContext, user, repo, unit.TypeCode)
}
// AccessLevelUnit returns the Access a user has to a repository's. Will return NoneAccess if the
// user does not have access.
func AccessLevelUnit(user *user_model.User, repo *Repository, unitType unit.Type) (perm_model.AccessMode, error) {
return accessLevelUnit(db.GetEngine(db.DefaultContext), user, repo, unitType)
func AccessLevelUnit(user *user_model.User, repo *repo_model.Repository, unitType unit.Type) (perm_model.AccessMode, error) {
return accessLevelUnit(db.DefaultContext, user, repo, unitType)
}
func accessLevelUnit(e db.Engine, user *user_model.User, repo *Repository, unitType unit.Type) (perm_model.AccessMode, error) {
perm, err := getUserRepoPermission(e, repo, user)
func accessLevelUnit(ctx context.Context, user *user_model.User, repo *repo_model.Repository, unitType unit.Type) (perm_model.AccessMode, error) {
perm, err := getUserRepoPermission(ctx, repo, user)
if err != nil {
return perm_model.AccessModeNone, err
}
return perm.UnitAccessMode(unitType), nil
}
func hasAccessUnit(e db.Engine, user *user_model.User, repo *Repository, unitType unit.Type, testMode perm_model.AccessMode) (bool, error) {
mode, err := accessLevelUnit(e, user, repo, unitType)
func hasAccessUnit(ctx context.Context, user *user_model.User, repo *repo_model.Repository, unitType unit.Type, testMode perm_model.AccessMode) (bool, error) {
mode, err := accessLevelUnit(ctx, user, repo, unitType)
return testMode <= mode, err
}
// HasAccessUnit returns true if user has testMode to the unit of the repository
func HasAccessUnit(user *user_model.User, repo *Repository, unitType unit.Type, testMode perm_model.AccessMode) (bool, error) {
return hasAccessUnit(db.GetEngine(db.DefaultContext), user, repo, unitType, testMode)
func HasAccessUnit(user *user_model.User, repo *repo_model.Repository, unitType unit.Type, testMode perm_model.AccessMode) (bool, error) {
return hasAccessUnit(db.DefaultContext, user, repo, unitType, testMode)
}
// CanBeAssigned return true if user can be assigned to issue or pull requests in repo
// Currently any write access (code, issues or pr's) is assignable, to match assignee list in user interface.
// FIXME: user could send PullRequest also could be assigned???
func CanBeAssigned(user *user_model.User, repo *Repository, isPull bool) (bool, error) {
return canBeAssigned(db.GetEngine(db.DefaultContext), user, repo, isPull)
func CanBeAssigned(user *user_model.User, repo *repo_model.Repository, isPull bool) (bool, error) {
return canBeAssigned(db.DefaultContext, user, repo, isPull)
}
func canBeAssigned(e db.Engine, user *user_model.User, repo *Repository, _ bool) (bool, error) {
func canBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model.Repository, _ bool) (bool, error) {
if user.IsOrganization() {
return false, fmt.Errorf("Organization can't be added as assignee [user_id: %d, repo_id: %d]", user.ID, repo.ID)
}
perm, err := getUserRepoPermission(e, repo, user)
perm, err := getUserRepoPermission(ctx, repo, user)
if err != nil {
return false, err
}
return perm.CanAccessAny(perm_model.AccessModeWrite, unit.TypeCode, unit.TypeIssues, unit.TypePullRequests), nil
}
func hasAccess(e db.Engine, userID int64, repo *Repository) (bool, error) {
func hasAccess(ctx context.Context, userID int64, repo *repo_model.Repository) (bool, error) {
var user *user_model.User
var err error
if userID > 0 {
user, err = user_model.GetUserByIDEngine(e, userID)
user, err = user_model.GetUserByIDEngine(db.GetEngine(ctx), userID)
if err != nil {
return false, err
}
}
perm, err := getUserRepoPermission(e, repo, user)
perm, err := getUserRepoPermission(ctx, repo, user)
if err != nil {
return false, err
}
@ -394,15 +396,15 @@ func hasAccess(e db.Engine, userID int64, repo *Repository) (bool, error) {
}
// HasAccess returns true if user has access to repo
func HasAccess(userID int64, repo *Repository) (bool, error) {
return hasAccess(db.GetEngine(db.DefaultContext), userID, repo)
func HasAccess(userID int64, repo *repo_model.Repository) (bool, error) {
return hasAccess(db.DefaultContext, userID, repo)
}
// FilterOutRepoIdsWithoutUnitAccess filter out repos where user has no access to repositories
func FilterOutRepoIdsWithoutUnitAccess(u *user_model.User, repoIDs []int64, units ...unit.Type) ([]int64, error) {
i := 0
for _, rID := range repoIDs {
repo, err := GetRepositoryByID(rID)
repo, err := repo_model.GetRepositoryByID(rID)
if err != nil {
return nil, err
}

View file

@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/models/db"
perm_model "code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@ -20,8 +21,8 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// public non-organization repo
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 4}).(*Repository)
assert.NoError(t, repo.getUnits(db.GetEngine(db.DefaultContext)))
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository)
assert.NoError(t, repo.LoadUnits(db.DefaultContext))
// plain user
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
@ -33,7 +34,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) {
}
// change to collaborator
assert.NoError(t, repo.AddCollaborator(user))
assert.NoError(t, AddCollaborator(repo, user))
perm, err = GetUserRepoPermission(repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@ -73,8 +74,8 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// private non-organization repo
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
assert.NoError(t, repo.getUnits(db.GetEngine(db.DefaultContext)))
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
assert.NoError(t, repo.LoadUnits(db.DefaultContext))
// plain user
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
@ -86,7 +87,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) {
}
// change to collaborator to default write access
assert.NoError(t, repo.AddCollaborator(user))
assert.NoError(t, AddCollaborator(repo, user))
perm, err = GetUserRepoPermission(repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@ -94,7 +95,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) {
assert.True(t, perm.CanWrite(unit.Type))
}
assert.NoError(t, repo.ChangeCollaborationAccessMode(user.ID, perm_model.AccessModeRead))
assert.NoError(t, ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead))
perm, err = GetUserRepoPermission(repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@ -125,8 +126,8 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// public organization repo
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 32}).(*Repository)
assert.NoError(t, repo.getUnits(db.GetEngine(db.DefaultContext)))
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32}).(*repo_model.Repository)
assert.NoError(t, repo.LoadUnits(db.DefaultContext))
// plain user
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
@ -138,7 +139,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
}
// change to collaborator to default write access
assert.NoError(t, repo.AddCollaborator(user))
assert.NoError(t, AddCollaborator(repo, user))
perm, err = GetUserRepoPermission(repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@ -146,7 +147,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
assert.True(t, perm.CanWrite(unit.Type))
}
assert.NoError(t, repo.ChangeCollaborationAccessMode(user.ID, perm_model.AccessModeRead))
assert.NoError(t, ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead))
perm, err = GetUserRepoPermission(repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@ -187,8 +188,8 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// private organization repo
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 24}).(*Repository)
assert.NoError(t, repo.getUnits(db.GetEngine(db.DefaultContext)))
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24}).(*repo_model.Repository)
assert.NoError(t, repo.LoadUnits(db.DefaultContext))
// plain user
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
@ -200,7 +201,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
}
// change to collaborator to default write access
assert.NoError(t, repo.AddCollaborator(user))
assert.NoError(t, AddCollaborator(repo, user))
perm, err = GetUserRepoPermission(repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@ -208,7 +209,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
assert.True(t, perm.CanWrite(unit.Type))
}
assert.NoError(t, repo.ChangeCollaborationAccessMode(user.ID, perm_model.AccessModeRead))
assert.NoError(t, ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead))
perm, err = GetUserRepoPermission(repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {

View file

@ -8,6 +8,7 @@ import (
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
@ -28,7 +29,7 @@ func TestNewRepoRedirect(t *testing.T) {
// redirect to a completely new name
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
assert.NoError(t, newRepoRedirect(db.GetEngine(db.DefaultContext), repo.OwnerID, repo.ID, repo.Name, "newreponame"))
unittest.AssertExistsAndLoadBean(t, &RepoRedirect{
@ -47,7 +48,7 @@ func TestNewRepoRedirect2(t *testing.T) {
// redirect to previously used name
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
assert.NoError(t, newRepoRedirect(db.GetEngine(db.DefaultContext), repo.OwnerID, repo.ID, repo.Name, "oldrepo1"))
unittest.AssertExistsAndLoadBean(t, &RepoRedirect{
@ -66,7 +67,7 @@ func TestNewRepoRedirect3(t *testing.T) {
// redirect for a previously-unredirected repo
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
assert.NoError(t, newRepoRedirect(db.GetEngine(db.DefaultContext), repo.OwnerID, repo.ID, repo.Name, "newreponame"))
unittest.AssertExistsAndLoadBean(t, &RepoRedirect{

View file

@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/login"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
@ -144,7 +145,7 @@ Loop:
}
// SignWikiCommit determines if we should sign the commits to this repository wiki
func (repo *Repository) SignWikiCommit(u *user_model.User) (bool, string, *git.Signature, error) {
func SignWikiCommit(repo *repo_model.Repository, u *user_model.User) (bool, string, *git.Signature, error) {
rules := signingModeFromStrings(setting.Repository.Signing.Wiki)
signingKey, sig := SigningKey(repo.WikiPath())
if signingKey == "" {
@ -197,7 +198,7 @@ Loop:
}
// SignCRUDAction determines if we should sign a CRUD commit to this repository
func (repo *Repository) SignCRUDAction(u *user_model.User, tmpBasePath, parentCommit string) (bool, string, *git.Signature, error) {
func SignCRUDAction(repo *repo_model.Repository, u *user_model.User, tmpBasePath, parentCommit string) (bool, string, *git.Signature, error) {
rules := signingModeFromStrings(setting.Repository.Signing.CRUDActions)
signingKey, sig := SigningKey(repo.RepoPath())
if signingKey == "" {

View file

@ -25,7 +25,7 @@ import (
func TestMetas(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := &Repository{Name: "testRepo"}
repo := &repo_model.Repository{Name: "testRepo"}
repo.Owner = &user_model.User{Name: "testOwner"}
repo.OwnerName = repo.Owner.Name
@ -35,15 +35,15 @@ func TestMetas(t *testing.T) {
assert.Equal(t, "testRepo", metas["repo"])
assert.Equal(t, "testOwner", metas["user"])
externalTracker := RepoUnit{
externalTracker := repo_model.RepoUnit{
Type: unit.TypeExternalTracker,
Config: &ExternalTrackerConfig{
Config: &repo_model.ExternalTrackerConfig{
ExternalTrackerFormat: "https://someurl.com/{user}/{repo}/{issue}",
},
}
testSuccess := func(expectedStyle string) {
repo.Units = []*RepoUnit{&externalTracker}
repo.Units = []*repo_model.RepoUnit{&externalTracker}
repo.RenderingMetas = nil
metas := repo.ComposeMetas()
assert.Equal(t, expectedStyle, metas["style"])
@ -60,7 +60,7 @@ func TestMetas(t *testing.T) {
externalTracker.ExternalTrackerConfig().ExternalTrackerStyle = markup.IssueNameStyleNumeric
testSuccess(markup.IssueNameStyleNumeric)
repo, err := GetRepositoryByID(3)
repo, err := repo_model.GetRepositoryByID(3)
assert.NoError(t, err)
metas = repo.ComposeMetas()
@ -70,40 +70,11 @@ func TestMetas(t *testing.T) {
assert.Equal(t, ",owners,team1,", metas["teams"])
}
func TestGetRepositoryCount(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
count, err1 := GetRepositoryCount(db.DefaultContext, 10)
privateCount, err2 := GetPrivateRepositoryCount(&user_model.User{ID: int64(10)})
publicCount, err3 := GetPublicRepositoryCount(&user_model.User{ID: int64(10)})
assert.NoError(t, err1)
assert.NoError(t, err2)
assert.NoError(t, err3)
assert.Equal(t, int64(3), count)
assert.Equal(t, privateCount+publicCount, count)
}
func TestGetPublicRepositoryCount(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
count, err := GetPublicRepositoryCount(&user_model.User{ID: int64(10)})
assert.NoError(t, err)
assert.Equal(t, int64(1), count)
}
func TestGetPrivateRepositoryCount(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
count, err := GetPrivateRepositoryCount(&user_model.User{ID: int64(10)})
assert.NoError(t, err)
assert.Equal(t, int64(2), count)
}
func TestUpdateRepositoryVisibilityChanged(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// Get sample repo and change visibility
repo, err := GetRepositoryByID(9)
repo, err := repo_model.GetRepositoryByID(9)
assert.NoError(t, err)
repo.IsPrivate = true
@ -123,24 +94,24 @@ func TestGetUserFork(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// User13 has repo 11 forked from repo10
repo, err := GetRepositoryByID(10)
repo, err := repo_model.GetRepositoryByID(10)
assert.NoError(t, err)
assert.NotNil(t, repo)
repo, err = repo.GetUserFork(13)
repo, err = GetUserFork(repo.ID, 13)
assert.NoError(t, err)
assert.NotNil(t, repo)
repo, err = GetRepositoryByID(9)
repo, err = repo_model.GetRepositoryByID(9)
assert.NoError(t, err)
assert.NotNil(t, repo)
repo, err = repo.GetUserFork(13)
repo, err = GetUserFork(repo.ID, 13)
assert.NoError(t, err)
assert.Nil(t, repo)
}
func TestRepoAPIURL(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 10}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user12/repo10", repo.APIURL())
}
@ -152,9 +123,9 @@ func TestUploadAvatar(t *testing.T) {
png.Encode(&buff, myImage)
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 10}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository)
err := repo.UploadAvatar(buff.Bytes())
err := UploadRepoAvatar(repo, buff.Bytes())
assert.NoError(t, err)
assert.Equal(t, fmt.Sprintf("%d-%x", 10, md5.Sum(buff.Bytes())), repo.Avatar)
}
@ -166,9 +137,9 @@ func TestUploadBigAvatar(t *testing.T) {
png.Encode(&buff, myImage)
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 10}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository)
err := repo.UploadAvatar(buff.Bytes())
err := UploadRepoAvatar(repo, buff.Bytes())
assert.Error(t, err)
}
@ -179,12 +150,12 @@ func TestDeleteAvatar(t *testing.T) {
png.Encode(&buff, myImage)
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 10}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository)
err := repo.UploadAvatar(buff.Bytes())
err := UploadRepoAvatar(repo, buff.Bytes())
assert.NoError(t, err)
err = repo.DeleteAvatar()
err = DeleteRepoAvatar(repo)
assert.NoError(t, err)
assert.Equal(t, "", repo.Avatar)
@ -200,15 +171,15 @@ func TestRepoGetReviewers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// test public repo
repo1 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
reviewers, err := repo1.GetReviewers(2, 2)
reviewers, err := GetReviewers(repo1, 2, 2)
assert.NoError(t, err)
assert.Len(t, reviewers, 4)
// test private repo
repo2 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
reviewers, err = repo2.GetReviewers(2, 2)
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
reviewers, err = GetReviewers(repo2, 2, 2)
assert.NoError(t, err)
assert.Empty(t, reviewers)
}
@ -216,13 +187,13 @@ func TestRepoGetReviewers(t *testing.T) {
func TestRepoGetReviewerTeams(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo2 := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
teams, err := repo2.GetReviewerTeams()
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, &Repository{ID: 3}).(*Repository)
teams, err = repo3.GetReviewerTeams()
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)
}
@ -232,12 +203,12 @@ func TestLinkedRepository(t *testing.T) {
testCases := []struct {
name string
attachID int64
expectedRepo *Repository
expectedRepo *repo_model.Repository
expectedUnitType unit.Type
}{
{"LinkedIssue", 1, &Repository{ID: 1}, unit.TypeIssues},
{"LinkedComment", 3, &Repository{ID: 1}, unit.TypePullRequests},
{"LinkedRelease", 9, &Repository{ID: 1}, unit.TypeReleases},
{"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 {

View file

@ -9,6 +9,7 @@ import (
"os"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
@ -96,7 +97,7 @@ func (r *RepoTransfer) CanUserAcceptTransfer(u *user_model.User) bool {
// GetPendingRepositoryTransfer fetches the most recent and ongoing transfer
// process for the repository
func GetPendingRepositoryTransfer(repo *Repository) (*RepoTransfer, error) {
func GetPendingRepositoryTransfer(repo *repo_model.Repository) (*RepoTransfer, error) {
transfer := new(RepoTransfer)
has, err := db.GetEngine(db.DefaultContext).Where("repo_id = ? ", repo.ID).Get(transfer)
@ -118,7 +119,7 @@ func deleteRepositoryTransfer(e db.Engine, repoID int64) error {
// CancelRepositoryTransfer marks the repository as ready and remove pending transfer entry,
// thus cancel the transfer process.
func CancelRepositoryTransfer(repo *Repository) error {
func CancelRepositoryTransfer(repo *repo_model.Repository) error {
ctx, committer, err := db.TxContext()
if err != nil {
return err
@ -126,7 +127,7 @@ func CancelRepositoryTransfer(repo *Repository) error {
defer committer.Close()
sess := db.GetEngine(ctx)
repo.Status = RepositoryReady
repo.Status = repo_model.RepositoryReady
if err := updateRepositoryCols(sess, repo, "status"); err != nil {
return err
}
@ -139,11 +140,11 @@ func CancelRepositoryTransfer(repo *Repository) error {
}
// TestRepositoryReadyForTransfer make sure repo is ready to transfer
func TestRepositoryReadyForTransfer(status RepositoryStatus) error {
func TestRepositoryReadyForTransfer(status repo_model.RepositoryStatus) error {
switch status {
case RepositoryBeingMigrated:
case repo_model.RepositoryBeingMigrated:
return fmt.Errorf("repo is not ready, currently migrating")
case RepositoryPendingTransfer:
case repo_model.RepositoryPendingTransfer:
return ErrRepoTransferInProgress{}
}
return nil
@ -159,7 +160,7 @@ func CreatePendingRepositoryTransfer(doer, newOwner *user_model.User, repoID int
defer committer.Close()
sess := db.GetEngine(ctx)
repo, err := getRepositoryByID(sess, repoID)
repo, err := repo_model.GetRepositoryByIDCtx(ctx, repoID)
if err != nil {
return err
}
@ -169,13 +170,13 @@ func CreatePendingRepositoryTransfer(doer, newOwner *user_model.User, repoID int
return err
}
repo.Status = RepositoryPendingTransfer
repo.Status = repo_model.RepositoryPendingTransfer
if err := updateRepositoryCols(sess, repo, "status"); err != nil {
return err
}
// Check if new owner has repository with same name.
if has, err := isRepositoryExist(sess, newOwner, repo.Name); err != nil {
if has, err := repo_model.IsRepositoryExistCtx(ctx, newOwner, repo.Name); err != nil {
return fmt.Errorf("IsRepositoryExist: %v", err)
} else if has {
return ErrRepoAlreadyExist{newOwner.LowerName, repo.Name}
@ -202,7 +203,7 @@ func CreatePendingRepositoryTransfer(doer, newOwner *user_model.User, repoID int
}
// TransferOwnership transfers all corresponding repository items from old user to new one.
func TransferOwnership(doer *user_model.User, newOwnerName string, repo *Repository) (err error) {
func TransferOwnership(doer *user_model.User, newOwnerName string, repo *repo_model.Repository) (err error) {
repoRenamed := false
wikiRenamed := false
oldOwnerName := doer.Name
@ -218,14 +219,16 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *Reposit
}
if repoRenamed {
if err := util.Rename(RepoPath(newOwnerName, repo.Name), RepoPath(oldOwnerName, repo.Name)); err != nil {
log.Critical("Unable to move repository %s/%s directory from %s back to correct place %s: %v", oldOwnerName, repo.Name, RepoPath(newOwnerName, repo.Name), RepoPath(oldOwnerName, repo.Name), err)
if err := util.Rename(repo_model.RepoPath(newOwnerName, repo.Name), repo_model.RepoPath(oldOwnerName, repo.Name)); err != nil {
log.Critical("Unable to move repository %s/%s directory from %s back to correct place %s: %v", oldOwnerName, repo.Name,
repo_model.RepoPath(newOwnerName, repo.Name), repo_model.RepoPath(oldOwnerName, repo.Name), err)
}
}
if wikiRenamed {
if err := util.Rename(WikiPath(newOwnerName, repo.Name), WikiPath(oldOwnerName, repo.Name)); err != nil {
log.Critical("Unable to move wiki for repository %s/%s directory from %s back to correct place %s: %v", oldOwnerName, repo.Name, WikiPath(newOwnerName, repo.Name), WikiPath(oldOwnerName, repo.Name), err)
if err := util.Rename(repo_model.WikiPath(newOwnerName, repo.Name), repo_model.WikiPath(oldOwnerName, repo.Name)); err != nil {
log.Critical("Unable to move wiki for repository %s/%s directory from %s back to correct place %s: %v", oldOwnerName, repo.Name,
repo_model.WikiPath(newOwnerName, repo.Name), repo_model.WikiPath(oldOwnerName, repo.Name), err)
}
}
@ -250,7 +253,7 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *Reposit
newOwnerName = newOwner.Name // ensure capitalisation matches
// Check if new owner has repository with same name.
if has, err := isRepositoryExist(sess, newOwner, repo.Name); err != nil {
if has, err := repo_model.IsRepositoryExistCtx(ctx, newOwner, repo.Name); err != nil {
return fmt.Errorf("IsRepositoryExist: %v", err)
} else if has {
return ErrRepoAlreadyExist{newOwnerName, repo.Name}
@ -271,7 +274,7 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *Reposit
}
// Remove redundant collaborators.
collaborators, err := repo.getCollaborators(sess, db.ListOptions{})
collaborators, err := getCollaborators(sess, repo.ID, db.ListOptions{})
if err != nil {
return fmt.Errorf("getCollaborators: %v", err)
}
@ -316,12 +319,12 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *Reposit
}
for _, t := range teams {
if t.IncludesAllRepositories {
if err := t.addRepository(sess, repo); err != nil {
if err := t.addRepository(ctx, repo); err != nil {
return fmt.Errorf("addRepository: %v", err)
}
}
}
} else if err := repo.recalculateAccesses(sess); err != nil {
} else if err := recalculateAccesses(ctx, repo); err != nil {
// Organization called this in addRepository method.
return fmt.Errorf("recalculateAccesses: %v", err)
}
@ -378,19 +381,19 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *Reposit
return fmt.Errorf("Failed to create dir %s: %v", dir, err)
}
if err := util.Rename(RepoPath(oldOwner.Name, repo.Name), RepoPath(newOwner.Name, repo.Name)); err != nil {
if err := util.Rename(repo_model.RepoPath(oldOwner.Name, repo.Name), repo_model.RepoPath(newOwner.Name, repo.Name)); err != nil {
return fmt.Errorf("rename repository directory: %v", err)
}
repoRenamed = true
// Rename remote wiki repository to new path and delete local copy.
wikiPath := WikiPath(oldOwner.Name, repo.Name)
wikiPath := repo_model.WikiPath(oldOwner.Name, repo.Name)
if isExist, err := util.IsExist(wikiPath); err != nil {
log.Error("Unable to check if %s exists. Error: %v", wikiPath, err)
return err
} else if isExist {
if err := util.Rename(wikiPath, WikiPath(newOwner.Name, repo.Name)); err != nil {
if err := util.Rename(wikiPath, repo_model.WikiPath(newOwner.Name, repo.Name)); err != nil {
return fmt.Errorf("rename repository wiki: %v", err)
}
wikiRenamed = true
@ -399,7 +402,7 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *Reposit
if err := deleteRepositoryTransfer(sess, repo.ID); err != nil {
return fmt.Errorf("deleteRepositoryTransfer: %v", err)
}
repo.Status = RepositoryReady
repo.Status = repo_model.RepositoryReady
if err := updateRepositoryCols(sess, repo, "status"); err != nil {
return err
}

View file

@ -7,6 +7,7 @@ package models
import (
"testing"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@ -17,7 +18,7 @@ func TestRepositoryTransfer(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
transfer, err := GetPendingRepositoryTransfer(repo)
assert.NoError(t, err)

View file

@ -5,9 +5,11 @@
package models
import (
"context"
"fmt"
"code.gitea.io/gitea/models/db"
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/setting"
@ -166,9 +168,9 @@ func getRepoWatchersIDs(e db.Engine, repoID int64) ([]int64, error) {
Find(&ids)
}
// GetWatchers returns range of users watching given repository.
func (repo *Repository) GetWatchers(opts db.ListOptions) ([]*user_model.User, error) {
sess := db.GetEngine(db.DefaultContext).Where("watch.repo_id=?", repo.ID).
// GetRepoWatchers returns range of users watching given repository.
func GetRepoWatchers(repoID int64, opts db.ListOptions) ([]*user_model.User, error) {
sess := db.GetEngine(db.DefaultContext).Where("watch.repo_id=?", repoID).
Join("LEFT", "watch", "`user`.id=`watch`.user_id").
And("`watch`.mode<>?", RepoWatchModeDont)
if opts.Page > 0 {
@ -182,14 +184,16 @@ func (repo *Repository) GetWatchers(opts db.ListOptions) ([]*user_model.User, er
return users, sess.Find(&users)
}
func notifyWatchers(e db.Engine, actions ...*Action) error {
func notifyWatchers(ctx context.Context, actions ...*Action) error {
var watchers []*Watch
var repo *Repository
var repo *repo_model.Repository
var err error
var permCode []bool
var permIssue []bool
var permPR []bool
e := db.GetEngine(ctx)
for _, act := range actions {
repoChanged := repo == nil || repo.ID != act.RepoID
@ -212,7 +216,7 @@ func notifyWatchers(e db.Engine, actions ...*Action) error {
repo = act.Repo
// check repo owner exist.
if err := act.Repo.getOwner(e); err != nil {
if err := act.Repo.GetOwner(ctx); err != nil {
return fmt.Errorf("can't get repo owner: %v", err)
}
} else if act.Repo == nil {
@ -240,7 +244,7 @@ func notifyWatchers(e db.Engine, actions ...*Action) error {
permPR[i] = false
continue
}
perm, err := getUserRepoPermission(e, repo, user)
perm, err := getUserRepoPermission(ctx, repo, user)
if err != nil {
permCode[i] = false
permIssue[i] = false
@ -286,7 +290,7 @@ func notifyWatchers(e db.Engine, actions ...*Action) error {
// NotifyWatchers creates batch of actions for every watcher.
func NotifyWatchers(actions ...*Action) error {
return notifyWatchers(db.GetEngine(db.DefaultContext), actions...)
return notifyWatchers(db.DefaultContext, actions...)
}
// NotifyWatchersActions creates batch of actions for every watcher.
@ -297,7 +301,7 @@ func NotifyWatchersActions(acts []*Action) error {
}
defer committer.Close()
for _, act := range acts {
if err := notifyWatchers(db.GetEngine(ctx), act); err != nil {
if err := notifyWatchers(ctx, act); err != nil {
return err
}
}

View file

@ -8,6 +8,7 @@ import (
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/setting"
@ -33,17 +34,17 @@ func TestWatchRepo(t *testing.T) {
assert.NoError(t, WatchRepo(userID, repoID, true))
unittest.AssertExistsAndLoadBean(t, &Watch{RepoID: repoID, UserID: userID})
unittest.CheckConsistencyFor(t, &Repository{ID: repoID})
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID})
assert.NoError(t, WatchRepo(userID, repoID, false))
unittest.AssertNotExistsBean(t, &Watch{RepoID: repoID, UserID: userID})
unittest.CheckConsistencyFor(t, &Repository{ID: repoID})
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID})
}
func TestGetWatchers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
watches, err := GetWatchers(repo.ID)
assert.NoError(t, err)
// One watchers are inactive, thus minus 1
@ -60,16 +61,16 @@ func TestGetWatchers(t *testing.T) {
func TestRepository_GetWatchers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
watchers, err := repo.GetWatchers(db.ListOptions{Page: 1})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
watchers, err := GetRepoWatchers(repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Len(t, watchers, repo.NumWatches)
for _, watcher := range watchers {
unittest.AssertExistsAndLoadBean(t, &Watch{UserID: watcher.ID, RepoID: repo.ID})
}
repo = unittest.AssertExistsAndLoadBean(t, &Repository{ID: 9}).(*Repository)
watchers, err = repo.GetWatchers(db.ListOptions{Page: 1})
repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 9}).(*repo_model.Repository)
watchers, err = GetRepoWatchers(repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Len(t, watchers, 0)
}
@ -114,8 +115,8 @@ func TestNotifyWatchers(t *testing.T) {
func TestWatchIfAuto(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
watchers, err := repo.GetWatchers(db.ListOptions{Page: 1})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
watchers, err := GetRepoWatchers(repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Len(t, watchers, repo.NumWatches)
@ -125,13 +126,13 @@ func TestWatchIfAuto(t *testing.T) {
// Must not add watch
assert.NoError(t, WatchIfAuto(8, 1, true))
watchers, err = repo.GetWatchers(db.ListOptions{Page: 1})
watchers, err = GetRepoWatchers(repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Len(t, watchers, prevCount)
// Should not add watch
assert.NoError(t, WatchIfAuto(10, 1, true))
watchers, err = repo.GetWatchers(db.ListOptions{Page: 1})
watchers, err = GetRepoWatchers(repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Len(t, watchers, prevCount)
@ -139,31 +140,31 @@ func TestWatchIfAuto(t *testing.T) {
// Must not add watch
assert.NoError(t, WatchIfAuto(8, 1, true))
watchers, err = repo.GetWatchers(db.ListOptions{Page: 1})
watchers, err = GetRepoWatchers(repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Len(t, watchers, prevCount)
// Should not add watch
assert.NoError(t, WatchIfAuto(12, 1, false))
watchers, err = repo.GetWatchers(db.ListOptions{Page: 1})
watchers, err = GetRepoWatchers(repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Len(t, watchers, prevCount)
// Should add watch
assert.NoError(t, WatchIfAuto(12, 1, true))
watchers, err = repo.GetWatchers(db.ListOptions{Page: 1})
watchers, err = GetRepoWatchers(repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Len(t, watchers, prevCount+1)
// Should remove watch, inhibit from adding auto
assert.NoError(t, WatchRepo(12, 1, false))
watchers, err = repo.GetWatchers(db.ListOptions{Page: 1})
watchers, err = GetRepoWatchers(repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Len(t, watchers, prevCount)
// Must not add watch
assert.NoError(t, WatchIfAuto(12, 1, true))
watchers, err = repo.GetWatchers(db.ListOptions{Page: 1})
watchers, err = GetRepoWatchers(repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Len(t, watchers, prevCount)
}

View file

@ -5,6 +5,7 @@
package models
import (
"context"
"fmt"
"strings"
@ -85,20 +86,20 @@ func init() {
db.RegisterModel(new(Review))
}
func (r *Review) loadCodeComments(e db.Engine) (err error) {
func (r *Review) loadCodeComments(ctx context.Context) (err error) {
if r.CodeComments != nil {
return
}
if err = r.loadIssue(e); err != nil {
if err = r.loadIssue(db.GetEngine(ctx)); err != nil {
return
}
r.CodeComments, err = fetchCodeCommentsByReview(e, r.Issue, nil, r)
r.CodeComments, err = fetchCodeCommentsByReview(ctx, r.Issue, nil, r)
return
}
// LoadCodeComments loads CodeComments
func (r *Review) LoadCodeComments() error {
return r.loadCodeComments(db.GetEngine(db.DefaultContext))
return r.loadCodeComments(db.DefaultContext)
}
func (r *Review) loadIssue(e db.Engine) (err error) {
@ -136,11 +137,12 @@ func (r *Review) LoadReviewerTeam() error {
return r.loadReviewerTeam(db.GetEngine(db.DefaultContext))
}
func (r *Review) loadAttributes(e db.Engine) (err error) {
func (r *Review) loadAttributes(ctx context.Context) (err error) {
e := db.GetEngine(ctx)
if err = r.loadIssue(e); err != nil {
return
}
if err = r.loadCodeComments(e); err != nil {
if err = r.loadCodeComments(ctx); err != nil {
return
}
if err = r.loadReviewer(e); err != nil {
@ -154,7 +156,7 @@ func (r *Review) loadAttributes(e db.Engine) (err error) {
// LoadAttributes loads all attributes except CodeComments
func (r *Review) LoadAttributes() error {
return r.loadAttributes(db.GetEngine(db.DefaultContext))
return r.loadAttributes(db.DefaultContext)
}
func getReviewByID(e db.Engine, id int64) (*Review, error) {
@ -235,15 +237,15 @@ type CreateReviewOptions struct {
// IsOfficialReviewer check if at least one of the provided reviewers can make official reviews in issue (counts towards required approvals)
func IsOfficialReviewer(issue *Issue, reviewers ...*user_model.User) (bool, error) {
return isOfficialReviewer(db.GetEngine(db.DefaultContext), issue, reviewers...)
return isOfficialReviewer(db.DefaultContext, issue, reviewers...)
}
func isOfficialReviewer(e db.Engine, issue *Issue, reviewers ...*user_model.User) (bool, error) {
pr, err := getPullRequestByIssueID(e, issue.ID)
func isOfficialReviewer(ctx context.Context, issue *Issue, reviewers ...*user_model.User) (bool, error) {
pr, err := getPullRequestByIssueID(db.GetEngine(ctx), issue.ID)
if err != nil {
return false, err
}
if err = pr.loadProtectedBranch(e); err != nil {
if err = pr.loadProtectedBranch(ctx); err != nil {
return false, err
}
if pr.ProtectedBranch == nil {
@ -251,7 +253,7 @@ func isOfficialReviewer(e db.Engine, issue *Issue, reviewers ...*user_model.User
}
for _, reviewer := range reviewers {
official, err := pr.ProtectedBranch.isUserOfficialReviewer(e, reviewer)
official, err := isUserOfficialReviewer(ctx, pr.ProtectedBranch, reviewer)
if official || err != nil {
return official, err
}
@ -262,15 +264,15 @@ func isOfficialReviewer(e db.Engine, issue *Issue, reviewers ...*user_model.User
// IsOfficialReviewerTeam check if reviewer in this team can make official reviews in issue (counts towards required approvals)
func IsOfficialReviewerTeam(issue *Issue, team *Team) (bool, error) {
return isOfficialReviewerTeam(db.GetEngine(db.DefaultContext), issue, team)
return isOfficialReviewerTeam(db.DefaultContext, issue, team)
}
func isOfficialReviewerTeam(e db.Engine, issue *Issue, team *Team) (bool, error) {
pr, err := getPullRequestByIssueID(e, issue.ID)
func isOfficialReviewerTeam(ctx context.Context, issue *Issue, team *Team) (bool, error) {
pr, err := getPullRequestByIssueID(db.GetEngine(ctx), issue.ID)
if err != nil {
return false, err
}
if err = pr.loadProtectedBranch(e); err != nil {
if err = pr.loadProtectedBranch(ctx); err != nil {
return false, err
}
if pr.ProtectedBranch == nil {
@ -385,7 +387,7 @@ func SubmitReview(doer *user_model.User, issue *Issue, reviewType ReviewType, co
if _, err := sess.Exec("UPDATE `review` SET official=? WHERE issue_id=? AND reviewer_id=?", false, issue.ID, doer.ID); err != nil {
return nil, nil, err
}
if official, err = isOfficialReviewer(sess, issue, doer); err != nil {
if official, err = isOfficialReviewer(ctx, issue, doer); err != nil {
return nil, nil, err
}
}
@ -403,7 +405,7 @@ func SubmitReview(doer *user_model.User, issue *Issue, reviewType ReviewType, co
return nil, nil, err
}
} else {
if err := review.loadCodeComments(sess); err != nil {
if err := review.loadCodeComments(ctx); err != nil {
return nil, nil, err
}
if reviewType != ReviewTypeApprove && len(review.CodeComments) == 0 && len(strings.TrimSpace(content)) == 0 {
@ -415,7 +417,7 @@ func SubmitReview(doer *user_model.User, issue *Issue, reviewType ReviewType, co
if _, err := sess.Exec("UPDATE `review` SET official=? WHERE issue_id=? AND reviewer_id=?", false, issue.ID, doer.ID); err != nil {
return nil, nil, err
}
if official, err = isOfficialReviewer(sess, issue, doer); err != nil {
if official, err = isOfficialReviewer(ctx, issue, doer); err != nil {
return nil, nil, err
}
}
@ -647,7 +649,7 @@ func AddReviewRequest(issue *Issue, reviewer, doer *user_model.User) (*Comment,
return nil, nil
}
official, err := isOfficialReviewer(sess, issue, reviewer, doer)
official, err := isOfficialReviewer(ctx, issue, reviewer, doer)
if err != nil {
return nil, err
} else if official {
@ -705,7 +707,7 @@ func RemoveReviewRequest(issue *Issue, reviewer, doer *user_model.User) (*Commen
return nil, err
}
official, err := isOfficialReviewer(sess, issue, reviewer)
official, err := isOfficialReviewer(ctx, issue, reviewer)
if err != nil {
return nil, err
} else if official {
@ -756,11 +758,11 @@ func AddTeamReviewRequest(issue *Issue, reviewer *Team, doer *user_model.User) (
return nil, nil
}
official, err := isOfficialReviewerTeam(sess, issue, reviewer)
official, err := isOfficialReviewerTeam(ctx, issue, reviewer)
if err != nil {
return nil, fmt.Errorf("isOfficialReviewerTeam(): %v", err)
} else if !official {
if official, err = isOfficialReviewer(sess, issue, doer); err != nil {
if official, err = isOfficialReviewer(ctx, issue, doer); err != nil {
return nil, fmt.Errorf("isOfficialReviewer(): %v", err)
}
}
@ -819,7 +821,7 @@ func RemoveTeamReviewRequest(issue *Issue, reviewer *Team, doer *user_model.User
return nil, err
}
official, err := isOfficialReviewerTeam(sess, issue, reviewer)
official, err := isOfficialReviewerTeam(ctx, issue, reviewer)
if err != nil {
return nil, fmt.Errorf("isOfficialReviewerTeam(): %v", err)
}

View file

@ -5,11 +5,13 @@
package models
import (
"context"
"fmt"
"time"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/timeutil"
@ -221,13 +223,14 @@ func DeleteDeployKey(doer *user_model.User, id int64) error {
}
defer committer.Close()
if err := deleteDeployKey(db.GetEngine(ctx), doer, id); err != nil {
if err := deleteDeployKey(ctx, doer, id); err != nil {
return err
}
return committer.Commit()
}
func deleteDeployKey(sess db.Engine, doer *user_model.User, id int64) error {
func deleteDeployKey(ctx context.Context, doer *user_model.User, id int64) error {
sess := db.GetEngine(ctx)
key, err := getDeployKeyByID(sess, id)
if err != nil {
if IsErrDeployKeyNotExist(err) {
@ -238,9 +241,9 @@ func deleteDeployKey(sess db.Engine, doer *user_model.User, id int64) error {
// Check if user has access to delete this key.
if !doer.IsAdmin {
repo, err := getRepositoryByID(sess, key.RepoID)
repo, err := repo_model.GetRepositoryByIDCtx(ctx, key.RepoID)
if err != nil {
return fmt.Errorf("GetRepositoryByID: %v", err)
return fmt.Errorf("repo_model.GetRepositoryByID: %v", err)
}
has, err := isUserRepoAdmin(sess, repo, doer)
if err != nil {

View file

@ -6,6 +6,7 @@ package models
import (
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/timeutil"
)
@ -75,7 +76,7 @@ func isStaring(e db.Engine, userID, repoID int64) bool {
}
// GetStargazers returns the users that starred the repo.
func GetStargazers(repo *Repository, opts db.ListOptions) ([]*user_model.User, error) {
func GetStargazers(repo *repo_model.Repository, opts db.ListOptions) ([]*user_model.User, error) {
sess := db.GetEngine(db.DefaultContext).Where("star.repo_id = ?", repo.ID).
Join("LEFT", "star", "`user`.id = star.uid")
if opts.Page > 0 {

View file

@ -8,6 +8,7 @@ import (
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
@ -35,7 +36,7 @@ func TestIsStaring(t *testing.T) {
func TestRepository_GetStargazers(t *testing.T) {
// repo with stargazers
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 4}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository)
gazers, err := GetStargazers(repo, db.ListOptions{Page: 0})
assert.NoError(t, err)
if assert.Len(t, gazers, 1) {
@ -46,7 +47,7 @@ func TestRepository_GetStargazers(t *testing.T) {
func TestRepository_GetStargazers2(t *testing.T) {
// repo with stargazers
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
gazers, err := GetStargazers(repo, db.ListOptions{Page: 0})
assert.NoError(t, err)
assert.Len(t, gazers, 0)

View file

@ -48,7 +48,7 @@ func GetStatistic() (stats Statistic) {
stats.Counter.User = user_model.CountUsers()
stats.Counter.Org = CountOrganizations()
stats.Counter.PublicKey, _ = e.Count(new(PublicKey))
stats.Counter.Repo = CountRepositories(true)
stats.Counter.Repo = repo_model.CountRepositories(true)
stats.Counter.Watch, _ = e.Count(new(Watch))
stats.Counter.Star, _ = e.Count(new(Star))
stats.Counter.Action, _ = e.Count(new(Action))
@ -95,7 +95,7 @@ func GetStatistic() (stats Statistic) {
stats.Counter.Comment, _ = e.Count(new(Comment))
stats.Counter.Oauth = 0
stats.Counter.Follow, _ = e.Count(new(user_model.Follow))
stats.Counter.Mirror, _ = e.Count(new(Mirror))
stats.Counter.Mirror, _ = e.Count(new(repo_model.Mirror))
stats.Counter.Release, _ = e.Count(new(Release))
stats.Counter.LoginSource = login.CountSources()
stats.Counter.Webhook, _ = e.Count(new(webhook.Webhook))

View file

@ -8,6 +8,7 @@ import (
"fmt"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/migration"
@ -23,12 +24,12 @@ import (
// Task represents a task
type Task struct {
ID int64
DoerID int64 `xorm:"index"` // operator
Doer *user_model.User `xorm:"-"`
OwnerID int64 `xorm:"index"` // repo owner id, when creating, the repoID maybe zero
Owner *user_model.User `xorm:"-"`
RepoID int64 `xorm:"index"`
Repo *Repository `xorm:"-"`
DoerID int64 `xorm:"index"` // operator
Doer *user_model.User `xorm:"-"`
OwnerID int64 `xorm:"index"` // repo owner id, when creating, the repoID maybe zero
Owner *user_model.User `xorm:"-"`
RepoID int64 `xorm:"index"`
Repo *repo_model.Repository `xorm:"-"`
Type structs.TaskType
Status structs.TaskStatus `xorm:"index"`
StartTime timeutil.TimeStamp
@ -57,12 +58,12 @@ func (task *Task) loadRepo(e db.Engine) error {
if task.Repo != nil {
return nil
}
var repo Repository
var repo repo_model.Repository
has, err := e.ID(task.RepoID).Get(&repo)
if err != nil {
return err
} else if !has {
return ErrRepoNotExist{
return repo_model.ErrRepoNotExist{
ID: task.RepoID,
}
}

View file

@ -10,6 +10,7 @@ import (
"strings"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/builder"
@ -253,7 +254,7 @@ func AddTopic(repoID int64, topicName string) (*Topic, error) {
return nil, err
}
if _, err := sess.ID(repoID).Cols("topics").Update(&Repository{
if _, err := sess.ID(repoID).Cols("topics").Update(&repo_model.Repository{
Topics: topicNames,
}); err != nil {
return nil, err
@ -347,7 +348,7 @@ func SaveTopics(repoID int64, topicNames ...string) error {
return err
}
if _, err := sess.ID(repoID).Cols("topics").Update(&Repository{
if _, err := sess.ID(repoID).Cols("topics").Update(&repo_model.Repository{
Topics: topicNames,
}); err != nil {
return err

View file

@ -10,14 +10,15 @@ import (
"strings"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
)
// PushUpdateDeleteTagsContext updates a number of delete tags with context
func PushUpdateDeleteTagsContext(ctx context.Context, repo *Repository, tags []string) error {
func PushUpdateDeleteTagsContext(ctx context.Context, repo *repo_model.Repository, tags []string) error {
return pushUpdateDeleteTags(db.GetEngine(ctx), repo, tags)
}
func pushUpdateDeleteTags(e db.Engine, repo *Repository, tags []string) error {
func pushUpdateDeleteTags(e db.Engine, repo *repo_model.Repository, tags []string) error {
if len(tags) == 0 {
return nil
}
@ -47,7 +48,7 @@ func pushUpdateDeleteTags(e db.Engine, repo *Repository, tags []string) error {
}
// PushUpdateDeleteTag must be called for any push actions to delete tag
func PushUpdateDeleteTag(repo *Repository, tagName string) error {
func PushUpdateDeleteTag(repo *repo_model.Repository, tagName string) error {
rel, err := GetRelease(repo.ID, tagName)
if err != nil {
if IsErrReleaseNotExist(err) {
@ -72,7 +73,7 @@ func PushUpdateDeleteTag(repo *Repository, tagName string) error {
}
// SaveOrUpdateTag must be called for any push actions to add tag
func SaveOrUpdateTag(repo *Repository, newRel *Release) error {
func SaveOrUpdateTag(repo *repo_model.Repository, newRel *Release) error {
rel, err := GetRelease(repo.ID, newRel.TagName)
if err != nil && !IsErrReleaseNotExist(err) {
return fmt.Errorf("GetRelease: %v", err)

View file

@ -13,6 +13,7 @@ import (
_ "image/jpeg" // Needed for jpeg support
"code.gitea.io/gitea/models/db"
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/setting"
@ -151,7 +152,7 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) {
Where("watch.user_id = ?", u.ID).And("watch.mode <>?", RepoWatchModeDont).Find(&watchedRepoIDs); err != nil {
return fmt.Errorf("get all watches: %v", err)
}
if _, err = e.Decr("num_watches").In("id", watchedRepoIDs).NoAutoTime().Update(new(Repository)); err != nil {
if _, err = e.Decr("num_watches").In("id", watchedRepoIDs).NoAutoTime().Update(new(repo_model.Repository)); err != nil {
return fmt.Errorf("decrease repository num_watches: %v", err)
}
// ***** END: Watch *****
@ -161,7 +162,7 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) {
if err = e.Table("star").Cols("star.repo_id").
Where("star.uid = ?", u.ID).Find(&starredRepoIDs); err != nil {
return fmt.Errorf("get all stars: %v", err)
} else if _, err = e.Decr("num_stars").In("id", starredRepoIDs).NoAutoTime().Update(new(Repository)); err != nil {
} else if _, err = e.Decr("num_stars").In("id", starredRepoIDs).NoAutoTime().Update(new(repo_model.Repository)); err != nil {
return fmt.Errorf("decrease repository num_stars: %v", err)
}
// ***** END: Star *****
@ -273,7 +274,7 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) {
}
// GetStarredRepos returns the repos starred by a particular user
func GetStarredRepos(userID int64, private bool, listOptions db.ListOptions) ([]*Repository, error) {
func GetStarredRepos(userID int64, private bool, listOptions db.ListOptions) ([]*repo_model.Repository, error) {
sess := db.GetEngine(db.DefaultContext).Where("star.uid=?", userID).
Join("LEFT", "star", "`repository`.id=`star`.repo_id")
if !private {
@ -283,16 +284,16 @@ func GetStarredRepos(userID int64, private bool, listOptions db.ListOptions) ([]
if listOptions.Page != 0 {
sess = db.SetSessionPagination(sess, &listOptions)
repos := make([]*Repository, 0, listOptions.PageSize)
repos := make([]*repo_model.Repository, 0, listOptions.PageSize)
return repos, sess.Find(&repos)
}
repos := make([]*Repository, 0, 10)
repos := make([]*repo_model.Repository, 0, 10)
return repos, sess.Find(&repos)
}
// GetWatchedRepos returns the repos watched by a particular user
func GetWatchedRepos(userID int64, private bool, listOptions db.ListOptions) ([]*Repository, int64, error) {
func GetWatchedRepos(userID int64, private bool, listOptions db.ListOptions) ([]*repo_model.Repository, int64, error) {
sess := db.GetEngine(db.DefaultContext).Where("watch.user_id=?", userID).
And("`watch`.mode<>?", RepoWatchModeDont).
Join("LEFT", "watch", "`repository`.id=`watch`.repo_id")
@ -303,12 +304,12 @@ func GetWatchedRepos(userID int64, private bool, listOptions db.ListOptions) ([]
if listOptions.Page != 0 {
sess = db.SetSessionPagination(sess, &listOptions)
repos := make([]*Repository, 0, listOptions.PageSize)
repos := make([]*repo_model.Repository, 0, listOptions.PageSize)
total, err := sess.FindAndCount(&repos)
return repos, total, err
}
repos := make([]*Repository, 0, 10)
repos := make([]*repo_model.Repository, 0, 10)
total, err := sess.FindAndCount(&repos)
return repos, total, err
}