Move some code into models/git (#19879)
* Move access and repo permission to models/perm/access * fix test * Move some git related files into sub package models/git * Fix build * fix git test * move lfs to sub package * move more git related functions to models/git * Move functions sequence * Some improvements per @KN4CK3R and @delvh
This commit is contained in:
parent
a9dc9b06e4
commit
110fc57cbc
67 changed files with 549 additions and 495 deletions
80
models/branch.go
Normal file
80
models/branch.go
Normal file
|
@ -0,0 +1,80 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
)
|
||||
|
||||
// HasEnoughApprovals returns true if pr has enough granted approvals.
|
||||
func HasEnoughApprovals(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool {
|
||||
if protectBranch.RequiredApprovals == 0 {
|
||||
return true
|
||||
}
|
||||
return GetGrantedApprovalsCount(ctx, protectBranch, pr) >= protectBranch.RequiredApprovals
|
||||
}
|
||||
|
||||
// GetGrantedApprovalsCount returns the number of granted approvals for pr. A granted approval must be authored by a user in an approval whitelist.
|
||||
func GetGrantedApprovalsCount(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) int64 {
|
||||
sess := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID).
|
||||
And("type = ?", ReviewTypeApprove).
|
||||
And("official = ?", true).
|
||||
And("dismissed = ?", false)
|
||||
if protectBranch.DismissStaleApprovals {
|
||||
sess = sess.And("stale = ?", false)
|
||||
}
|
||||
approvals, err := sess.Count(new(Review))
|
||||
if err != nil {
|
||||
log.Error("GetGrantedApprovalsCount: %v", err)
|
||||
return 0
|
||||
}
|
||||
|
||||
return approvals
|
||||
}
|
||||
|
||||
// MergeBlockedByRejectedReview returns true if merge is blocked by rejected reviews
|
||||
func MergeBlockedByRejectedReview(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool {
|
||||
if !protectBranch.BlockOnRejectedReviews {
|
||||
return false
|
||||
}
|
||||
rejectExist, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID).
|
||||
And("type = ?", ReviewTypeReject).
|
||||
And("official = ?", true).
|
||||
And("dismissed = ?", false).
|
||||
Exist(new(Review))
|
||||
if err != nil {
|
||||
log.Error("MergeBlockedByRejectedReview: %v", err)
|
||||
return true
|
||||
}
|
||||
|
||||
return rejectExist
|
||||
}
|
||||
|
||||
// MergeBlockedByOfficialReviewRequests block merge because of some review request to official reviewer
|
||||
// of from official review
|
||||
func MergeBlockedByOfficialReviewRequests(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool {
|
||||
if !protectBranch.BlockOnOfficialReviewRequests {
|
||||
return false
|
||||
}
|
||||
has, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID).
|
||||
And("type = ?", ReviewTypeRequest).
|
||||
And("official = ?", true).
|
||||
Exist(new(Review))
|
||||
if err != nil {
|
||||
log.Error("MergeBlockedByOfficialReviewRequests: %v", err)
|
||||
return true
|
||||
}
|
||||
|
||||
return has
|
||||
}
|
||||
|
||||
// MergeBlockedByOutdatedBranch returns true if merge is blocked by an outdated head branch
|
||||
func MergeBlockedByOutdatedBranch(protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool {
|
||||
return protectBranch.BlockOnOutdatedBranch && pr.CommitsBehind > 0
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
// Copyright 2021 Gitea. 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
|
||||
|
||||
import (
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
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 *repo_model.Repository) []*SignCommitWithStatuses {
|
||||
return ParseCommitsWithStatus(
|
||||
asymkey_model.ParseCommitsWithSignature(
|
||||
user_model.ValidateCommitsWithEmails(commits),
|
||||
repo.GetTrustModel(),
|
||||
func(user *user_model.User) (bool, error) {
|
||||
return IsOwnerMemberCollaborator(repo, user.ID)
|
||||
},
|
||||
),
|
||||
repo,
|
||||
)
|
||||
}
|
|
@ -8,7 +8,6 @@ package models
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
)
|
||||
|
@ -145,83 +144,6 @@ func (err ErrAccessTokenEmpty) Error() string {
|
|||
return "access token is empty"
|
||||
}
|
||||
|
||||
//.____ ____________________
|
||||
//| | \_ _____/ _____/
|
||||
//| | | __) \_____ \
|
||||
//| |___| \ / \
|
||||
//|_______ \___ / /_______ /
|
||||
// \/ \/ \/
|
||||
|
||||
// ErrLFSLockNotExist represents a "LFSLockNotExist" kind of error.
|
||||
type ErrLFSLockNotExist struct {
|
||||
ID int64
|
||||
RepoID int64
|
||||
Path string
|
||||
}
|
||||
|
||||
// IsErrLFSLockNotExist checks if an error is a ErrLFSLockNotExist.
|
||||
func IsErrLFSLockNotExist(err error) bool {
|
||||
_, ok := err.(ErrLFSLockNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrLFSLockNotExist) Error() string {
|
||||
return fmt.Sprintf("lfs lock does not exist [id: %d, rid: %d, path: %s]", err.ID, err.RepoID, err.Path)
|
||||
}
|
||||
|
||||
// ErrLFSUnauthorizedAction represents a "LFSUnauthorizedAction" kind of error.
|
||||
type ErrLFSUnauthorizedAction struct {
|
||||
RepoID int64
|
||||
UserName string
|
||||
Mode perm.AccessMode
|
||||
}
|
||||
|
||||
// IsErrLFSUnauthorizedAction checks if an error is a ErrLFSUnauthorizedAction.
|
||||
func IsErrLFSUnauthorizedAction(err error) bool {
|
||||
_, ok := err.(ErrLFSUnauthorizedAction)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrLFSUnauthorizedAction) Error() string {
|
||||
if err.Mode == perm.AccessModeWrite {
|
||||
return fmt.Sprintf("User %s doesn't have write access for lfs lock [rid: %d]", err.UserName, err.RepoID)
|
||||
}
|
||||
return fmt.Sprintf("User %s doesn't have read access for lfs lock [rid: %d]", err.UserName, err.RepoID)
|
||||
}
|
||||
|
||||
// ErrLFSLockAlreadyExist represents a "LFSLockAlreadyExist" kind of error.
|
||||
type ErrLFSLockAlreadyExist struct {
|
||||
RepoID int64
|
||||
Path string
|
||||
}
|
||||
|
||||
// IsErrLFSLockAlreadyExist checks if an error is a ErrLFSLockAlreadyExist.
|
||||
func IsErrLFSLockAlreadyExist(err error) bool {
|
||||
_, ok := err.(ErrLFSLockAlreadyExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrLFSLockAlreadyExist) Error() string {
|
||||
return fmt.Sprintf("lfs lock already exists [rid: %d, path: %s]", err.RepoID, err.Path)
|
||||
}
|
||||
|
||||
// ErrLFSFileLocked represents a "LFSFileLocked" kind of error.
|
||||
type ErrLFSFileLocked struct {
|
||||
RepoID int64
|
||||
Path string
|
||||
UserName string
|
||||
}
|
||||
|
||||
// IsErrLFSFileLocked checks if an error is a ErrLFSFileLocked.
|
||||
func IsErrLFSFileLocked(err error) bool {
|
||||
_, ok := err.(ErrLFSFileLocked)
|
||||
return ok
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
// ErrNoPendingRepoTransfer is an error type for repositories without a pending
|
||||
// transfer request
|
||||
type ErrNoPendingRepoTransfer struct {
|
||||
|
|
|
@ -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 git
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -129,10 +129,11 @@ func IsUserMergeWhitelisted(ctx context.Context, protectBranch *ProtectedBranch,
|
|||
|
||||
// IsUserOfficialReviewer check if user is official reviewer for the branch (counts towards required approvals)
|
||||
func IsUserOfficialReviewer(protectBranch *ProtectedBranch, user *user_model.User) (bool, error) {
|
||||
return isUserOfficialReviewer(db.DefaultContext, protectBranch, user)
|
||||
return IsUserOfficialReviewerCtx(db.DefaultContext, protectBranch, user)
|
||||
}
|
||||
|
||||
func isUserOfficialReviewer(ctx context.Context, protectBranch *ProtectedBranch, user *user_model.User) (bool, error) {
|
||||
// IsUserOfficialReviewerCtx check if user is official reviewer for the branch (counts towards required approvals)
|
||||
func IsUserOfficialReviewerCtx(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
|
||||
|
@ -159,73 +160,6 @@ func isUserOfficialReviewer(ctx context.Context, protectBranch *ProtectedBranch,
|
|||
return inTeam, nil
|
||||
}
|
||||
|
||||
// HasEnoughApprovals returns true if pr has enough granted approvals.
|
||||
func (protectBranch *ProtectedBranch) HasEnoughApprovals(ctx context.Context, pr *PullRequest) bool {
|
||||
if protectBranch.RequiredApprovals == 0 {
|
||||
return true
|
||||
}
|
||||
return protectBranch.GetGrantedApprovalsCount(ctx, pr) >= protectBranch.RequiredApprovals
|
||||
}
|
||||
|
||||
// GetGrantedApprovalsCount returns the number of granted approvals for pr. A granted approval must be authored by a user in an approval whitelist.
|
||||
func (protectBranch *ProtectedBranch) GetGrantedApprovalsCount(ctx context.Context, pr *PullRequest) int64 {
|
||||
sess := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID).
|
||||
And("type = ?", ReviewTypeApprove).
|
||||
And("official = ?", true).
|
||||
And("dismissed = ?", false)
|
||||
if protectBranch.DismissStaleApprovals {
|
||||
sess = sess.And("stale = ?", false)
|
||||
}
|
||||
approvals, err := sess.Count(new(Review))
|
||||
if err != nil {
|
||||
log.Error("GetGrantedApprovalsCount: %v", err)
|
||||
return 0
|
||||
}
|
||||
|
||||
return approvals
|
||||
}
|
||||
|
||||
// MergeBlockedByRejectedReview returns true if merge is blocked by rejected reviews
|
||||
func (protectBranch *ProtectedBranch) MergeBlockedByRejectedReview(ctx context.Context, pr *PullRequest) bool {
|
||||
if !protectBranch.BlockOnRejectedReviews {
|
||||
return false
|
||||
}
|
||||
rejectExist, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID).
|
||||
And("type = ?", ReviewTypeReject).
|
||||
And("official = ?", true).
|
||||
And("dismissed = ?", false).
|
||||
Exist(new(Review))
|
||||
if err != nil {
|
||||
log.Error("MergeBlockedByRejectedReview: %v", err)
|
||||
return true
|
||||
}
|
||||
|
||||
return rejectExist
|
||||
}
|
||||
|
||||
// MergeBlockedByOfficialReviewRequests block merge because of some review request to official reviewer
|
||||
// of from official review
|
||||
func (protectBranch *ProtectedBranch) MergeBlockedByOfficialReviewRequests(ctx context.Context, pr *PullRequest) bool {
|
||||
if !protectBranch.BlockOnOfficialReviewRequests {
|
||||
return false
|
||||
}
|
||||
has, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID).
|
||||
And("type = ?", ReviewTypeRequest).
|
||||
And("official = ?", true).
|
||||
Exist(new(Review))
|
||||
if err != nil {
|
||||
log.Error("MergeBlockedByOfficialReviewRequests: %v", err)
|
||||
return true
|
||||
}
|
||||
|
||||
return has
|
||||
}
|
||||
|
||||
// MergeBlockedByOutdatedBranch returns true if merge is blocked by an outdated head branch
|
||||
func (protectBranch *ProtectedBranch) MergeBlockedByOutdatedBranch(pr *PullRequest) bool {
|
||||
return protectBranch.BlockOnOutdatedBranch && pr.CommitsBehind > 0
|
||||
}
|
||||
|
||||
// GetProtectedFilePatterns parses a semicolon separated list of protected file patterns and returns a glob.Glob slice
|
||||
func (protectBranch *ProtectedBranch) GetProtectedFilePatterns() []glob.Glob {
|
||||
return getFilePatterns(protectBranch.ProtectedFilePatterns)
|
||||
|
@ -252,13 +186,13 @@ func getFilePatterns(filePatterns string) []glob.Glob {
|
|||
}
|
||||
|
||||
// MergeBlockedByProtectedFiles returns true if merge is blocked by protected files change
|
||||
func (protectBranch *ProtectedBranch) MergeBlockedByProtectedFiles(pr *PullRequest) bool {
|
||||
func (protectBranch *ProtectedBranch) MergeBlockedByProtectedFiles(changedProtectedFiles []string) bool {
|
||||
glob := protectBranch.GetProtectedFilePatterns()
|
||||
if len(glob) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return len(pr.ChangedProtectedFiles) > 0
|
||||
return len(changedProtectedFiles) > 0
|
||||
}
|
||||
|
||||
// IsProtectedFile return if path is protected
|
||||
|
@ -642,7 +576,7 @@ func RenameBranch(repo *repo_model.Repository, from, to string, gitAction func(i
|
|||
}
|
||||
|
||||
// 3. Update all not merged pull request base branch name
|
||||
_, err = sess.Table(new(PullRequest)).Where("base_repo_id=? AND base_branch=? AND has_merged=?",
|
||||
_, err = sess.Table("pull_request").Where("base_repo_id=? AND base_branch=? AND has_merged=?",
|
||||
repo.ID, from, false).
|
||||
Update(map[string]interface{}{"base_branch": to})
|
||||
if err != nil {
|
|
@ -2,12 +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 git_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
|
@ -17,24 +19,24 @@ import (
|
|||
func TestAddDeletedBranch(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
|
||||
firstBranch := unittest.AssertExistsAndLoadBean(t, &DeletedBranch{ID: 1}).(*DeletedBranch)
|
||||
firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}).(*git_model.DeletedBranch)
|
||||
|
||||
assert.Error(t, AddDeletedBranch(repo.ID, firstBranch.Name, firstBranch.Commit, firstBranch.DeletedByID))
|
||||
assert.NoError(t, AddDeletedBranch(repo.ID, "test", "5655464564554545466464656", int64(1)))
|
||||
assert.Error(t, git_model.AddDeletedBranch(repo.ID, firstBranch.Name, firstBranch.Commit, firstBranch.DeletedByID))
|
||||
assert.NoError(t, git_model.AddDeletedBranch(repo.ID, "test", "5655464564554545466464656", int64(1)))
|
||||
}
|
||||
|
||||
func TestGetDeletedBranches(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
|
||||
|
||||
branches, err := GetDeletedBranches(repo.ID)
|
||||
branches, err := git_model.GetDeletedBranches(repo.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, branches, 2)
|
||||
}
|
||||
|
||||
func TestGetDeletedBranch(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
firstBranch := unittest.AssertExistsAndLoadBean(t, &DeletedBranch{ID: 1}).(*DeletedBranch)
|
||||
firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}).(*git_model.DeletedBranch)
|
||||
|
||||
assert.NotNil(t, getDeletedBranch(t, firstBranch))
|
||||
}
|
||||
|
@ -42,8 +44,8 @@ func TestGetDeletedBranch(t *testing.T) {
|
|||
func TestDeletedBranchLoadUser(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
firstBranch := unittest.AssertExistsAndLoadBean(t, &DeletedBranch{ID: 1}).(*DeletedBranch)
|
||||
secondBranch := unittest.AssertExistsAndLoadBean(t, &DeletedBranch{ID: 2}).(*DeletedBranch)
|
||||
firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}).(*git_model.DeletedBranch)
|
||||
secondBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 2}).(*git_model.DeletedBranch)
|
||||
|
||||
branch := getDeletedBranch(t, firstBranch)
|
||||
assert.Nil(t, branch.DeletedBy)
|
||||
|
@ -62,18 +64,18 @@ func TestRemoveDeletedBranch(t *testing.T) {
|
|||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
|
||||
|
||||
firstBranch := unittest.AssertExistsAndLoadBean(t, &DeletedBranch{ID: 1}).(*DeletedBranch)
|
||||
firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}).(*git_model.DeletedBranch)
|
||||
|
||||
err := RemoveDeletedBranchByID(repo.ID, 1)
|
||||
err := git_model.RemoveDeletedBranchByID(repo.ID, 1)
|
||||
assert.NoError(t, err)
|
||||
unittest.AssertNotExistsBean(t, firstBranch)
|
||||
unittest.AssertExistsAndLoadBean(t, &DeletedBranch{ID: 2})
|
||||
unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 2})
|
||||
}
|
||||
|
||||
func getDeletedBranch(t *testing.T, branch *DeletedBranch) *DeletedBranch {
|
||||
func getDeletedBranch(t *testing.T, branch *git_model.DeletedBranch) *git_model.DeletedBranch {
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
|
||||
|
||||
deletedBranch, err := GetDeletedBranchByID(repo.ID, branch.ID)
|
||||
deletedBranch, err := git_model.GetDeletedBranchByID(repo.ID, branch.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, branch.ID, deletedBranch.ID)
|
||||
assert.Equal(t, branch.Name, deletedBranch.Name)
|
||||
|
@ -85,12 +87,12 @@ func getDeletedBranch(t *testing.T, branch *DeletedBranch) *DeletedBranch {
|
|||
|
||||
func TestFindRenamedBranch(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
branch, exist, err := FindRenamedBranch(1, "dev")
|
||||
branch, exist, err := git_model.FindRenamedBranch(1, "dev")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, exist)
|
||||
assert.Equal(t, "master", branch.To)
|
||||
|
||||
_, exist, err = FindRenamedBranch(1, "unknow")
|
||||
_, exist, err = git_model.FindRenamedBranch(1, "unknow")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, false, exist)
|
||||
}
|
||||
|
@ -103,13 +105,13 @@ func TestRenameBranch(t *testing.T) {
|
|||
ctx, committer, err := db.TxContext()
|
||||
defer committer.Close()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, UpdateProtectBranch(ctx, repo1, &ProtectedBranch{
|
||||
assert.NoError(t, git_model.UpdateProtectBranch(ctx, repo1, &git_model.ProtectedBranch{
|
||||
RepoID: repo1.ID,
|
||||
BranchName: "master",
|
||||
}, WhitelistOptions{}))
|
||||
}, git_model.WhitelistOptions{}))
|
||||
assert.NoError(t, committer.Commit())
|
||||
|
||||
assert.NoError(t, RenameBranch(repo1, "master", "main", func(isDefault bool) error {
|
||||
assert.NoError(t, git_model.RenameBranch(repo1, "master", "main", func(isDefault bool) error {
|
||||
_isDefault = isDefault
|
||||
return nil
|
||||
}))
|
||||
|
@ -118,18 +120,18 @@ func TestRenameBranch(t *testing.T) {
|
|||
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
|
||||
pull := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 1}).(*models.PullRequest) // merged
|
||||
assert.Equal(t, "master", pull.BaseBranch)
|
||||
|
||||
pull = unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 2}).(*PullRequest) // open
|
||||
pull = unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) // open
|
||||
assert.Equal(t, "main", pull.BaseBranch)
|
||||
|
||||
renamedBranch := unittest.AssertExistsAndLoadBean(t, &RenamedBranch{ID: 2}).(*RenamedBranch)
|
||||
renamedBranch := unittest.AssertExistsAndLoadBean(t, &git_model.RenamedBranch{ID: 2}).(*git_model.RenamedBranch)
|
||||
assert.Equal(t, "master", renamedBranch.From)
|
||||
assert.Equal(t, "main", renamedBranch.To)
|
||||
assert.Equal(t, int64(1), renamedBranch.RepoID)
|
||||
|
||||
unittest.AssertExistsAndLoadBean(t, &ProtectedBranch{
|
||||
unittest.AssertExistsAndLoadBean(t, &git_model.ProtectedBranch{
|
||||
RepoID: repo1.ID,
|
||||
BranchName: "main",
|
||||
})
|
||||
|
@ -143,7 +145,7 @@ func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) {
|
|||
// is actually on repo with ID 1.
|
||||
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
|
||||
|
||||
deletedBranch, err := GetDeletedBranchByID(repo2.ID, 1)
|
||||
deletedBranch, err := git_model.GetDeletedBranchByID(repo2.ID, 1)
|
||||
|
||||
// Expect no error, and the returned branch is nil.
|
||||
assert.NoError(t, err)
|
||||
|
@ -153,7 +155,7 @@ func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) {
|
|||
// This should return the deletedBranch.
|
||||
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
|
||||
|
||||
deletedBranch, err = GetDeletedBranchByID(repo1.ID, 1)
|
||||
deletedBranch, err = git_model.GetDeletedBranchByID(repo1.ID, 1)
|
||||
|
||||
// Expect no error, and the returned branch to be not nil.
|
||||
assert.NoError(t, err)
|
|
@ -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 git
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -16,6 +16,7 @@ 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/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
|
@ -178,7 +179,7 @@ func GetCommitStatuses(repo *repo_model.Repository, sha string, opts *CommitStat
|
|||
opts.Page = 1
|
||||
}
|
||||
if opts.PageSize <= 0 {
|
||||
opts.Page = ItemsPerPage
|
||||
opts.Page = setting.ItemsPerPage
|
||||
}
|
||||
|
||||
countSession := listCommitStatusesStatement(repo, sha, opts)
|
||||
|
@ -353,3 +354,17 @@ func ParseCommitsWithStatus(oldCommits []*asymkey_model.SignCommit, repo *repo_m
|
|||
func hashCommitStatusContext(context string) string {
|
||||
return fmt.Sprintf("%x", sha1.Sum([]byte(context)))
|
||||
}
|
||||
|
||||
// ConvertFromGitCommit converts git commits into SignCommitWithStatuses
|
||||
func ConvertFromGitCommit(commits []*git.Commit, repo *repo_model.Repository) []*SignCommitWithStatuses {
|
||||
return ParseCommitsWithStatus(
|
||||
asymkey_model.ParseCommitsWithSignature(
|
||||
user_model.ValidateCommitsWithEmails(commits),
|
||||
repo.GetTrustModel(),
|
||||
func(user *user_model.User) (bool, error) {
|
||||
return repo_model.IsOwnerMemberCollaborator(repo, user.ID)
|
||||
},
|
||||
),
|
||||
repo,
|
||||
)
|
||||
}
|
|
@ -2,12 +2,13 @@
|
|||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package models
|
||||
package git_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
|
@ -22,7 +23,7 @@ func TestGetCommitStatuses(t *testing.T) {
|
|||
|
||||
sha1 := "1234123412341234123412341234123412341234"
|
||||
|
||||
statuses, maxResults, err := GetCommitStatuses(repo1, sha1, &CommitStatusOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 50}})
|
||||
statuses, maxResults, err := git_model.GetCommitStatuses(repo1, sha1, &git_model.CommitStatusOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 50}})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int(maxResults), 5)
|
||||
assert.Len(t, statuses, 5)
|
|
@ -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 git
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -10,6 +10,7 @@ import (
|
|||
"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"
|
||||
"code.gitea.io/gitea/modules/lfs"
|
||||
|
@ -19,6 +20,76 @@ import (
|
|||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// ErrLFSLockNotExist represents a "LFSLockNotExist" kind of error.
|
||||
type ErrLFSLockNotExist struct {
|
||||
ID int64
|
||||
RepoID int64
|
||||
Path string
|
||||
}
|
||||
|
||||
// IsErrLFSLockNotExist checks if an error is a ErrLFSLockNotExist.
|
||||
func IsErrLFSLockNotExist(err error) bool {
|
||||
_, ok := err.(ErrLFSLockNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrLFSLockNotExist) Error() string {
|
||||
return fmt.Sprintf("lfs lock does not exist [id: %d, rid: %d, path: %s]", err.ID, err.RepoID, err.Path)
|
||||
}
|
||||
|
||||
// ErrLFSUnauthorizedAction represents a "LFSUnauthorizedAction" kind of error.
|
||||
type ErrLFSUnauthorizedAction struct {
|
||||
RepoID int64
|
||||
UserName string
|
||||
Mode perm.AccessMode
|
||||
}
|
||||
|
||||
// IsErrLFSUnauthorizedAction checks if an error is a ErrLFSUnauthorizedAction.
|
||||
func IsErrLFSUnauthorizedAction(err error) bool {
|
||||
_, ok := err.(ErrLFSUnauthorizedAction)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrLFSUnauthorizedAction) Error() string {
|
||||
if err.Mode == perm.AccessModeWrite {
|
||||
return fmt.Sprintf("User %s doesn't have write access for lfs lock [rid: %d]", err.UserName, err.RepoID)
|
||||
}
|
||||
return fmt.Sprintf("User %s doesn't have read access for lfs lock [rid: %d]", err.UserName, err.RepoID)
|
||||
}
|
||||
|
||||
// ErrLFSLockAlreadyExist represents a "LFSLockAlreadyExist" kind of error.
|
||||
type ErrLFSLockAlreadyExist struct {
|
||||
RepoID int64
|
||||
Path string
|
||||
}
|
||||
|
||||
// IsErrLFSLockAlreadyExist checks if an error is a ErrLFSLockAlreadyExist.
|
||||
func IsErrLFSLockAlreadyExist(err error) bool {
|
||||
_, ok := err.(ErrLFSLockAlreadyExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrLFSLockAlreadyExist) Error() string {
|
||||
return fmt.Sprintf("lfs lock already exists [rid: %d, path: %s]", err.RepoID, err.Path)
|
||||
}
|
||||
|
||||
// ErrLFSFileLocked represents a "LFSFileLocked" kind of error.
|
||||
type ErrLFSFileLocked struct {
|
||||
RepoID int64
|
||||
Path string
|
||||
UserName string
|
||||
}
|
||||
|
||||
// IsErrLFSFileLocked checks if an error is a ErrLFSFileLocked.
|
||||
func IsErrLFSFileLocked(err error) bool {
|
||||
_, ok := err.(ErrLFSFileLocked)
|
||||
return ok
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
// LFSMetaObject stores metadata for LFS tracked files.
|
||||
type LFSMetaObject struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
|
@ -239,7 +310,7 @@ func CopyLFS(ctx context.Context, newRepo, oldRepo *repo_model.Repository) error
|
|||
for _, v := range lfsObjects {
|
||||
v.ID = 0
|
||||
v.RepositoryID = newRepo.ID
|
||||
if _, err := db.GetEngine(ctx).Insert(v); err != nil {
|
||||
if err := db.Insert(ctx, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
|
@ -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 git
|
||||
|
||||
import (
|
||||
"context"
|
18
models/git/main_test.go
Normal file
18
models/git/main_test.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2020 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 git_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m, &unittest.TestOptions{
|
||||
GiteaRootPath: filepath.Join("..", ".."),
|
||||
})
|
||||
}
|
|
@ -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 git
|
||||
|
||||
import (
|
||||
"regexp"
|
|
@ -2,11 +2,12 @@
|
|||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package models
|
||||
package git_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -15,42 +16,42 @@ import (
|
|||
func TestIsUserAllowed(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
pt := &ProtectedTag{}
|
||||
allowed, err := IsUserAllowedModifyTag(pt, 1)
|
||||
pt := &git_model.ProtectedTag{}
|
||||
allowed, err := git_model.IsUserAllowedModifyTag(pt, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, allowed)
|
||||
|
||||
pt = &ProtectedTag{
|
||||
pt = &git_model.ProtectedTag{
|
||||
AllowlistUserIDs: []int64{1},
|
||||
}
|
||||
allowed, err = IsUserAllowedModifyTag(pt, 1)
|
||||
allowed, err = git_model.IsUserAllowedModifyTag(pt, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, allowed)
|
||||
|
||||
allowed, err = IsUserAllowedModifyTag(pt, 2)
|
||||
allowed, err = git_model.IsUserAllowedModifyTag(pt, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, allowed)
|
||||
|
||||
pt = &ProtectedTag{
|
||||
pt = &git_model.ProtectedTag{
|
||||
AllowlistTeamIDs: []int64{1},
|
||||
}
|
||||
allowed, err = IsUserAllowedModifyTag(pt, 1)
|
||||
allowed, err = git_model.IsUserAllowedModifyTag(pt, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, allowed)
|
||||
|
||||
allowed, err = IsUserAllowedModifyTag(pt, 2)
|
||||
allowed, err = git_model.IsUserAllowedModifyTag(pt, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, allowed)
|
||||
|
||||
pt = &ProtectedTag{
|
||||
pt = &git_model.ProtectedTag{
|
||||
AllowlistUserIDs: []int64{1},
|
||||
AllowlistTeamIDs: []int64{1},
|
||||
}
|
||||
allowed, err = IsUserAllowedModifyTag(pt, 1)
|
||||
allowed, err = git_model.IsUserAllowedModifyTag(pt, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, allowed)
|
||||
|
||||
allowed, err = IsUserAllowedModifyTag(pt, 2)
|
||||
allowed, err = git_model.IsUserAllowedModifyTag(pt, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, allowed)
|
||||
}
|
||||
|
@ -119,7 +120,7 @@ func TestIsUserAllowedToControlTag(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("Glob", func(t *testing.T) {
|
||||
protectedTags := []*ProtectedTag{
|
||||
protectedTags := []*git_model.ProtectedTag{
|
||||
{
|
||||
NamePattern: `*gitea`,
|
||||
AllowlistUserIDs: []int64{1},
|
||||
|
@ -134,14 +135,14 @@ func TestIsUserAllowedToControlTag(t *testing.T) {
|
|||
}
|
||||
|
||||
for n, c := range cases {
|
||||
isAllowed, err := IsUserAllowedToControlTag(protectedTags, c.name, c.userid)
|
||||
isAllowed, err := git_model.IsUserAllowedToControlTag(protectedTags, c.name, c.userid)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, c.allowed, isAllowed, "case %d: error should match", n)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Regex", func(t *testing.T) {
|
||||
protectedTags := []*ProtectedTag{
|
||||
protectedTags := []*git_model.ProtectedTag{
|
||||
{
|
||||
NamePattern: `/gitea\z/`,
|
||||
AllowlistUserIDs: []int64{1},
|
||||
|
@ -156,7 +157,7 @@ func TestIsUserAllowedToControlTag(t *testing.T) {
|
|||
}
|
||||
|
||||
for n, c := range cases {
|
||||
isAllowed, err := IsUserAllowedToControlTag(protectedTags, c.name, c.userid)
|
||||
isAllowed, err := git_model.IsUserAllowedToControlTag(protectedTags, c.name, c.userid)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, c.allowed, isAllowed, "case %d: error should match", n)
|
||||
}
|
|
@ -15,6 +15,7 @@ import (
|
|||
"unicode/utf8"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
project_model "code.gitea.io/gitea/models/project"
|
||||
|
@ -271,11 +272,11 @@ type Comment struct {
|
|||
RefIssue *Issue `xorm:"-"`
|
||||
RefComment *Comment `xorm:"-"`
|
||||
|
||||
Commits []*SignCommitWithStatuses `xorm:"-"`
|
||||
OldCommit string `xorm:"-"`
|
||||
NewCommit string `xorm:"-"`
|
||||
CommitsNum int64 `xorm:"-"`
|
||||
IsForcePush bool `xorm:"-"`
|
||||
Commits []*git_model.SignCommitWithStatuses `xorm:"-"`
|
||||
OldCommit string `xorm:"-"`
|
||||
NewCommit string `xorm:"-"`
|
||||
CommitsNum int64 `xorm:"-"`
|
||||
IsForcePush bool `xorm:"-"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -761,7 +762,7 @@ func (c *Comment) LoadPushCommits(ctx context.Context) (err error) {
|
|||
}
|
||||
defer closer.Close()
|
||||
|
||||
c.Commits = ConvertFromGitCommit(gitRepo.GetCommitsFromIDs(data.CommitIDs), c.Issue.Repo)
|
||||
c.Commits = git_model.ConvertFromGitCommit(gitRepo.GetCommitsFromIDs(data.CommitIDs), c.Issue.Repo)
|
||||
c.CommitsNum = int64(len(c.Commits))
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
|
@ -412,7 +413,7 @@ func DeleteTeam(t *organization.Team) error {
|
|||
|
||||
// update branch protections
|
||||
{
|
||||
protections := make([]*ProtectedBranch, 0, 10)
|
||||
protections := make([]*git_model.ProtectedBranch, 0, 10)
|
||||
err := sess.In("repo_id",
|
||||
builder.Select("id").From("repository").Where(builder.Eq{"owner_id": t.OrgID})).
|
||||
Find(&protections)
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
pull_model "code.gitea.io/gitea/models/pull"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
@ -78,9 +79,9 @@ type PullRequest struct {
|
|||
HeadBranch string
|
||||
HeadCommitID string `xorm:"-"`
|
||||
BaseBranch string
|
||||
ProtectedBranch *ProtectedBranch `xorm:"-"`
|
||||
MergeBase string `xorm:"VARCHAR(40)"`
|
||||
AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"`
|
||||
ProtectedBranch *git_model.ProtectedBranch `xorm:"-"`
|
||||
MergeBase string `xorm:"VARCHAR(40)"`
|
||||
AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"`
|
||||
|
||||
HasMerged bool `xorm:"INDEX"`
|
||||
MergedCommitID string `xorm:"VARCHAR(40)"`
|
||||
|
@ -242,7 +243,7 @@ func (pr *PullRequest) LoadProtectedBranchCtx(ctx context.Context) (err error) {
|
|||
return
|
||||
}
|
||||
}
|
||||
pr.ProtectedBranch, err = GetProtectedBranchBy(ctx, pr.BaseRepo.ID, pr.BaseBranch)
|
||||
pr.ProtectedBranch, err = git_model.GetProtectedBranchBy(ctx, pr.BaseRepo.ID, pr.BaseBranch)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
admin_model "code.gitea.io/gitea/models/admin"
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
|
@ -34,9 +35,6 @@ import (
|
|||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// ItemsPerPage maximum items per page in forks, watchers and stars of a repo
|
||||
var ItemsPerPage = 40
|
||||
|
||||
// NewRepoContext creates a new repository context
|
||||
func NewRepoContext() {
|
||||
unit.LoadUnitConfig()
|
||||
|
@ -284,16 +282,16 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
|
|||
&Action{RepoID: repo.ID},
|
||||
&repo_model.Collaboration{RepoID: repoID},
|
||||
&Comment{RefRepoID: repoID},
|
||||
&CommitStatus{RepoID: repoID},
|
||||
&DeletedBranch{RepoID: repoID},
|
||||
&git_model.CommitStatus{RepoID: repoID},
|
||||
&git_model.DeletedBranch{RepoID: repoID},
|
||||
&webhook.HookTask{RepoID: repoID},
|
||||
&LFSLock{RepoID: repoID},
|
||||
&git_model.LFSLock{RepoID: repoID},
|
||||
&repo_model.LanguageStat{RepoID: repoID},
|
||||
&issues_model.Milestone{RepoID: repoID},
|
||||
&repo_model.Mirror{RepoID: repoID},
|
||||
&Notification{RepoID: repoID},
|
||||
&ProtectedBranch{RepoID: repoID},
|
||||
&ProtectedTag{RepoID: repoID},
|
||||
&git_model.ProtectedBranch{RepoID: repoID},
|
||||
&git_model.ProtectedTag{RepoID: repoID},
|
||||
&repo_model.PushMirror{RepoID: repoID},
|
||||
&Release{RepoID: repoID},
|
||||
&repo_model.RepoIndexerStatus{RepoID: repoID},
|
||||
|
@ -357,14 +355,14 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
|
|||
}
|
||||
|
||||
// Remove LFS objects
|
||||
var lfsObjects []*LFSMetaObject
|
||||
var lfsObjects []*git_model.LFSMetaObject
|
||||
if err = sess.Where("repository_id=?", repoID).Find(&lfsObjects); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lfsPaths := make([]string, 0, len(lfsObjects))
|
||||
for _, v := range lfsObjects {
|
||||
count, err := db.CountByBean(ctx, &LFSMetaObject{Pointer: lfs.Pointer{Oid: v.Oid}})
|
||||
count, err := db.CountByBean(ctx, &git_model.LFSMetaObject{Pointer: lfs.Pointer{Oid: v.Oid}})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -375,7 +373,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
|
|||
lfsPaths = append(lfsPaths, v.RelativePath())
|
||||
}
|
||||
|
||||
if _, err := db.DeleteByBean(ctx, &LFSMetaObject{RepositoryID: repoID}); err != nil {
|
||||
if _, err := db.DeleteByBean(ctx, &git_model.LFSMetaObject{RepositoryID: repoID}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
"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/timeutil"
|
||||
|
@ -149,3 +150,23 @@ func ChangeCollaborationAccessMode(repo *Repository, uid int64, mode perm.Access
|
|||
|
||||
return committer.Commit()
|
||||
}
|
||||
|
||||
// IsOwnerMemberCollaborator checks if a provided user is the owner, a collaborator or a member of a team in a repository
|
||||
func IsOwnerMemberCollaborator(repo *Repository, userID int64) (bool, error) {
|
||||
if repo.OwnerID == userID {
|
||||
return true, nil
|
||||
}
|
||||
teamMember, err := db.GetEngine(db.DefaultContext).Join("INNER", "team_repo", "team_repo.team_id = team_user.team_id").
|
||||
Join("INNER", "team_unit", "team_unit.team_id = team_user.team_id").
|
||||
Where("team_repo.repo_id = ?", repo.ID).
|
||||
And("team_unit.`type` = ?", unit.TypeCode).
|
||||
And("team_user.uid = ?", userID).Table("team_user").Exist()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if teamMember {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return db.GetEngine(db.DefaultContext).Get(&Collaboration{RepoID: repo.ID, UserID: userID})
|
||||
}
|
||||
|
|
|
@ -10,11 +10,9 @@ import (
|
|||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
||||
"xorm.io/builder"
|
||||
|
@ -120,23 +118,3 @@ func reconsiderWatches(ctx context.Context, repo *repo_model.Repository, uid int
|
|||
// Remove all IssueWatches a user has subscribed to in the repository
|
||||
return removeIssueWatchersByRepoID(ctx, uid, repo.ID)
|
||||
}
|
||||
|
||||
// IsOwnerMemberCollaborator checks if a provided user is the owner, a collaborator or a member of a team in a repository
|
||||
func IsOwnerMemberCollaborator(repo *repo_model.Repository, userID int64) (bool, error) {
|
||||
if repo.OwnerID == userID {
|
||||
return true, nil
|
||||
}
|
||||
teamMember, err := db.GetEngine(db.DefaultContext).Join("INNER", "team_repo", "team_repo.team_id = team_user.team_id").
|
||||
Join("INNER", "team_unit", "team_unit.team_id = team_user.team_id").
|
||||
Where("team_repo.repo_id = ?", repo.ID).
|
||||
And("team_unit.`type` = ?", unit.TypeCode).
|
||||
And("team_user.uid = ?", userID).Table("team_user").Exist(&organization.TeamUser{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if teamMember {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return db.GetEngine(db.DefaultContext).Get(&repo_model.Collaboration{RepoID: repo.ID, UserID: userID})
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
|
@ -234,7 +235,7 @@ func IsOfficialReviewer(ctx context.Context, issue *Issue, reviewers ...*user_mo
|
|||
}
|
||||
|
||||
for _, reviewer := range reviewers {
|
||||
official, err := isUserOfficialReviewer(ctx, pr.ProtectedBranch, reviewer)
|
||||
official, err := git_model.IsUserOfficialReviewerCtx(ctx, pr.ProtectedBranch, reviewer)
|
||||
if official || err != nil {
|
||||
return official, err
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
"code.gitea.io/gitea/models/issues"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
|
@ -125,7 +126,7 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) {
|
|||
{
|
||||
const batchSize = 50
|
||||
for start := 0; ; start += batchSize {
|
||||
protections := make([]*ProtectedBranch, 0, batchSize)
|
||||
protections := make([]*git_model.ProtectedBranch, 0, batchSize)
|
||||
// @perf: We can't filter on DB side by u.ID, as those IDs are serialized as JSON strings.
|
||||
// We could filter down with `WHERE repo_id IN (reposWithPushPermission(u))`,
|
||||
// though that query will be quite complex and tricky to maintain (compare `getRepoAssignees()`).
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue