Move PushUpdateAddDeleteTags to repository module from models (#10106)
* Move PushUpdateAddDeleteTags to repository module from models * Fix deadlock on sqlite
This commit is contained in:
parent
e959d1a48b
commit
48ce135cc9
8 changed files with 176 additions and 166 deletions
|
@ -10,6 +10,19 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// env keys for git hooks need
|
||||
const (
|
||||
EnvRepoName = "GITEA_REPO_NAME"
|
||||
EnvRepoUsername = "GITEA_REPO_USER_NAME"
|
||||
EnvRepoIsWiki = "GITEA_REPO_IS_WIKI"
|
||||
EnvPusherName = "GITEA_PUSHER_NAME"
|
||||
EnvPusherEmail = "GITEA_PUSHER_EMAIL"
|
||||
EnvPusherID = "GITEA_PUSHER_ID"
|
||||
EnvKeyID = "GITEA_KEY_ID"
|
||||
EnvIsDeployKey = "GITEA_IS_DEPLOY_KEY"
|
||||
EnvIsInternal = "GITEA_INTERNAL_PUSH"
|
||||
)
|
||||
|
||||
// InternalPushingEnvironment returns an os environment to switch off hooks on push
|
||||
// It is recommended to avoid using this unless you are pushing within a transaction
|
||||
// or if you absolutely are sure that post-receive and pre-receive will do nothing
|
||||
|
|
|
@ -119,9 +119,15 @@ func InsertRelease(rel *Release) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// InsertReleasesContext insert releases
|
||||
func InsertReleasesContext(ctx DBContext, rels []*Release) error {
|
||||
_, err := ctx.e.Insert(rels)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateRelease updates all columns of a release
|
||||
func UpdateRelease(rel *Release) error {
|
||||
_, err := x.ID(rel.ID).AllCols().Update(rel)
|
||||
func UpdateRelease(ctx DBContext, rel *Release) error {
|
||||
_, err := ctx.e.ID(rel.ID).AllCols().Update(rel)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -212,10 +218,10 @@ func GetReleasesByRepoID(repoID int64, opts FindReleasesOptions) ([]*Release, er
|
|||
}
|
||||
|
||||
// GetReleasesByRepoIDAndNames returns a list of releases of repository according repoID and tagNames.
|
||||
func GetReleasesByRepoIDAndNames(repoID int64, tagNames []string) (rels []*Release, err error) {
|
||||
err = x.
|
||||
Desc("created_unix").
|
||||
func GetReleasesByRepoIDAndNames(ctx DBContext, repoID int64, tagNames []string) (rels []*Release, err error) {
|
||||
err = ctx.e.
|
||||
In("tag_name", tagNames).
|
||||
Desc("created_unix").
|
||||
Find(&rels, Release{RepoID: repoID})
|
||||
return rels, err
|
||||
}
|
||||
|
|
158
models/update.go
158
models/update.go
|
@ -7,42 +7,8 @@ package models
|
|||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
)
|
||||
|
||||
// env keys for git hooks need
|
||||
const (
|
||||
EnvRepoName = "GITEA_REPO_NAME"
|
||||
EnvRepoUsername = "GITEA_REPO_USER_NAME"
|
||||
EnvRepoIsWiki = "GITEA_REPO_IS_WIKI"
|
||||
EnvPusherName = "GITEA_PUSHER_NAME"
|
||||
EnvPusherEmail = "GITEA_PUSHER_EMAIL"
|
||||
EnvPusherID = "GITEA_PUSHER_ID"
|
||||
EnvKeyID = "GITEA_KEY_ID"
|
||||
EnvIsDeployKey = "GITEA_IS_DEPLOY_KEY"
|
||||
EnvIsInternal = "GITEA_INTERNAL_PUSH"
|
||||
)
|
||||
|
||||
// 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()
|
||||
|
@ -57,6 +23,11 @@ func PushUpdateDeleteTags(repo *Repository, tags []string) error {
|
|||
return sess.Commit()
|
||||
}
|
||||
|
||||
// PushUpdateDeleteTagsContext updates a number of delete tags with context
|
||||
func PushUpdateDeleteTagsContext(ctx DBContext, repo *Repository, tags []string) error {
|
||||
return pushUpdateDeleteTags(ctx.e, repo, tags)
|
||||
}
|
||||
|
||||
func pushUpdateDeleteTags(e Engine, repo *Repository, tags []string) error {
|
||||
if len(tags) == 0 {
|
||||
return nil
|
||||
|
@ -111,125 +82,6 @@ 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
|
||||
}
|
||||
|
||||
// SaveOrUpdateTag must be called for any push actions to add tag
|
||||
func SaveOrUpdateTag(repo *Repository, newRel *Release) error {
|
||||
rel, err := GetRelease(repo.ID, newRel.TagName)
|
||||
|
|
|
@ -1452,6 +1452,11 @@ func ValidateCommitsWithEmails(oldCommits *list.List) *list.List {
|
|||
|
||||
// GetUserByEmail returns the user object by given e-mail if exists.
|
||||
func GetUserByEmail(email string) (*User, error) {
|
||||
return GetUserByEmailContext(DefaultDBContext(), email)
|
||||
}
|
||||
|
||||
// GetUserByEmailContext returns the user object by given e-mail if exists with db context
|
||||
func GetUserByEmailContext(ctx DBContext, email string) (*User, error) {
|
||||
if len(email) == 0 {
|
||||
return nil, ErrUserNotExist{0, email, 0}
|
||||
}
|
||||
|
@ -1459,7 +1464,7 @@ func GetUserByEmail(email string) (*User, error) {
|
|||
email = strings.ToLower(email)
|
||||
// First try to find the user by primary email
|
||||
user := &User{Email: email}
|
||||
has, err := x.Get(user)
|
||||
has, err := ctx.e.Get(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1469,19 +1474,19 @@ func GetUserByEmail(email string) (*User, error) {
|
|||
|
||||
// Otherwise, check in alternative list for activated email addresses
|
||||
emailAddress := &EmailAddress{Email: email, IsActivated: true}
|
||||
has, err = x.Get(emailAddress)
|
||||
has, err = ctx.e.Get(emailAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if has {
|
||||
return GetUserByID(emailAddress.UID)
|
||||
return getUserByID(ctx.e, emailAddress.UID)
|
||||
}
|
||||
|
||||
// Finally, if email address is the protected email address:
|
||||
if strings.HasSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress)) {
|
||||
username := strings.TrimSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress))
|
||||
user := &User{LowerName: username}
|
||||
has, err := x.Get(user)
|
||||
has, err := ctx.e.Get(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -732,7 +732,7 @@ func createCommitRepoActions(repo *models.Repository, gitRepo *git.Repository, o
|
|||
Commits: commits,
|
||||
})
|
||||
}
|
||||
if err := models.PushUpdateAddDeleteTags(repo, gitRepo, addTags, delTags); err != nil {
|
||||
if err := repo_module.PushUpdateAddDeleteTags(repo, gitRepo, addTags, delTags); err != nil {
|
||||
return nil, fmt.Errorf("PushUpdateAddDeleteTags: %v", err)
|
||||
}
|
||||
return actions, nil
|
||||
|
|
134
modules/repository/update.go
Normal file
134
modules/repository/update.go
Normal file
|
@ -0,0 +1,134 @@
|
|||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
)
|
||||
|
||||
// PushUpdateAddDeleteTags updates a number of added and delete tags
|
||||
func PushUpdateAddDeleteTags(repo *models.Repository, gitRepo *git.Repository, addTags, delTags []string) error {
|
||||
return models.WithTx(func(ctx models.DBContext) error {
|
||||
if err := models.PushUpdateDeleteTagsContext(ctx, repo, delTags); err != nil {
|
||||
return err
|
||||
}
|
||||
return pushUpdateAddTags(ctx, repo, gitRepo, addTags)
|
||||
})
|
||||
}
|
||||
|
||||
// pushUpdateAddTags updates a number of add tags
|
||||
func pushUpdateAddTags(ctx models.DBContext, repo *models.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, err := models.GetReleasesByRepoIDAndNames(ctx, repo.ID, lowerTags)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetReleasesByRepoIDAndNames: %v", err)
|
||||
}
|
||||
relMap := make(map[string]*models.Release)
|
||||
for _, rel := range releases {
|
||||
relMap[rel.LowerTagName] = rel
|
||||
}
|
||||
|
||||
newReleases := make([]*models.Release, 0, len(lowerTags)-len(relMap))
|
||||
|
||||
emailToUser := make(map[string]*models.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 *models.User
|
||||
var createdAt = time.Unix(1, 0)
|
||||
|
||||
if sig != nil {
|
||||
var ok bool
|
||||
author, ok = emailToUser[sig.Email]
|
||||
if !ok {
|
||||
author, err = models.GetUserByEmailContext(ctx, sig.Email)
|
||||
if err != nil && !models.IsErrUserNotExist(err) {
|
||||
return fmt.Errorf("GetUserByEmail: %v", err)
|
||||
}
|
||||
if author != nil {
|
||||
emailToUser[sig.Email] = author
|
||||
}
|
||||
}
|
||||
createdAt = sig.When
|
||||
}
|
||||
|
||||
commitsCount, err := commit.CommitsCount()
|
||||
if err != nil {
|
||||
return fmt.Errorf("CommitsCount: %v", err)
|
||||
}
|
||||
|
||||
rel, has := relMap[lowerTag]
|
||||
|
||||
if !has {
|
||||
rel = &models.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 = models.UpdateRelease(ctx, rel); err != nil {
|
||||
return fmt.Errorf("Update: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(newReleases) > 0 {
|
||||
if err = models.InsertReleasesContext(ctx, newReleases); err != nil {
|
||||
return fmt.Errorf("Insert: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -420,7 +420,7 @@ func RedirectDownload(ctx *context.Context) {
|
|||
)
|
||||
tagNames := []string{vTag}
|
||||
curRepo := ctx.Repo.Repository
|
||||
releases, err := models.GetReleasesByRepoIDAndNames(curRepo.ID, tagNames)
|
||||
releases, err := models.GetReleasesByRepoIDAndNames(models.DefaultDBContext(), curRepo.ID, tagNames)
|
||||
if err != nil {
|
||||
if models.IsErrAttachmentNotExist(err) {
|
||||
ctx.Error(404)
|
||||
|
|
|
@ -102,7 +102,7 @@ func UpdateRelease(doer *models.User, gitRepo *git.Repository, rel *models.Relea
|
|||
}
|
||||
rel.LowerTagName = strings.ToLower(rel.TagName)
|
||||
|
||||
if err = models.UpdateRelease(rel); err != nil {
|
||||
if err = models.UpdateRelease(models.DefaultDBContext(), rel); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ func DeleteReleaseByID(id int64, doer *models.User, delTag bool) error {
|
|||
rel.Title = ""
|
||||
rel.Note = ""
|
||||
|
||||
if err = models.UpdateRelease(rel); err != nil {
|
||||
if err = models.UpdateRelease(models.DefaultDBContext(), rel); err != nil {
|
||||
return fmt.Errorf("Update: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue