1
0
Просмотр исходного кода

Complete XORM to GORM migration for internal/database/pull.go

Co-authored-by: unknwon <2946214+unknwon@users.noreply.github.com>
copilot-swe-agent[bot] 2 недель назад
Родитель
Сommit
748ecbfdf3
1 измененных файлов с 162 добавлено и 163 удалено
  1. 162 163
      internal/database/pull.go

+ 162 - 163
internal/database/pull.go

@@ -200,188 +200,185 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
 			return errors.Newf("Issue.changeStatus: %v", err)
 		}
 
-	headRepoPath := RepoPath(pr.HeadUserName, pr.HeadRepo.Name)
-	headGitRepo, err := git.Open(headRepoPath)
-	if err != nil {
-		return errors.Newf("open repository: %v", err)
-	}
+			headRepoPath := RepoPath(pr.HeadUserName, pr.HeadRepo.Name)
+		headGitRepo, err := git.Open(headRepoPath)
+		if err != nil {
+			return errors.Newf("open repository: %v", err)
+		}
 
-	// Create temporary directory to store temporary copy of the base repository,
-	// and clean it up when operation finished regardless of succeed or not.
-	tmpBasePath := filepath.Join(conf.Server.AppDataPath, "tmp", "repos", com.ToStr(time.Now().Nanosecond())+".git")
-	if err = os.MkdirAll(filepath.Dir(tmpBasePath), os.ModePerm); err != nil {
-		return err
-	}
-	defer func() {
-		_ = os.RemoveAll(filepath.Dir(tmpBasePath))
-	}()
+		// Create temporary directory to store temporary copy of the base repository,
+		// and clean it up when operation finished regardless of succeed or not.
+		tmpBasePath := filepath.Join(conf.Server.AppDataPath, "tmp", "repos", com.ToStr(time.Now().Nanosecond())+".git")
+		if err = os.MkdirAll(filepath.Dir(tmpBasePath), os.ModePerm); err != nil {
+			return err
+		}
+		defer func() {
+			_ = os.RemoveAll(filepath.Dir(tmpBasePath))
+		}()
+
+		// Clone the base repository to the defined temporary directory,
+		// and checks out to base branch directly.
+		var stderr string
+		if _, stderr, err = process.ExecTimeout(5*time.Minute,
+			fmt.Sprintf("PullRequest.Merge (git clone): %s", tmpBasePath),
+			"git", "clone", "-b", pr.BaseBranch, baseGitRepo.Path(), tmpBasePath); err != nil {
+			return errors.Newf("git clone: %s", stderr)
+		}
 
-	// Clone the base repository to the defined temporary directory,
-	// and checks out to base branch directly.
-	var stderr string
-	if _, stderr, err = process.ExecTimeout(5*time.Minute,
-		fmt.Sprintf("PullRequest.Merge (git clone): %s", tmpBasePath),
-		"git", "clone", "-b", pr.BaseBranch, baseGitRepo.Path(), tmpBasePath); err != nil {
-		return errors.Newf("git clone: %s", stderr)
-	}
+		// Add remote which points to the head repository.
+		if _, stderr, err = process.ExecDir(-1, tmpBasePath,
+			fmt.Sprintf("PullRequest.Merge (git remote add): %s", tmpBasePath),
+			"git", "remote", "add", "head_repo", headRepoPath); err != nil {
+			return errors.Newf("git remote add [%s -> %s]: %s", headRepoPath, tmpBasePath, stderr)
+		}
 
-	// Add remote which points to the head repository.
-	if _, stderr, err = process.ExecDir(-1, tmpBasePath,
-		fmt.Sprintf("PullRequest.Merge (git remote add): %s", tmpBasePath),
-		"git", "remote", "add", "head_repo", headRepoPath); err != nil {
-		return errors.Newf("git remote add [%s -> %s]: %s", headRepoPath, tmpBasePath, stderr)
-	}
+		// Fetch information from head repository to the temporary copy.
+		if _, stderr, err = process.ExecDir(-1, tmpBasePath,
+			fmt.Sprintf("PullRequest.Merge (git fetch): %s", tmpBasePath),
+			"git", "fetch", "head_repo"); err != nil {
+			return errors.Newf("git fetch [%s -> %s]: %s", headRepoPath, tmpBasePath, stderr)
+		}
 
