diff options
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) |