207 lines
6.0 KiB
Go
207 lines
6.0 KiB
Go
package pull
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"code.gitea.io/gitea/models/db"
|
|
issues_model "code.gitea.io/gitea/models/issues"
|
|
webhook_model "code.gitea.io/gitea/models/webhook"
|
|
"code.gitea.io/gitea/modules/git"
|
|
"code.gitea.io/gitea/modules/graceful"
|
|
"code.gitea.io/gitea/modules/log"
|
|
"code.gitea.io/gitea/modules/queue"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
"code.gitea.io/gitea/services/gitdiff"
|
|
hat_issues_model "code.gitlink.org.cn/Gitlink/gitea_hat.git/models/issues"
|
|
hat_pull_model "code.gitlink.org.cn/Gitlink/gitea_hat.git/models/pull"
|
|
hat_webhook_model "code.gitlink.org.cn/Gitlink/gitea_hat.git/models/webhook"
|
|
)
|
|
|
|
var hatPrPatchCheckerQueue queue.UniqueQueue
|
|
|
|
func AddToTaskQueue(pr *issues_model.PullRequest, action string) {
|
|
if action == "opened" || action == "synchronized" {
|
|
err := hatPrPatchCheckerQueue.PushFunc(strconv.FormatInt(pr.ID, 10), func() error {
|
|
return nil
|
|
})
|
|
if err != nil && err != queue.ErrAlreadyInQueue {
|
|
log.Error("Error adding prID %d to the test pull requests queue: %v", pr.ID, err)
|
|
}
|
|
} else {
|
|
log.Error("action type is not found rule.")
|
|
}
|
|
|
|
}
|
|
|
|
// InitializePullRequests checks and tests untested patches of pull requests.
|
|
func InitializePullRequests(ctx context.Context) {
|
|
prs, err := hat_issues_model.GetPullRequestIDsByIssueUpdatedUnix()
|
|
if err != nil {
|
|
log.Error("Find Checking PRs: %v", err)
|
|
return
|
|
}
|
|
for _, prID := range prs {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
default:
|
|
if err := hatPrPatchCheckerQueue.PushFunc(strconv.FormatInt(prID, 10), func() error {
|
|
log.Trace("Adding PR ID: %d to the pull requests patch hat checking queue", prID)
|
|
return nil
|
|
}); err != nil {
|
|
log.Error("Error adding prID: %s to the pull requests patch hat checking queue %v", prID, err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func InitializeCheckHook(ctx context.Context) {
|
|
w := webhook_model.Webhook{
|
|
RepoID: 0,
|
|
OrgID: 0,
|
|
IsSystemWebhook: true,
|
|
URL: fmt.Sprintf("%sapi/hat/create_pr_version", setting.AppURL),
|
|
HTTPMethod: "POST",
|
|
}
|
|
_, err := hat_webhook_model.GetWebhook(&hat_webhook_model.Webhook{
|
|
Webhook: w,
|
|
})
|
|
if err != nil {
|
|
log.Error("Find System Hook: %v", err)
|
|
if webhook_model.IsErrWebhookNotExist(err) {
|
|
w.HookEvent = &webhook_model.HookEvent{
|
|
ChooseEvents: true,
|
|
HookEvents: webhook_model.HookEvents{
|
|
PullRequestSync: true,
|
|
PullRequest: true,
|
|
},
|
|
BranchFilter: "*",
|
|
}
|
|
w.ContentType = webhook_model.ContentTypeJSON
|
|
w.IsActive = true
|
|
w.Type = "gitea"
|
|
|
|
err = w.UpdateEvent()
|
|
if err != nil {
|
|
log.Error("Update System Hook Event: %v", err)
|
|
}
|
|
err = webhook_model.CreateWebhook(ctx, &w)
|
|
if err != nil {
|
|
log.Error("Create System Hook: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func handle(data ...queue.Data) []queue.Data {
|
|
for _, datum := range data {
|
|
id, _ := strconv.ParseInt(datum.(string), 10, 64)
|
|
pr, err := issues_model.GetPullRequestByID(db.DefaultContext, id)
|
|
if err != nil {
|
|
log.Error("GetPullRequestByID[%s]: %v", datum, err)
|
|
continue
|
|
} else if pr.HasMerged {
|
|
continue
|
|
}
|
|
|
|
err = pr.LoadIssue()
|
|
if err != nil {
|
|
log.Error("pullrequest load issue error: %v", err)
|
|
continue
|
|
}
|
|
|
|
err = pr.LoadBaseRepo()
|
|
if err != nil {
|
|
log.Error("pullrequest load base repo error: %v", err)
|
|
continue
|
|
}
|
|
|
|
err = pr.LoadHeadRepo()
|
|
if err != nil {
|
|
log.Error("pullrequest load head repo error: %v", err)
|
|
continue
|
|
}
|
|
|
|
baseGitRepo, err := git.OpenRepository(db.DefaultContext, pr.BaseRepo.RepoPath())
|
|
if err != nil {
|
|
log.Error("git.OpenRepository err:%v", err)
|
|
continue
|
|
}
|
|
defer baseGitRepo.Close()
|
|
|
|
commit, err := baseGitRepo.GetCommit(pr.GetGitRefName())
|
|
if err != nil {
|
|
log.Error("GetCommit err:%v", err)
|
|
continue
|
|
}
|
|
|
|
hpr := &hat_issues_model.PullRequest{PullRequest: *pr}
|
|
err = hpr.LoadLatestPullRequestVersion(db.DefaultContext)
|
|
if err != nil && !issues_model.IsErrPullRequestNotExist(err) {
|
|
log.Error("pullrequest load version error: %v", err)
|
|
continue
|
|
}
|
|
if hpr.LatestPullRequestVersion == nil {
|
|
betweenCommitsCount, err := baseGitRepo.CommitsCountBetween(pr.MergeBase, commit.ID.String())
|
|
if err != nil {
|
|
log.Error("CommitsBeforeUntil err: %v", err)
|
|
continue
|
|
}
|
|
diffs, err := gitdiff.GetDiff(baseGitRepo, &gitdiff.DiffOptions{
|
|
BeforeCommitID: pr.MergeBase,
|
|
AfterCommitID: commit.ID.String(),
|
|
})
|
|
if err != nil {
|
|
log.Error("GetDiff err: %v", err)
|
|
continue
|
|
}
|
|
err = hat_pull_model.NewPullRequestVersion(db.DefaultContext, pr.HeadRepo, pr, diffs.TotalAddition, int(betweenCommitsCount), diffs.TotalDeletion, diffs.NumFiles, commit.ID.String(), pr.MergeBase, pr.MergeBase)
|
|
if err != nil {
|
|
log.Error("models.NewPullRequestVersion err: %v", err)
|
|
continue
|
|
}
|
|
} else {
|
|
if commit.ID.String() == hpr.LatestPullRequestVersion.HeadCommitID {
|
|
log.Error("This pull version is saved.")
|
|
continue
|
|
}
|
|
betweenCommitsCount, err := baseGitRepo.CommitsCountBetween(hpr.LatestPullRequestVersion.HeadCommitID, commit.ID.String())
|
|
if err != nil {
|
|
log.Error("CommitsBeforeUntil err: %v", err)
|
|
continue
|
|
}
|
|
diffs, err := gitdiff.GetDiff(baseGitRepo, &gitdiff.DiffOptions{
|
|
BeforeCommitID: hpr.LatestPullRequestVersion.HeadCommitID,
|
|
AfterCommitID: commit.ID.String(),
|
|
})
|
|
if err != nil {
|
|
log.Error("GetDiff err: %v", err)
|
|
continue
|
|
}
|
|
err = hat_pull_model.NewPullRequestVersion(db.DefaultContext, pr.HeadRepo, pr, diffs.TotalAddition, int(betweenCommitsCount), diffs.TotalDeletion, diffs.NumFiles, commit.ID.String(), pr.MergeBase, hpr.LatestPullRequestVersion.HeadCommitID)
|
|
if err != nil {
|
|
log.Error("models.NewPullRequestVersion err: %v", err)
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func Init() error {
|
|
hatPrPatchCheckerQueue = queue.CreateUniqueQueue("hat_pr_patch_checker", handle, "")
|
|
if hatPrPatchCheckerQueue == nil {
|
|
return fmt.Errorf("Unable to create hat_pr_patch_checker Queue")
|
|
}
|
|
|
|
go graceful.GetManager().RunWithShutdownFns(hatPrPatchCheckerQueue.Run)
|
|
go graceful.GetManager().RunWithShutdownContext(InitializePullRequests)
|
|
go graceful.GetManager().RunWithShutdownContext(InitializeCheckHook)
|
|
|
|
return nil
|
|
}
|