diff options
author | zeripath <art27@cantab.net> | 2019-12-26 11:29:45 +0000 |
---|---|---|
committer | Lauris BH <lauris@nix.lv> | 2019-12-26 13:29:45 +0200 |
commit | 7bfb83e0642530183cc15f3c9208d95f88fdc79a (patch) | |
tree | 7e3670ea97ac6e9304a8df5488fed6839d1f3dc4 /models/repo_watch.go | |
parent | 114d474f02f8e4148b9fd65c8f2bc7b47f924c17 (diff) | |
download | gitea-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.go | 129 |
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. |