123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- // 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 migrations
-
- import (
- "fmt"
- "path/filepath"
- "strings"
-
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
-
- "xorm.io/xorm"
- )
-
- // Copy paste from models/repo.go because we cannot import models package
- func repoPath(userName, repoName string) string {
- return filepath.Join(userPath(userName), strings.ToLower(repoName)+".git")
- }
-
- func userPath(userName string) string {
- return filepath.Join(setting.RepoRootPath, strings.ToLower(userName))
- }
-
- func fixPublisherIDforTagReleases(x *xorm.Engine) error {
- type Release struct {
- ID int64
- RepoID int64
- Sha1 string
- TagName string
- PublisherID int64
- }
-
- type Repository struct {
- ID int64
- OwnerID int64
- OwnerName string
- Name string
- }
-
- type User struct {
- ID int64
- Name string
- Email string
- }
-
- const batchSize = 100
- sess := x.NewSession()
- defer sess.Close()
-
- var (
- repo *Repository
- gitRepo *git.Repository
- user *User
- )
- defer func() {
- if gitRepo != nil {
- gitRepo.Close()
- }
- }()
- for start := 0; ; start += batchSize {
- releases := make([]*Release, 0, batchSize)
-
- if err := sess.Begin(); err != nil {
- return err
- }
-
- if err := sess.Limit(batchSize, start).
- Where("publisher_id = 0 OR publisher_id is null").
- Asc("repo_id", "id").Where("is_tag=?", true).
- Find(&releases); err != nil {
- return err
- }
-
- if len(releases) == 0 {
- break
- }
-
- for _, release := range releases {
- if repo == nil || repo.ID != release.RepoID {
- if gitRepo != nil {
- gitRepo.Close()
- gitRepo = nil
- }
- repo = new(Repository)
- has, err := sess.ID(release.RepoID).Get(repo)
- if err != nil {
- log.Error("Error whilst loading repository[%d] for release[%d] with tag name %s", release.RepoID, release.ID, release.TagName)
- return err
- } else if !has {
- log.Warn("Release[%d] is orphaned and refers to non-existing repository %d", release.ID, release.RepoID)
- log.Warn("This release should be deleted")
- continue
- }
-
- if repo.OwnerName == "" {
- // v120.go migration may not have been run correctly - we'll just replicate it here
- // because this appears to be a common-ish problem.
- if _, err := sess.Exec("UPDATE repository SET owner_name = (SELECT name FROM `user` WHERE `user`.id = repository.owner_id)"); err != nil {
- log.Error("Error whilst updating repository[%d] owner name", repo.ID)
- return err
- }
-
- if _, err := sess.ID(release.RepoID).Get(repo); err != nil {
- log.Error("Error whilst loading repository[%d] for release[%d] with tag name %s", release.RepoID, release.ID, release.TagName)
- return err
- }
- }
- gitRepo, err = git.OpenRepository(repoPath(repo.OwnerName, repo.Name))
- if err != nil {
- log.Error("Error whilst opening git repo for %-v", repo)
- return err
- }
- }
-
- commit, err := gitRepo.GetTagCommit(release.TagName)
- if err != nil {
- if git.IsErrNotExist(err) {
- log.Warn("Unable to find commit %s for Tag: %s in %-v. Cannot update publisher ID.", err.(*git.ErrNotExist).ID, release.TagName, repo)
- continue
- }
- log.Error("Error whilst getting commit for Tag: %s in %-v.", release.TagName, repo)
- return fmt.Errorf("GetTagCommit: %v", err)
- }
-
- if user == nil || !strings.EqualFold(user.Email, commit.Author.Email) {
- user = new(User)
- _, err = sess.Where("email=?", commit.Author.Email).Get(user)
- if err != nil {
- log.Error("Error whilst getting commit author by email: %s for Tag: %s in %-v.", commit.Author.Email, release.TagName, repo)
- return err
- }
-
- user.Email = commit.Author.Email
- }
-
- if user.ID <= 0 {
- continue
- }
-
- release.PublisherID = user.ID
- if _, err := sess.ID(release.ID).Cols("publisher_id").Update(release); err != nil {
- log.Error("Error whilst updating publisher[%d] for release[%d] with tag name %s", release.PublisherID, release.ID, release.TagName)
- return err
- }
- }
- if gitRepo != nil {
- gitRepo.Close()
- }
-
- if err := sess.Commit(); err != nil {
- return err
- }
- }
-
- return nil
- }
|