Skip to content

Commit

Permalink
Some repository refactors (go-gitea#17950)
Browse files Browse the repository at this point in the history
* some repository refactors

* remove unnecessary code

* Fix test

* Remove unnecessary banner
  • Loading branch information
lunny authored Dec 12, 2021
1 parent 0a7e832 commit 5723240
Show file tree
Hide file tree
Showing 88 changed files with 1,363 additions and 1,388 deletions.
2 changes: 1 addition & 1 deletion cmd/migrate_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func migrateAvatars(dstStorage storage.ObjectStorage) error {
}

func migrateRepoAvatars(dstStorage storage.ObjectStorage) error {
return models.IterateRepository(func(repo *repo_model.Repository) error {
return repo_model.IterateRepository(func(repo *repo_model.Repository) error {
_, err := storage.Copy(dstStorage, repo.CustomAvatarRelativePath(), storage.RepoAvatars, repo.CustomAvatarRelativePath())
return err
})
Expand Down
2 changes: 1 addition & 1 deletion integrations/delete_user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func assertUserDeleted(t *testing.T, userID int64) {
unittest.AssertNotExistsBean(t, &models.OrgUser{UID: userID})
unittest.AssertNotExistsBean(t, &models.IssueUser{UID: userID})
unittest.AssertNotExistsBean(t, &models.TeamUser{UID: userID})
unittest.AssertNotExistsBean(t, &models.Star{UID: userID})
unittest.AssertNotExistsBean(t, &repo_model.Star{UID: userID})
}

func TestUserDeleteAccount(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion integrations/pull_update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *models.Pul
assert.NoError(t, err)
assert.NotEmpty(t, baseRepo)

headRepo, err := repo_service.ForkRepository(actor, forkOrg, models.ForkRepoOptions{
headRepo, err := repo_service.ForkRepository(actor, forkOrg, repo_service.ForkRepoOptions{
BaseRepo: baseRepo,
Name: "repo-pr-update",
Description: "desc",
Expand Down
6 changes: 3 additions & 3 deletions integrations/repo_watch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"net/url"
"testing"

"code.gitea.io/gitea/models"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/setting"
)
Expand All @@ -18,8 +18,8 @@ func TestRepoWatch(t *testing.T) {
// Test round-trip auto-watch
setting.Service.AutoWatchOnChanges = true
session := loginUser(t, "user2")
unittest.AssertNotExistsBean(t, &models.Watch{UserID: 2, RepoID: 3})
unittest.AssertNotExistsBean(t, &repo_model.Watch{UserID: 2, RepoID: 3})
testEditFile(t, session, "user3", "repo3", "master", "README.md", "Hello, World (Edited for watch)\n")
unittest.AssertExistsAndLoadBean(t, &models.Watch{UserID: 2, RepoID: 3, Mode: models.RepoWatchModeAuto})
unittest.AssertExistsAndLoadBean(t, &repo_model.Watch{UserID: 2, RepoID: 3, Mode: repo_model.WatchModeAuto})
})
}
125 changes: 125 additions & 0 deletions models/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

"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/base"
"code.gitea.io/gitea/modules/git"
Expand Down Expand Up @@ -414,3 +415,127 @@ func DeleteOldActions(olderThan time.Duration) (err error) {
_, err = db.GetEngine(db.DefaultContext).Where("created_unix < ?", time.Now().Add(-olderThan).Unix()).Delete(&Action{})
return
}

func notifyWatchers(ctx context.Context, actions ...*Action) error {
var watchers []*repo_model.Watch
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

if repoChanged {
// Add feeds for user self and all watchers.
watchers, err = repo_model.GetWatchers(ctx, act.RepoID)
if err != nil {
return fmt.Errorf("get watchers: %v", err)
}
}

// Add feed for actioner.
act.UserID = act.ActUserID
if _, err = e.Insert(act); err != nil {
return fmt.Errorf("insert new actioner: %v", err)
}

if repoChanged {
act.loadRepo()
repo = act.Repo

// check repo owner exist.
if err := act.Repo.GetOwner(ctx); err != nil {
return fmt.Errorf("can't get repo owner: %v", err)
}
} else if act.Repo == nil {
act.Repo = repo
}

// Add feed for organization
if act.Repo.Owner.IsOrganization() && act.ActUserID != act.Repo.Owner.ID {
act.ID = 0
act.UserID = act.Repo.Owner.ID
if _, err = e.InsertOne(act); err != nil {
return fmt.Errorf("insert new actioner: %v", err)
}
}

if repoChanged {
permCode = make([]bool, len(watchers))
permIssue = make([]bool, len(watchers))
permPR = make([]bool, len(watchers))
for i, watcher := range watchers {
user, err := user_model.GetUserByIDEngine(e, watcher.UserID)
if err != nil {
permCode[i] = false
permIssue[i] = false
permPR[i] = false
continue
}
perm, err := getUserRepoPermission(ctx, repo, user)
if err != nil {
permCode[i] = false
permIssue[i] = false
permPR[i] = false
continue
}
permCode[i] = perm.CanRead(unit.TypeCode)
permIssue[i] = perm.CanRead(unit.TypeIssues)
permPR[i] = perm.CanRead(unit.TypePullRequests)
}
}

for i, watcher := range watchers {
if act.ActUserID == watcher.UserID {
continue
}
act.ID = 0
act.UserID = watcher.UserID
act.Repo.Units = nil

switch act.OpType {
case ActionCommitRepo, ActionPushTag, ActionDeleteTag, ActionPublishRelease, ActionDeleteBranch:
if !permCode[i] {
continue
}
case ActionCreateIssue, ActionCommentIssue, ActionCloseIssue, ActionReopenIssue:
if !permIssue[i] {
continue
}
case ActionCreatePullRequest, ActionCommentPull, ActionMergePullRequest, ActionClosePullRequest, ActionReopenPullRequest:
if !permPR[i] {
continue
}
}

if _, err = e.InsertOne(act); err != nil {
return fmt.Errorf("insert new action: %v", err)
}
}
}
return nil
}

// NotifyWatchers creates batch of actions for every watcher.
func NotifyWatchers(actions ...*Action) error {
return notifyWatchers(db.DefaultContext, actions...)
}

// NotifyWatchersActions creates batch of actions for every watcher.
func NotifyWatchersActions(acts []*Action) error {
ctx, committer, err := db.TxContext()
if err != nil {
return err
}
defer committer.Close()
for _, act := range acts {
if err := notifyWatchers(ctx, act); err != nil {
return err
}
}
return committer.Commit()
}
37 changes: 37 additions & 0 deletions models/action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,40 @@ func TestGetFeeds2(t *testing.T) {
assert.NoError(t, err)
assert.Len(t, actions, 0)
}

func TestNotifyWatchers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())

action := &Action{
ActUserID: 8,
RepoID: 1,
OpType: ActionStarRepo,
}
assert.NoError(t, NotifyWatchers(action))

// One watchers are inactive, thus action is only created for user 8, 1, 4, 11
unittest.AssertExistsAndLoadBean(t, &Action{
ActUserID: action.ActUserID,
UserID: 8,
RepoID: action.RepoID,
OpType: action.OpType,
})
unittest.AssertExistsAndLoadBean(t, &Action{
ActUserID: action.ActUserID,
UserID: 1,
RepoID: action.RepoID,
OpType: action.OpType,
})
unittest.AssertExistsAndLoadBean(t, &Action{
ActUserID: action.ActUserID,
UserID: 4,
RepoID: action.RepoID,
OpType: action.OpType,
})
unittest.AssertExistsAndLoadBean(t, &Action{
ActUserID: action.ActUserID,
UserID: 11,
RepoID: action.RepoID,
OpType: action.OpType,
})
}
63 changes: 0 additions & 63 deletions models/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,6 @@ func (err ErrUserNotAllowedCreateOrg) Error() string {
return "user is not allowed to create organizations"
}

// ErrReachLimitOfRepo represents a "ReachLimitOfRepo" kind of error.
type ErrReachLimitOfRepo struct {
Limit int
}

// IsErrReachLimitOfRepo checks if an error is a ErrReachLimitOfRepo.
func IsErrReachLimitOfRepo(err error) bool {
_, ok := err.(ErrReachLimitOfRepo)
return ok
}

func (err ErrReachLimitOfRepo) Error() string {
return fmt.Sprintf("user has reached maximum limit of repositories [limit: %d]", err.Limit)
}

// __ __.__ __ .__
// / \ / \__| | _|__|
// \ \/\/ / | |/ / |
Expand Down Expand Up @@ -322,38 +307,6 @@ func (err ErrRepoTransferInProgress) Error() string {
return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name)
}

// ErrRepoAlreadyExist represents a "RepoAlreadyExist" kind of error.
type ErrRepoAlreadyExist struct {
Uname string
Name string
}

// IsErrRepoAlreadyExist checks if an error is a ErrRepoAlreadyExist.
func IsErrRepoAlreadyExist(err error) bool {
_, ok := err.(ErrRepoAlreadyExist)
return ok
}

func (err ErrRepoAlreadyExist) Error() string {
return fmt.Sprintf("repository already exists [uname: %s, name: %s]", err.Uname, err.Name)
}

// ErrRepoFilesAlreadyExist represents a "RepoFilesAlreadyExist" kind of error.
type ErrRepoFilesAlreadyExist struct {
Uname string
Name string
}

// IsErrRepoFilesAlreadyExist checks if an error is a ErrRepoAlreadyExist.
func IsErrRepoFilesAlreadyExist(err error) bool {
_, ok := err.(ErrRepoFilesAlreadyExist)
return ok
}

func (err ErrRepoFilesAlreadyExist) Error() string {
return fmt.Sprintf("repository files already exist [uname: %s, name: %s]", err.Uname, err.Name)
}

// ErrForkAlreadyExist represents a "ForkAlreadyExist" kind of error.
type ErrForkAlreadyExist struct {
Uname string
Expand All @@ -371,22 +324,6 @@ func (err ErrForkAlreadyExist) Error() string {
return fmt.Sprintf("repository is already forked by user [uname: %s, repo path: %s, fork path: %s]", err.Uname, err.RepoName, err.ForkName)
}

// ErrRepoRedirectNotExist represents a "RepoRedirectNotExist" kind of error.
type ErrRepoRedirectNotExist struct {
OwnerID int64
RepoName string
}

// IsErrRepoRedirectNotExist check if an error is an ErrRepoRedirectNotExist.
func IsErrRepoRedirectNotExist(err error) bool {
_, ok := err.(ErrRepoRedirectNotExist)
return ok
}

func (err ErrRepoRedirectNotExist) Error() string {
return fmt.Sprintf("repository redirect does not exist [uid: %d, name: %s]", err.OwnerID, err.RepoName)
}

// ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error.
type ErrInvalidCloneAddr struct {
Host string
Expand Down
5 changes: 3 additions & 2 deletions models/issue_watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -80,11 +81,11 @@ func CheckIssueWatch(user *user_model.User, issue *Issue) (bool, error) {
if exist {
return iw.IsWatching, nil
}
w, err := getWatch(db.GetEngine(db.DefaultContext), user.ID, issue.RepoID)
w, err := repo_model.GetWatch(db.DefaultContext, user.ID, issue.RepoID)
if err != nil {
return false, err
}
return isWatchMode(w.Mode) || IsUserParticipantsOfIssue(user, issue), nil
return repo_model.IsWatchMode(w.Mode) || IsUserParticipantsOfIssue(user, issue), nil
}

// GetIssueWatchersIDs returns IDs of subscribers or explicit unsubscribers to a given issue id
Expand Down
2 changes: 1 addition & 1 deletion models/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
toNotify[id] = struct{}{}
}
if !(issue.IsPull && HasWorkInProgressPrefix(issue.Title)) {
repoWatches, err := getRepoWatchersIDs(e, issue.RepoID)
repoWatches, err := repo_model.GetRepoWatchersIDs(ctx, issue.RepoID)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion models/org.go
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ func removeOrgUser(ctx context.Context, orgID, userID int64) error {
return fmt.Errorf("GetUserRepositories [%d]: %v", userID, err)
}
for _, repoID := range repoIDs {
if err = watchRepo(sess, userID, repoID, false); err != nil {
if err = repo_model.WatchRepoCtx(ctx, userID, repoID, false); err != nil {
return err
}
}
Expand Down
8 changes: 4 additions & 4 deletions models/org_team.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ func (t *Team) addRepository(ctx context.Context, repo *repo_model.Repository) (
return fmt.Errorf("getMembers: %v", err)
}
for _, u := range t.Members {
if err = watchRepo(e, u.ID, repo.ID, true); err != nil {
if err = repo_model.WatchRepoCtx(ctx, u.ID, repo.ID, true); err != nil {
return fmt.Errorf("watchRepo: %v", err)
}
}
Expand Down Expand Up @@ -341,7 +341,7 @@ func (t *Team) removeAllRepositories(ctx context.Context) (err error) {
continue
}

if err = watchRepo(e, user.ID, repo.ID, false); err != nil {
if err = repo_model.WatchRepoCtx(ctx, user.ID, repo.ID, false); err != nil {
return err
}

Expand Down Expand Up @@ -399,7 +399,7 @@ func (t *Team) removeRepository(ctx context.Context, repo *repo_model.Repository
continue
}

if err = watchRepo(e, teamUser.UID, repo.ID, false); err != nil {
if err = repo_model.WatchRepoCtx(ctx, teamUser.UID, repo.ID, false); err != nil {
return err
}

Expand Down Expand Up @@ -857,7 +857,7 @@ func AddTeamMember(team *Team, userID int64) error {
return err
}
if setting.Service.AutoWatchNewRepos {
if err = watchRepo(sess, userID, repo.ID, true); err != nil {
if err = repo_model.WatchRepoCtx(ctx, userID, repo.ID, true); err != nil {
return err
}
}
Expand Down
Loading

0 comments on commit 5723240

Please sign in to comment.