-	// Fetch information from head repository to the temporary copy.
-	if _, stderr, err = process.ExecDir(-1, tmpBasePath,
-		fmt.Sprintf("PullRequest.Merge (git fetch): %s", tmpBasePath),
-		"git", "fetch", "head_repo"); err != nil {
-		return errors.Newf("git fetch [%s -> %s]: %s", headRepoPath, tmpBasePath, stderr)
-	}
+		remoteHeadBranch := "head_repo/" + pr.HeadBranch
 
-	remoteHeadBranch := "head_repo/" + pr.HeadBranch
+		// Check if merge style is allowed, reset to default style if not
+		if mergeStyle == MergeStyleRebase && !pr.BaseRepo.PullsAllowRebase {
+			mergeStyle = MergeStyleRegular
+		}
 
-	// Check if merge style is allowed, reset to default style if not
-	if mergeStyle == MergeStyleRebase && !pr.BaseRepo.PullsAllowRebase {
-		mergeStyle = MergeStyleRegular
-	}
+		switch mergeStyle {
+		case MergeStyleRegular: // Create merge commit
 
-	switch mergeStyle {
-	case MergeStyleRegular: // Create merge commit
+			// Merge changes from head branch.
+			if _, stderr, err = process.ExecDir(-1, tmpBasePath,
+				fmt.Sprintf("PullRequest.Merge (git merge --no-ff --no-commit): %s", tmpBasePath),
+				"git", "merge", "--no-ff", "--no-commit", remoteHeadBranch); err != nil {
+				return errors.Newf("git merge --no-ff --no-commit [%s]: %v - %s", tmpBasePath, err, stderr)
+			}
 
-		// Merge changes from head branch.
-		if _, stderr, err = process.ExecDir(-1, tmpBasePath,
-			fmt.Sprintf("PullRequest.Merge (git merge --no-ff --no-commit): %s", tmpBasePath),
-			"git", "merge", "--no-ff", "--no-commit", remoteHeadBranch); err != nil {
-			return errors.Newf("git merge --no-ff --no-commit [%s]: %v - %s", tmpBasePath, err, stderr)
-		}
+			// Create a merge commit for the base branch.
+			if _, stderr, err = process.ExecDir(-1, tmpBasePath,
+				fmt.Sprintf("PullRequest.Merge (git merge): %s", tmpBasePath),
+				"git", "commit", fmt.Sprintf("--author='%s <%s>'", doer.DisplayName(), doer.Email),
+				"-m", fmt.Sprintf("Merge branch '%s' of %s/%s into %s", pr.HeadBranch, pr.HeadUserName, pr.HeadRepo.Name, pr.BaseBranch),
+				"-m", commitDescription); err != nil {
+				return errors.Newf("git commit [%s]: %v - %s", tmpBasePath, err, stderr)
+			}
 
-		// Create a merge commit for the base branch.
-		if _, stderr, err = process.ExecDir(-1, tmpBasePath,
-			fmt.Sprintf("PullRequest.Merge (git merge): %s", tmpBasePath),
-			"git", "commit", fmt.Sprintf("--author='%s <%s>'", doer.DisplayName(), doer.Email),
-			"-m", fmt.Sprintf("Merge branch '%s' of %s/%s into %s", pr.HeadBranch, pr.HeadUserName, pr.HeadRepo.Name, pr.BaseBranch),
-			"-m", commitDescription); err != nil {
-			return errors.Newf("git commit [%s]: %v - %s", tmpBasePath, err, stderr)
-		}
+		case MergeStyleRebase: // Rebase before merging
 
-	case MergeStyleRebase: // Rebase before merging
+			// Rebase head branch based on base branch, this creates a non-branch commit state.
+			if _, stderr, err = process.ExecDir(-1, tmpBasePath,
+				fmt.Sprintf("PullRequest.Merge (git rebase): %s", tmpBasePath),
+				"git", "rebase", "--quiet", pr.BaseBranch, remoteHeadBranch); err != nil {
+				return errors.Newf("git rebase [%s on %s]: %s", remoteHeadBranch, pr.BaseBranch, stderr)
+			}
 
-		// Rebase head branch based on base branch, this creates a non-branch commit state.
-		if _, stderr, err = process.ExecDir(-1, tmpBasePath,
-			fmt.Sprintf("PullRequest.Merge (git rebase): %s", tmpBasePath),
-			"git", "rebase", "--quiet", pr.BaseBranch, remoteHeadBranch); err != nil {
-			return errors.Newf("git rebase [%s on %s]: %s", remoteHeadBranch, pr.BaseBranch, stderr)
-		}
+			// Name non-branch commit state to a new temporary branch in order to save changes.
+			tmpBranch := com.ToStr(time.Now().UnixNano(), 10)
+			if _, stderr, err = process.ExecDir(-1, tmpBasePath,
+				fmt.Sprintf("PullRequest.Merge (git checkout): %s", tmpBasePath),
+				"git", "checkout", "-b", tmpBranch); err != nil {
+				return errors.Newf("git checkout '%s': %s", tmpBranch, stderr)
+			}
 
-		// Name non-branch commit state to a new temporary branch in order to save changes.
-		tmpBranch := com.ToStr(time.Now().UnixNano(), 10)
-		if _, stderr, err = process.ExecDir(-1, tmpBasePath,
-			fmt.Sprintf("PullRequest.Merge (git checkout): %s", tmpBasePath),
-			"git", "checkout", "-b", tmpBranch); err != nil {
-			return errors.Newf("git checkout '%s': %s", tmpBranch, stderr)
-		}
+			// Check out the base branch to be operated on.
+			if _, stderr, err = process.ExecDir(-1, tmpBasePath,
+				fmt.Sprintf("PullRequest.Merge (git checkout): %s", tmpBasePath),
+				"git", "checkout", pr.BaseBranch); err != nil {
+				return errors.Newf("git checkout '%s': %s", pr.BaseBranch, stderr)
+			}
 
-		// Check out the base branch to be operated on.
-		if _, stderr, err = process.ExecDir(-1, tmpBasePath,
-			fmt.Sprintf("PullRequest.Merge (git checkout): %s", tmpBasePath),
-			"git", "checkout", pr.BaseBranch); err != nil {
-			return errors.Newf("git checkout '%s': %s", pr.BaseBranch, stderr)
+			// Merge changes from temporary branch to the base branch.
+			if _, stderr, err = process.ExecDir(-1, tmpBasePath,
+				fmt.Sprintf("PullRequest.Merge (git merge): %s", tmpBasePath),
+				"git", "merge", tmpBranch); err != nil {
+				return errors.Newf("git merge [%s]: %v - %s", tmpBasePath, err, stderr)
+			}
+
+		default:
+			return errors.Newf("unknown merge style: %s", mergeStyle)
 		}
 
-		// Merge changes from temporary branch to the base branch.
+		// Push changes on base branch to upstream.
 		if _, stderr, err = process.ExecDir(-1, tmpBasePath,
-			fmt.Sprintf("PullRequest.Merge (git merge): %s", tmpBasePath),
-			"git", "merge", tmpBranch); err != nil {
-			return errors.Newf("git merge [%s]: %v - %s", tmpBasePath, err, stderr)
+			fmt.Sprintf("PullRequest.Merge (git push): %s", tmpBasePath),
+			"git", "push", baseGitRepo.Path(), pr.BaseBranch); err != nil {
+			return errors.Newf("git push: %s", stderr)
 		}
 
-	default:
-		return errors.Newf("unknown merge style: %s", mergeStyle)
-	}
-
-	// Push changes on base branch to upstream.
-	if _, stderr, err = process.ExecDir(-1, tmpBasePath,
-		fmt.Sprintf("PullRequest.Merge (git push): %s", tmpBasePath),
-		"git", "push", baseGitRepo.Path(), pr.BaseBranch); err != nil {
-		return errors.Newf("git push: %s", stderr)
-	}
-
-	pr.MergedCommitID, err = headGitRepo.BranchCommitID(pr.HeadBranch)
-	if err != nil {
-		return errors.Newf("get head branch %q commit ID: %v", pr.HeadBranch, err)
-	}
-
-	pr.HasMerged = true
-	pr.Merged = time.Now()
-	pr.MergerID = doer.ID
-	if _, err = sess.ID(pr.ID).AllCols().Update(pr); err != nil {
-		return errors.Newf("update pull request: %v", err)
-	}
+		pr.MergedCommitID, err = headGitRepo.BranchCommitID(pr.HeadBranch)
+		if err != nil {
+			return errors.Newf("get head branch %q commit ID: %v", pr.HeadBranch, err)
+		}
 
-	if err = sess.Commit(); err != nil {
-		return errors.Newf("commit: %v", err)
-	}
+		pr.HasMerged = true
+		pr.Merged = time.Now()
+		pr.MergerID = doer.ID
+		if err := tx.Model(&PullRequest{}).Where("id = ?", pr.ID).Updates(pr).Error; err != nil {
+			return errors.Newf("update pull request: %v", err)
+		}
 
-	if err = Handle.Actions().MergePullRequest(ctx, doer, pr.Issue.Repo.Owner, pr.Issue.Repo, pr.Issue); err != nil {
-		log.Error("Failed to create action for merge pull request, pull_request_id: %d, error: %v", pr.ID, err)
-	}
+		if err = Handle.Actions().MergePullRequest(ctx, doer, pr.Issue.Repo.Owner, pr.Issue.Repo, pr.Issue); err != nil {
+			log.Error("Failed to create action for merge pull request, pull_request_id: %d, error: %v", pr.ID, err)
+		}
 
-	// Reload pull request information.
-	if err = pr.LoadAttributes(); err != nil {
-		log.Error("LoadAttributes: %v", err)
-		return nil
-	}
-	if err = PrepareWebhooks(pr.Issue.Repo, HookEventTypePullRequest, &api.PullRequestPayload{
-		Action:      api.HOOK_ISSUE_CLOSED,
-		Index:       pr.Index,
-		PullRequest: pr.APIFormat(),
-		Repository:  pr.Issue.Repo.APIFormatLegacy(nil),
-		Sender:      doer.APIFormat(),
-	}); err != nil {
-		log.Error("PrepareWebhooks: %v", err)
-		return nil
-	}
+		// Reload pull request information.
+		if err = pr.LoadAttributes(); err != nil {
+			log.Error("LoadAttributes: %v", err)
+			return nil
+		}
+		if err = PrepareWebhooks(pr.Issue.Repo, HookEventTypePullRequest, &api.PullRequestPayload{
+			Action:      api.HOOK_ISSUE_CLOSED,
+			Index:       pr.Index,
+			PullRequest: pr.APIFormat(),
+			Repository:  pr.Issue.Repo.APIFormatLegacy(nil),
+			Sender:      doer.APIFormat(),
+		}); err != nil {
+			log.Error("PrepareWebhooks: %v", err)
+			return nil
+		}
 
-	commits, err := headGitRepo.RevList([]string{pr.MergeBase + "..." + pr.MergedCommitID})
-	if err != nil {
-		log.Error("Failed to list commits [merge_base: %s, merged_commit_id: %s]: %v", pr.MergeBase, pr.MergedCommitID, err)
-		return nil
-	}
+		commits, err := headGitRepo.RevList([]string{pr.MergeBase + "..." + pr.MergedCommitID})
+		if err != nil {
+			log.Error("Failed to list commits [merge_base: %s, merged_commit_id: %s]: %v", pr.MergeBase, pr.MergedCommitID, err)
+			return nil
+		}
 
-	// NOTE: It is possible that head branch is not fully sync with base branch
-	// for merge commits, so we need to get latest head commit and append merge
-	// commit manually to avoid strange diff commits produced.
-	mergeCommit, err := baseGitRepo.BranchCommit(pr.BaseBranch)
-	if err != nil {
-		log.Error("Failed to get base branch %q commit: %v", pr.BaseBranch, err)
-		return nil
-	}
-	if mergeStyle == MergeStyleRegular {
-		commits = append([]*git.Commit{mergeCommit}, commits...)
-	}
+		// NOTE: It is possible that head branch is not fully sync with base branch
+		// for merge commits, so we need to get latest head commit and append merge
+		// commit manually to avoid strange diff commits produced.
+		mergeCommit, err := baseGitRepo.BranchCommit(pr.BaseBranch)
+		if err != nil {
+			log.Error("Failed to get base branch %q commit: %v", pr.BaseBranch, err)
+			return nil
+		}
+		if mergeStyle == MergeStyleRegular {
+			commits = append([]*git.Commit{mergeCommit}, commits...)
+		}
 
-	pcs, err := CommitsToPushCommits(commits).APIFormat(ctx, Handle.Users(), pr.BaseRepo.RepoPath(), pr.BaseRepo.HTMLURL())
-	if err != nil {
-		log.Error("Failed to convert to API payload commits: %v", err)
-		return nil
-	}
+		pcs, err := CommitsToPushCommits(commits).APIFormat(ctx, Handle.Users(), pr.BaseRepo.RepoPath(), pr.BaseRepo.HTMLURL())
+		if err != nil {
+			log.Error("Failed to convert to API payload commits: %v", err)
+			return nil
+		}
 
-	p := &api.PushPayload{
-		Ref:        git.RefsHeads + pr.BaseBranch,
-		Before:     pr.MergeBase,
-		After:      mergeCommit.ID.String(),
-		CompareURL: conf.Server.ExternalURL + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID),
-		Commits:    pcs,
-		Repo:       pr.BaseRepo.APIFormatLegacy(nil),
-		Pusher:     pr.HeadRepo.MustOwner().APIFormat(),
-		Sender:     doer.APIFormat(),
-	}
-	if err = PrepareWebhooks(pr.BaseRepo, HookEventTypePush, p); err != nil {
-		log.Error("Failed to prepare webhooks: %v", err)
+		p := &api.PushPayload{
+			Ref:        git.RefsHeads + pr.BaseBranch,
+			Before:     pr.MergeBase,
+			After:      mergeCommit.ID.String(),
+			CompareURL: conf.Server.ExternalURL + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID),
+			Commits:    pcs,
+			Repo:       pr.BaseRepo.APIFormatLegacy(nil),
+			Pusher:     pr.HeadRepo.MustOwner().APIFormat(),
+			Sender:     doer.APIFormat(),
+		}
+		if err = PrepareWebhooks(pr.BaseRepo, HookEventTypePush, p); err != nil {
+			log.Error("Failed to prepare webhooks: %v", err)
+			return nil
+		}
 		return nil
