2025-01-27 17:43:50 +01:00

142 lines
3.5 KiB
Go

package main
import (
"bufio"
"errors"
"slices"
"strings"
"src.opensuse.org/autogits/common"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
type PRInfo struct {
pr *models.PullRequest
}
type PRSet struct {
prs []PRInfo
config *common.AutogitConfig
}
func readPRData(gitea common.GiteaPRFetcher, org, repo string, num int64, currentSet []PRInfo) ([]PRInfo, error) {
for _, p := range currentSet {
if num == p.pr.Index && repo == p.pr.Base.Repo.Name && org == p.pr.Base.Repo.Owner.UserName {
return nil, nil
}
}
pr, err := gitea.GetPullRequest(org, repo, num)
if err != nil {
return nil, err
}
_, refPRs := common.ExtractDescriptionAndPRs(bufio.NewScanner(strings.NewReader(pr.Body)))
retSet := []PRInfo{PRInfo{pr: pr}}
for _, prdata := range refPRs {
data, err := readPRData(gitea, prdata.Org, prdata.Repo, prdata.Num, slices.Concat(currentSet, retSet))
if err != nil {
return nil, err
}
retSet = slices.Concat(retSet, data)
}
return retSet, nil
}
func FetchPRSet(gitea common.GiteaPRFetcher, org, repo string, num int64, config *common.AutogitConfig) (*PRSet, error) {
prs, err := readPRData(gitea, org, repo, num, nil)
if err != nil {
return nil, err
}
return &PRSet{prs: prs, config: config}, nil
}
func (rs *PRSet) GetPrjGitPR() (*models.PullRequest, error) {
var ret *models.PullRequest
for _, prinfo := range rs.prs {
if prinfo.pr.Base.Repo.Name == rs.config.GitProjectName && prinfo.pr.Base.Repo.Owner.UserName == rs.config.Organization {
if ret == nil {
ret = prinfo.pr
} else {
return nil, errors.New("Multiple PrjGit PRs in one review set")
}
}
}
if ret != nil {
return ret, nil
}
return nil, errors.New("No PrjGit PR found")
}
func (rs *PRSet) IsConsistent() bool {
prjpr, err := rs.GetPrjGitPR()
if err != nil {
return false
}
_, prjpr_set := common.ExtractDescriptionAndPRs(bufio.NewScanner(strings.NewReader(prjpr.Body)))
if len(prjpr_set) != len(rs.prs)-1 { // 1 to many mapping
return false
}
for _, prinfo := range rs.prs {
if prjpr == prinfo.pr {
continue
}
_, prs := common.ExtractDescriptionAndPRs(bufio.NewScanner(strings.NewReader(prinfo.pr.Body)))
if len(prs) != 1 || prs[0].Repo != prjpr.Base.Repo.Name || prs[0].Org != prjpr.Base.Repo.Owner.UserName || prs[0].Num != prjpr.Index {
return false
}
}
return true
}
func (rs *PRSet) IsReviewed(gitea common.GiteaReviewFetcher) bool {
common_reviwers := rs.config.Reviewers
is_reviewed := false
for _, pr := range rs.prs {
r, err := FetchGiteaReviews(gitea, common_reviwers, pr.pr.Base.Repo.Owner.UserName, pr.pr.Base.Repo.Name, pr.pr.Index)
if err != nil {
return false
}
is_reviewed = r.IsReviewed()
if !is_reviewed {
return false
}
}
return is_reviewed
}
func (rs *PRSet) Merge() error {
prjgit, err := rs.GetPrjGitPR()
if err != nil {
return err
}
gh:=common.GitHandlerGeneratorImpl{}
git, err := gh.CreateGitHandler(GitAuthor, GitEmail, prjgit.Base.Name)
if err != nil {
return err
}
git.GitExecOrPanic("", "clone", "--depth", "1", prjgit.Base.Repo.SSHURL, common.DefaultGitPrj)
git.GitExecOrPanic(common.DefaultGitPrj, "fetch", common.DefaultGitPrj, "origin", prjgit.Base.Sha, prjgit.Head.Sha)
// if other changes merged, check if we have conflicts
rev := git.GitExecWithOutputOrPanic(common.DefaultGitPrj, "rev-list", "-1", "HEAD")
if rev != prjgit.Base.Sha {
panic("FIXME")
}
msg := "haha"
git.GitExecOrPanic(common.DefaultGitPrj, "merge", "--no-ff", "-m", msg, prjgit.Head.Sha)
git.GitExecOrPanic(common.DefaultGitPrj, "push", "origin")
return nil
}