aboutsummaryrefslogtreecommitdiffstats
path: root/models/repo_watch.go
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2019-12-26 11:29:45 +0000
committerLauris BH <lauris@nix.lv>2019-12-26 13:29:45 +0200
commit7bfb83e0642530183cc15f3c9208d95f88fdc79a (patch)
tree7e3670ea97ac6e9304a8df5488fed6839d1f3dc4 /models/repo_watch.go
parent114d474f02f8e4148b9fd65c8f2bc7b47f924c17 (diff)
downloadgitea-7bfb83e0642530183cc15f3c9208d95f88fdc79a.tar.gz
gitea-7bfb83e0642530183cc15f3c9208d95f88fdc79a.zip
Batch hook pre- and post-receive calls (#8602)
* make notifyWatchers work on multiple actions * more efficient multiple notifyWatchers * Make CommitRepoAction take advantage of multiple actions * Batch post and pre-receive results * Set batch to 30 * Auto adjust timeout & add logging * adjust processing message * Add some messages to pre-receive * Make any non-200 status code from pre-receive an error * Add missing hookPrintResults * Remove shortcut for single action * mistaken merge fix * oops * Move master branch to the front * If repo was empty and the master branch is pushed ensure that that is set as the default branch * fixup * fixup * Missed HookOptions in setdefaultbranch * Batch PushUpdateAddTag and PushUpdateDelTag Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Diffstat (limited to 'models/repo_watch.go')
-rw-r--r--models/repo_watch.go129
1 files changed, 86 insertions, 43 deletions
diff --git a/models/repo_watch.go b/models/repo_watch.go
index 7d421081a4..9b3659dbf5 100644
--- a/models/repo_watch.go
+++ b/models/repo_watch.go
@@ -164,68 +164,111 @@ func (repo *Repository) GetWatchers(page int) ([]*User, error) {
return users, sess.Find(&users)
}
-func notifyWatchers(e Engine, act *Action) error {
- // Add feeds for user self and all watchers.
- watches, err := getWatchers(e, act.RepoID)
- if err != nil {
- return fmt.Errorf("get watchers: %v", err)
- }
-
- // Add feed for actioner.
- act.UserID = act.ActUserID
- if _, err = e.InsertOne(act); err != nil {
- return fmt.Errorf("insert new actioner: %v", err)
- }
-
- act.loadRepo()
- // check repo owner exist.
- if err := act.Repo.getOwner(e); err != nil {
- return fmt.Errorf("can't get repo owner: %v", err)
- }
+func notifyWatchers(e Engine, actions ...*Action) error {
+ var watchers []*Watch
+ var repo *Repository
+ var err error
+ var permCode []bool
+ var permIssue []bool
+ var permPR []bool
+
+ for _, act := range actions {
+ repoChanged := repo == nil || repo.ID != act.RepoID
+
+ if repoChanged {
+ // Add feeds for user self and all watchers.
+ watchers, err = getWatchers(e, act.RepoID)
+ if err != nil {
+ return fmt.Errorf("get watchers: %v", err)
+ }
+ }
- // Add feed for organization
- if act.Repo.Owner.IsOrganization() && act.ActUserID != act.Repo.Owner.ID {
- act.ID = 0
- act.UserID = act.Repo.Owner.ID
+ // Add feed for actioner.
+ act.UserID = act.ActUserID
if _, err = e.InsertOne(act); err != nil {
return fmt.Errorf("insert new actioner: %v", err)
}
- }
- for i := range watches {
- if act.ActUserID == watches[i].UserID {
- continue
+ if repoChanged {
+ act.loadRepo()
+ repo = act.Repo
+
+ // check repo owner exist.
+ if err := act.Repo.getOwner(e); err != nil {
+ return fmt.Errorf("can't get repo owner: %v", err)
+ }
+ } else if act.Repo == nil {
+ act.Repo = repo
}
- act.ID = 0
- act.UserID = watches[i].UserID
- act.Repo.Units = nil
+ // 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)
+ }
+ }
- switch act.OpType {
- case ActionCommitRepo, ActionPushTag, ActionDeleteTag, ActionDeleteBranch:
- if !act.Repo.checkUnitUser(e, act.UserID, false, UnitTypeCode) {
- continue
+ if repoChanged {
+ permCode = make([]bool, len(watchers))
+ permIssue = make([]bool, len(watchers))
+ permPR = make([]bool, len(watchers))
+ for i, watcher := range watchers {
+ user, err := getUserByID(e, watcher.UserID)
+ if err != nil {
+ permCode[i] = false
+ permIssue[i] = false
+ permPR[i] = false
+ continue
+ }
+ perm, err := getUserRepoPermission(e, repo, user)
+ if err != nil {
+ permCode[i] = false
+ permIssue[i] = false
+ permPR[i] = false
+ continue
+ }
+ permCode[i] = perm.CanRead(UnitTypeCode)
+ permIssue[i] = perm.CanRead(UnitTypeIssues)
+ permPR[i] = perm.CanRead(UnitTypePullRequests)
}
- case ActionCreateIssue, ActionCommentIssue, ActionCloseIssue, ActionReopenIssue:
- if !act.Repo.checkUnitUser(e, act.UserID, false, UnitTypeIssues) {
+ }
+
+ for i, watcher := range watchers {
+ if act.ActUserID == watcher.UserID {
continue
}
- case ActionCreatePullRequest, ActionCommentPull, ActionMergePullRequest, ActionClosePullRequest, ActionReopenPullRequest:
- if !act.Repo.checkUnitUser(e, act.UserID, false, UnitTypePullRequests) {
- continue
+ act.ID = 0
+ act.UserID = watcher.UserID
+ act.Repo.Units = nil
+
+ switch act.OpType {
+ case ActionCommitRepo, ActionPushTag, ActionDeleteTag, 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)
+ 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(act *Action) error {
- return notifyWatchers(x, act)
+func NotifyWatchers(actions ...*Action) error {
+ return notifyWatchers(x, actions...)
}
// NotifyWatchersActions creates batch of actions for every watcher.