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/update.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/update.go')
-rw-r--r-- | models/update.go | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/models/update.go b/models/update.go index deac91b6dc..1105c9a828 100644 --- a/models/update.go +++ b/models/update.go @@ -53,6 +53,66 @@ func ListToPushCommits(l *list.List) *PushCommits { return &PushCommits{l.Len(), commits, "", make(map[string]string), make(map[string]*User)} } +// PushUpdateAddDeleteTags updates a number of added and delete tags +func PushUpdateAddDeleteTags(repo *Repository, gitRepo *git.Repository, addTags, delTags []string) error { + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return fmt.Errorf("Unable to begin sess in PushUpdateDeleteTags: %v", err) + } + if err := pushUpdateDeleteTags(sess, repo, delTags); err != nil { + return err + } + if err := pushUpdateAddTags(sess, repo, gitRepo, addTags); err != nil { + return err + } + + return sess.Commit() +} + +// PushUpdateDeleteTags updates a number of delete tags +func PushUpdateDeleteTags(repo *Repository, tags []string) error { + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return fmt.Errorf("Unable to begin sess in PushUpdateDeleteTags: %v", err) + } + if err := pushUpdateDeleteTags(sess, repo, tags); err != nil { + return err + } + + return sess.Commit() +} + +func pushUpdateDeleteTags(e Engine, repo *Repository, tags []string) error { + if len(tags) == 0 { + return nil + } + lowerTags := make([]string, 0, len(tags)) + for _, tag := range tags { + lowerTags = append(lowerTags, strings.ToLower(tag)) + } + + if _, err := e. + Where("repo_id = ? AND is_tag = ?", repo.ID, true). + In("lower_tag_name", lowerTags). + Delete(new(Release)); err != nil { + return fmt.Errorf("Delete: %v", err) + } + + if _, err := e. + Where("repo_id = ? AND is_tag = ?", repo.ID, false). + In("lower_tag_name", lowerTags). + SetExpr("is_draft", true). + SetExpr("num_commits", 0). + SetExpr("sha1", ""). + Update(new(Release)); err != nil { + return fmt.Errorf("Update: %v", err) + } + + return nil +} + // PushUpdateDeleteTag must be called for any push actions to delete tag func PushUpdateDeleteTag(repo *Repository, tagName string) error { rel, err := GetRelease(repo.ID, tagName) @@ -78,6 +138,125 @@ func PushUpdateDeleteTag(repo *Repository, tagName string) error { return nil } +// PushUpdateAddTags updates a number of add tags +func PushUpdateAddTags(repo *Repository, gitRepo *git.Repository, tags []string) error { + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return fmt.Errorf("Unable to begin sess in PushUpdateAddTags: %v", err) + } + if err := pushUpdateAddTags(sess, repo, gitRepo, tags); err != nil { + return err + } + + return sess.Commit() +} +func pushUpdateAddTags(e Engine, repo *Repository, gitRepo *git.Repository, tags []string) error { + if len(tags) == 0 { + return nil + } + + lowerTags := make([]string, 0, len(tags)) + for _, tag := range tags { + lowerTags = append(lowerTags, strings.ToLower(tag)) + } + + releases := make([]Release, 0, len(tags)) + if err := e.Where("repo_id = ?", repo.ID). + In("lower_tag_name", lowerTags).Find(&releases); err != nil { + return fmt.Errorf("GetRelease: %v", err) + } + relMap := make(map[string]*Release) + for _, rel := range releases { + relMap[rel.LowerTagName] = &rel + } + + newReleases := make([]*Release, 0, len(lowerTags)-len(relMap)) + + emailToUser := make(map[string]*User) + + for i, lowerTag := range lowerTags { + tag, err := gitRepo.GetTag(tags[i]) + if err != nil { + return fmt.Errorf("GetTag: %v", err) + } + commit, err := tag.Commit() + if err != nil { + return fmt.Errorf("Commit: %v", err) + } + + sig := tag.Tagger + if sig == nil { + sig = commit.Author + } + if sig == nil { + sig = commit.Committer + } + var author *User + var createdAt = time.Unix(1, 0) + + if sig != nil { + var ok bool + author, ok = emailToUser[sig.Email] + if !ok { + author, err = GetUserByEmail(sig.Email) + if err != nil && !IsErrUserNotExist(err) { + return fmt.Errorf("GetUserByEmail: %v", err) + } + } + createdAt = sig.When + } + + commitsCount, err := commit.CommitsCount() + if err != nil { + return fmt.Errorf("CommitsCount: %v", err) + } + + rel, has := relMap[lowerTag] + + if !has { + rel = &Release{ + RepoID: repo.ID, + Title: "", + TagName: tags[i], + LowerTagName: lowerTag, + Target: "", + Sha1: commit.ID.String(), + NumCommits: commitsCount, + Note: "", + IsDraft: false, + IsPrerelease: false, + IsTag: true, + CreatedUnix: timeutil.TimeStamp(createdAt.Unix()), + } + if author != nil { + rel.PublisherID = author.ID + } + + newReleases = append(newReleases, rel) + } else { + rel.Sha1 = commit.ID.String() + rel.CreatedUnix = timeutil.TimeStamp(createdAt.Unix()) + rel.NumCommits = commitsCount + rel.IsDraft = false + if rel.IsTag && author != nil { + rel.PublisherID = author.ID + } + if _, err = e.ID(rel.ID).AllCols().Update(rel); err != nil { + return fmt.Errorf("Update: %v", err) + } + } + } + + if len(newReleases) > 0 { + if _, err := e.Insert(newReleases); err != nil { + return fmt.Errorf("Insert: %v", err) + } + } + + return nil +} + // PushUpdateAddTag must be called for any push actions to add tag func PushUpdateAddTag(repo *Repository, gitRepo *git.Repository, tagName string) error { rel, err := GetRelease(repo.ID, tagName) |