-	}
-	return nil
+	})
 }
 
 // testPatch checks if patch can be merged to base repository without conflict.
@@ -460,12 +457,14 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
 	}
 
 	pr.IssueID = pull.ID
-	if _, err = sess.Insert(pr); err != nil {
-		return errors.Newf("insert pull repo: %v", err)
-	}
+		if err := tx.Create(pr).Error; err != nil {
+			return errors.Newf("insert pull repo: %v", err)
+		}
 
-	if err = sess.Commit(); err != nil {
-		return errors.Newf("commit: %v", err)
+		return nil
+	})
+	if err != nil {
+		return err
 	}
 
 	if err = NotifyWatchers(&Action{
@@ -745,7 +744,7 @@ func (prs PullRequestList) loadAttributes(db *gorm.DB) (err error) {
 
 	// Load attributes
 	for i := range prs {
-		if err = prs[i].loadAttributes(e); err != nil {
+		if err = prs[i].loadAttributes(db); err != nil {
 			return errors.Newf("loadAttributes [%d]: %v", prs[i].ID, err)
 		}
 	}
@@ -754,7 +753,7 @@ func (prs PullRequestList) loadAttributes(db *gorm.DB) (err error) {
 }
 
 func (prs PullRequestList) LoadAttributes() error {
-	return prs.loadAttributes(x)
+	return prs.loadAttributes(db)
 }
 
 func addHeadRepoTasks(prs []*PullRequest) {