Skip to content

Commit 45d7872

Browse files
committed
Merge branch 'main' into fork-dialog
2 parents bbb458f + 5723240 commit 45d7872

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+1593
-1436
lines changed

cmd/migrate_storage.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func migrateAvatars(dstStorage storage.ObjectStorage) error {
102102
}
103103

104104
func migrateRepoAvatars(dstStorage storage.ObjectStorage) error {
105-
return models.IterateRepository(func(repo *repo_model.Repository) error {
105+
return repo_model.IterateRepository(func(repo *repo_model.Repository) error {
106106
_, err := storage.Copy(dstStorage, repo.CustomAvatarRelativePath(), storage.RepoAvatars, repo.CustomAvatarRelativePath())
107107
return err
108108
})

integrations/delete_user_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func assertUserDeleted(t *testing.T, userID int64) {
2424
unittest.AssertNotExistsBean(t, &models.OrgUser{UID: userID})
2525
unittest.AssertNotExistsBean(t, &models.IssueUser{UID: userID})
2626
unittest.AssertNotExistsBean(t, &models.TeamUser{UID: userID})
27-
unittest.AssertNotExistsBean(t, &models.Star{UID: userID})
27+
unittest.AssertNotExistsBean(t, &repo_model.Star{UID: userID})
2828
}
2929

3030
func TestUserDeleteAccount(t *testing.T) {

integrations/pull_update_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *models.Pul
8989
assert.NoError(t, err)
9090
assert.NotEmpty(t, baseRepo)
9191

92-
headRepo, err := repo_service.ForkRepository(actor, forkOrg, models.ForkRepoOptions{
92+
headRepo, err := repo_service.ForkRepository(actor, forkOrg, repo_service.ForkRepoOptions{
9393
BaseRepo: baseRepo,
9494
Name: "repo-pr-update",
9595
Description: "desc",

integrations/repo_watch_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"net/url"
99
"testing"
1010

11-
"code.gitea.io/gitea/models"
11+
repo_model "code.gitea.io/gitea/models/repo"
1212
"code.gitea.io/gitea/models/unittest"
1313
"code.gitea.io/gitea/modules/setting"
1414
)
@@ -18,8 +18,8 @@ func TestRepoWatch(t *testing.T) {
1818
// Test round-trip auto-watch
1919
setting.Service.AutoWatchOnChanges = true
2020
session := loginUser(t, "user2")
21-
unittest.AssertNotExistsBean(t, &models.Watch{UserID: 2, RepoID: 3})
21+
unittest.AssertNotExistsBean(t, &repo_model.Watch{UserID: 2, RepoID: 3})
2222
testEditFile(t, session, "user3", "repo3", "master", "README.md", "Hello, World (Edited for watch)\n")
23-
unittest.AssertExistsAndLoadBean(t, &models.Watch{UserID: 2, RepoID: 3, Mode: models.RepoWatchModeAuto})
23+
unittest.AssertExistsAndLoadBean(t, &repo_model.Watch{UserID: 2, RepoID: 3, Mode: repo_model.WatchModeAuto})
2424
})
2525
}

models/action.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
"code.gitea.io/gitea/models/db"
1818
repo_model "code.gitea.io/gitea/models/repo"
19+
"code.gitea.io/gitea/models/unit"
1920
user_model "code.gitea.io/gitea/models/user"
2021
"code.gitea.io/gitea/modules/base"
2122
"code.gitea.io/gitea/modules/git"
@@ -414,3 +415,127 @@ func DeleteOldActions(olderThan time.Duration) (err error) {
414415
_, err = db.GetEngine(db.DefaultContext).Where("created_unix < ?", time.Now().Add(-olderThan).Unix()).Delete(&Action{})
415416
return
416417
}
418+
419+
func notifyWatchers(ctx context.Context, actions ...*Action) error {
420+
var watchers []*repo_model.Watch
421+
var repo *repo_model.Repository
422+
var err error
423+
var permCode []bool
424+
var permIssue []bool
425+
var permPR []bool
426+
427+
e := db.GetEngine(ctx)
428+
429+
for _, act := range actions {
430+
repoChanged := repo == nil || repo.ID != act.RepoID
431+
432+
if repoChanged {
433+
// Add feeds for user self and all watchers.
434+
watchers, err = repo_model.GetWatchers(ctx, act.RepoID)
435+
if err != nil {
436+
return fmt.Errorf("get watchers: %v", err)
437+
}
438+
}
439+
440+
// Add feed for actioner.
441+
act.UserID = act.ActUserID
442+
if _, err = e.Insert(act); err != nil {
443+
return fmt.Errorf("insert new actioner: %v", err)
444+
}
445+
446+
if repoChanged {
447+
act.loadRepo()
448+
repo = act.Repo
449+
450+
// check repo owner exist.
451+
if err := act.Repo.GetOwner(ctx); err != nil {
452+
return fmt.Errorf("can't get repo owner: %v", err)
453+
}
454+
} else if act.Repo == nil {
455+
act.Repo = repo
456+
}
457+
458+
// Add feed for organization
459+
if act.Repo.Owner.IsOrganization() && act.ActUserID != act.Repo.Owner.ID {
460+
act.ID = 0
461+
act.UserID = act.Repo.Owner.ID
462+
if _, err = e.InsertOne(act); err != nil {
463+
return fmt.Errorf("insert new actioner: %v", err)
464+
}
465+
}
466+
467+
if repoChanged {
468+
permCode = make([]bool, len(watchers))
469+
permIssue = make([]bool, len(watchers))
470+
permPR = make([]bool, len(watchers))
471+
for i, watcher := range watchers {
472+
user, err := user_model.GetUserByIDEngine(e, watcher.UserID)
473+
if err != nil {
474+
permCode[i] = false
475+
permIssue[i] = false
476+
permPR[i] = false
477+
continue
478+
}
479+
perm, err := getUserRepoPermission(ctx, repo, user)
480+
if err != nil {
481+
permCode[i] = false
482+
permIssue[i] = false
483+
permPR[i] = false
484+
continue
485+
}
486+
permCode[i] = perm.CanRead(unit.TypeCode)
487+
permIssue[i] = perm.CanRead(unit.TypeIssues)
488+
permPR[i] = perm.CanRead(unit.TypePullRequests)
489+
}
490+
}
491+
492+
for i, watcher := range watchers {
493+
if act.ActUserID == watcher.UserID {
494+
continue
495+
}
496+
act.ID = 0
497+
act.UserID = watcher.UserID
498+
act.Repo.Units = nil
499+
500+
switch act.OpType {
501+
case ActionCommitRepo, ActionPushTag, ActionDeleteTag, ActionPublishRelease, ActionDeleteBranch:
502+
if !permCode[i] {
503+
continue
504+
}
505+
case ActionCreateIssue, ActionCommentIssue, ActionCloseIssue, ActionReopenIssue:
506+
if !permIssue[i] {
507+
continue
508+
}
509+
case ActionCreatePullRequest, ActionCommentPull, ActionMergePullRequest, ActionClosePullRequest, ActionReopenPullRequest:
510+
if !permPR[i] {
511+
continue
512+
}
513+
}
514+
515+
if _, err = e.InsertOne(act); err != nil {
516+
return fmt.Errorf("insert new action: %v", err)
517+
}
518+
}
519+
}
520+
return nil
521+
}
522+
523+
// NotifyWatchers creates batch of actions for every watcher.
524+
func NotifyWatchers(actions ...*Action) error {
525+
return notifyWatchers(db.DefaultContext, actions...)
526+
}
527+
528+
// NotifyWatchersActions creates batch of actions for every watcher.
529+
func NotifyWatchersActions(acts []*Action) error {
530+
ctx, committer, err := db.TxContext()
531+
if err != nil {
532+
return err
533+
}
534+
defer committer.Close()
535+
for _, act := range acts {
536+
if err := notifyWatchers(ctx, act); err != nil {
537+
return err
538+
}
539+
}
540+
return committer.Commit()
541+
}

models/action_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,40 @@ func TestGetFeeds2(t *testing.T) {
9292
assert.NoError(t, err)
9393
assert.Len(t, actions, 0)
9494
}
95+
96+
func TestNotifyWatchers(t *testing.T) {
97+
assert.NoError(t, unittest.PrepareTestDatabase())
98+
99+
action := &Action{
100+
ActUserID: 8,
101+
RepoID: 1,
102+
OpType: ActionStarRepo,
103+
}
104+
assert.NoError(t, NotifyWatchers(action))
105+
106+
// One watchers are inactive, thus action is only created for user 8, 1, 4, 11
107+
unittest.AssertExistsAndLoadBean(t, &Action{
108+
ActUserID: action.ActUserID,
109+
UserID: 8,
110+
RepoID: action.RepoID,
111+
OpType: action.OpType,
112+
})
113+
unittest.AssertExistsAndLoadBean(t, &Action{
114+
ActUserID: action.ActUserID,
115+
UserID: 1,
116+
RepoID: action.RepoID,
117+
OpType: action.OpType,
118+
})
119+
unittest.AssertExistsAndLoadBean(t, &Action{
120+
ActUserID: action.ActUserID,
121+
UserID: 4,
122+
RepoID: action.RepoID,
123+
OpType: action.OpType,
124+
})
125+
unittest.AssertExistsAndLoadBean(t, &Action{
126+
ActUserID: action.ActUserID,
127+
UserID: 11,
128+
RepoID: action.RepoID,
129+
OpType: action.OpType,
130+
})
131+
}

models/error.go

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,6 @@ func (err ErrUserNotAllowedCreateOrg) Error() string {
7171
return "user is not allowed to create organizations"
7272
}
7373

74-
// ErrReachLimitOfRepo represents a "ReachLimitOfRepo" kind of error.
75-
type ErrReachLimitOfRepo struct {
76-
Limit int
77-
}
78-
79-
// IsErrReachLimitOfRepo checks if an error is a ErrReachLimitOfRepo.
80-
func IsErrReachLimitOfRepo(err error) bool {
81-
_, ok := err.(ErrReachLimitOfRepo)
82-
return ok
83-
}
84-
85-
func (err ErrReachLimitOfRepo) Error() string {
86-
return fmt.Sprintf("user has reached maximum limit of repositories [limit: %d]", err.Limit)
87-
}
88-
8974
// __ __.__ __ .__
9075
// / \ / \__| | _|__|
9176
// \ \/\/ / | |/ / |
@@ -322,38 +307,6 @@ func (err ErrRepoTransferInProgress) Error() string {
322307
return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name)
323308
}
324309

325-
// ErrRepoAlreadyExist represents a "RepoAlreadyExist" kind of error.
326-
type ErrRepoAlreadyExist struct {
327-
Uname string
328-
Name string
329-
}
330-
331-
// IsErrRepoAlreadyExist checks if an error is a ErrRepoAlreadyExist.
332-
func IsErrRepoAlreadyExist(err error) bool {
333-
_, ok := err.(ErrRepoAlreadyExist)
334-
return ok
335-
}
336-
337-
func (err ErrRepoAlreadyExist) Error() string {
338-
return fmt.Sprintf("repository already exists [uname: %s, name: %s]", err.Uname, err.Name)
339-
}
340-
341-
// ErrRepoFilesAlreadyExist represents a "RepoFilesAlreadyExist" kind of error.
342-
type ErrRepoFilesAlreadyExist struct {
343-
Uname string
344-
Name string
345-
}
346-
347-
// IsErrRepoFilesAlreadyExist checks if an error is a ErrRepoAlreadyExist.
348-
func IsErrRepoFilesAlreadyExist(err error) bool {
349-
_, ok := err.(ErrRepoFilesAlreadyExist)
350-
return ok
351-
}
352-
353-
func (err ErrRepoFilesAlreadyExist) Error() string {
354-
return fmt.Sprintf("repository files already exist [uname: %s, name: %s]", err.Uname, err.Name)
355-
}
356-
357310
// ErrForkAlreadyExist represents a "ForkAlreadyExist" kind of error.
358311
type ErrForkAlreadyExist struct {
359312
Uname string
@@ -371,22 +324,6 @@ func (err ErrForkAlreadyExist) Error() string {
371324
return fmt.Sprintf("repository is already forked by user [uname: %s, repo path: %s, fork path: %s]", err.Uname, err.RepoName, err.ForkName)
372325
}
373326

374-
// ErrRepoRedirectNotExist represents a "RepoRedirectNotExist" kind of error.
375-
type ErrRepoRedirectNotExist struct {
376-
OwnerID int64
377-
RepoName string
378-
}
379-
380-
// IsErrRepoRedirectNotExist check if an error is an ErrRepoRedirectNotExist.
381-
func IsErrRepoRedirectNotExist(err error) bool {
382-
_, ok := err.(ErrRepoRedirectNotExist)
383-
return ok
384-
}
385-
386-
func (err ErrRepoRedirectNotExist) Error() string {
387-
return fmt.Sprintf("repository redirect does not exist [uid: %d, name: %s]", err.OwnerID, err.RepoName)
388-
}
389-
390327
// ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error.
391328
type ErrInvalidCloneAddr struct {
392329
Host string

models/issue_watch.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package models
66

77
import (
88
"code.gitea.io/gitea/models/db"
9+
repo_model "code.gitea.io/gitea/models/repo"
910
user_model "code.gitea.io/gitea/models/user"
1011
"code.gitea.io/gitea/modules/timeutil"
1112
)
@@ -80,11 +81,11 @@ func CheckIssueWatch(user *user_model.User, issue *Issue) (bool, error) {
8081
if exist {
8182
return iw.IsWatching, nil
8283
}
83-
w, err := getWatch(db.GetEngine(db.DefaultContext), user.ID, issue.RepoID)
84+
w, err := repo_model.GetWatch(db.DefaultContext, user.ID, issue.RepoID)
8485
if err != nil {
8586
return false, err
8687
}
87-
return isWatchMode(w.Mode) || IsUserParticipantsOfIssue(user, issue), nil
88+
return repo_model.IsWatchMode(w.Mode) || IsUserParticipantsOfIssue(user, issue), nil
8889
}
8990

9091
// GetIssueWatchersIDs returns IDs of subscribers or explicit unsubscribers to a given issue id

models/notification.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
225225
toNotify[id] = struct{}{}
226226
}
227227
if !(issue.IsPull && HasWorkInProgressPrefix(issue.Title)) {
228-
repoWatches, err := getRepoWatchersIDs(e, issue.RepoID)
228+
repoWatches, err := repo_model.GetRepoWatchersIDs(ctx, issue.RepoID)
229229
if err != nil {
230230
return err
231231
}

models/org.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ func removeOrgUser(ctx context.Context, orgID, userID int64) error {
794794
return fmt.Errorf("GetUserRepositories [%d]: %v", userID, err)
795795
}
796796
for _, repoID := range repoIDs {
797-
if err = watchRepo(sess, userID, repoID, false); err != nil {
797+
if err = repo_model.WatchRepoCtx(ctx, userID, repoID, false); err != nil {
798798
return err
799799
}
800800
}

models/org_team.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ func (t *Team) addRepository(ctx context.Context, repo *repo_model.Repository) (
238238
return fmt.Errorf("getMembers: %v", err)
239239
}
240240
for _, u := range t.Members {
241-
if err = watchRepo(e, u.ID, repo.ID, true); err != nil {
241+
if err = repo_model.WatchRepoCtx(ctx, u.ID, repo.ID, true); err != nil {
242242
return fmt.Errorf("watchRepo: %v", err)
243243
}
244244
}
@@ -341,7 +341,7 @@ func (t *Team) removeAllRepositories(ctx context.Context) (err error) {
341341
continue
342342
}
343343

344-
if err = watchRepo(e, user.ID, repo.ID, false); err != nil {
344+
if err = repo_model.WatchRepoCtx(ctx, user.ID, repo.ID, false); err != nil {
345345
return err
346346
}
347347

@@ -399,7 +399,7 @@ func (t *Team) removeRepository(ctx context.Context, repo *repo_model.Repository
399399
continue
400400
}
401401

402-
if err = watchRepo(e, teamUser.UID, repo.ID, false); err != nil {
402+
if err = repo_model.WatchRepoCtx(ctx, teamUser.UID, repo.ID, false); err != nil {
403403
return err
404404
}
405405

@@ -857,7 +857,7 @@ func AddTeamMember(team *Team, userID int64) error {
857857
return err
858858
}
859859
if setting.Service.AutoWatchNewRepos {
860-
if err = watchRepo(sess, userID, repo.ID, true); err != nil {
860+
if err = repo_model.WatchRepoCtx(ctx, userID, repo.ID, true); err != nil {
861861
return err
862862
}
863863
}

0 commit comments

Comments
 (0)