From 2be5837cb04d016ef8e6d89eee441dfaad1ce34d Mon Sep 17 00:00:00 2001 From: Unknwon Date: Sat, 24 Oct 2015 14:48:11 -0400 Subject: [PATCH] New push to base repo of base branch: retest all corresponding patches --- models/pull.go | 89 ++++++++++++++++++++++++++++++++--------------- models/webhook.go | 9 ++++- 2 files changed, 69 insertions(+), 29 deletions(-) diff --git a/models/pull.go b/models/pull.go index d8bff01998..7436511c91 100644 --- a/models/pull.go +++ b/models/pull.go @@ -206,6 +206,12 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error return sess.Commit() } +// patchConflicts is a list of conflit description from Git. +var patchConflicts = []string{ + "patch does not apply", + "already exists in working directory", +} + // testPatch checks if patch can be merged to base repository without conflit. func (pr *PullRequest) testPatch() (err error) { if pr.BaseRepo == nil { @@ -231,12 +237,15 @@ func (pr *PullRequest) testPatch() (err error) { fmt.Sprintf("testPatch(git apply --check): %d", pr.BaseRepo.ID), "git", "apply", "--check", patchPath) if err != nil { - if strings.Contains(stderr, "patch does not apply") { - log.Trace("PullRequest[%d].testPatch(apply): has conflit", pr.ID) - pr.Status = PULL_REQUEST_STATUS_CONFLICT - } else { - return fmt.Errorf("git apply --check: %v - %s", err, stderr) + for i := range patchConflicts { + if strings.Contains(stderr, patchConflicts[i]) { + log.Trace("PullRequest[%d].testPatch(apply): has conflit", pr.ID) + pr.Status = PULL_REQUEST_STATUS_CONFLICT + return nil + } } + + return fmt.Errorf("git apply --check: %v - %s", err, stderr) } return nil } @@ -269,6 +278,7 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str return err } + pr.Index = pull.Index if err = repo.SavePatch(pr.Index, patch); err != nil { return fmt.Errorf("SavePatch: %v", err) } @@ -282,7 +292,6 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str } pr.IssueID = pull.ID - pr.Index = pull.Index if _, err = sess.Insert(pr); err != nil { return fmt.Errorf("insert pull repo: %v", err) } @@ -308,10 +317,19 @@ func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch // GetUnmergedPullRequestsByHeadInfo returnss all pull requests that are open and has not been merged // by given head information (repo and branch). -func GetUnmergedPullRequestsByHeadInfo(headRepoID int64, headBranch string) ([]*PullRequest, error) { +func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequest, error) { prs := make([]*PullRequest, 0, 2) return prs, x.Where("head_repo_id=? AND head_branch=? AND has_merged=? AND issue.is_closed=?", - headRepoID, headBranch, false, false). + repoID, branch, false, false). + Join("INNER", "issue", "issue.id=pull_request.issue_id").Find(&prs) +} + +// GetUnmergedPullRequestsByBaseInfo returnss all pull requests that are open and has not been merged +// by given base information (repo and branch). +func GetUnmergedPullRequestsByBaseInfo(repoID int64, branch string) ([]*PullRequest, error) { + prs := make([]*PullRequest, 0, 2) + return prs, x.Where("base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?", + repoID, branch, false, false). Join("INNER", "issue", "issue.id=pull_request.issue_id").Find(&prs) } @@ -371,23 +389,24 @@ func (pr *PullRequest) checkAndUpdateStatus() { } } -// AddTestPullRequestTask adds new test tasks by given head repository and head branch, -// and generate new patch for testing as needed. -func AddTestPullRequestTask(headRepoID int64, headBranch string) { - log.Trace("AddTestPullRequestTask[head_repo_id: %d, head_branch: %s]: finding pull requests", headRepoID, headBranch) - prs, err := GetUnmergedPullRequestsByHeadInfo(headRepoID, headBranch) - if err != nil { - log.Error(4, "Find pull requests[head_repo_id: %d, head_branch: %s]: %v", headRepoID, headBranch, err) - return - } +// addToTaskQueue adds itself to pull request test task queue. +func (pr *PullRequest) addToTaskQueue() { + go PullRequestQueue.AddFunc(pr.ID, func() { + pr.Status = PULL_REQUEST_STATUS_CHECKING + if err := pr.UpdateCols("status"); err != nil { + log.Error(5, "addToTaskQueue.UpdateCols[%d].(add to queue): %v", pr.ID, err) + } + }) +} +func addHeadRepoTasks(prs []*PullRequest) { for _, pr := range prs { - log.Trace("AddTestPullRequestTask[%d]: composing new test task", pr.ID) + log.Trace("addHeadRepoTasks[%d]: composing new test task", pr.ID) if err := pr.GetHeadRepo(); err != nil { log.Error(4, "GetHeadRepo[%d]: %v", pr.ID, err) continue } else if pr.HeadRepo == nil { - log.Trace("AddTestPullRequestTask[%d]: ignored cruppted data", pr.ID) + log.Trace("addHeadRepoTasks[%d]: ignored cruppted data", pr.ID) continue } @@ -420,15 +439,29 @@ func AddTestPullRequestTask(headRepoID int64, headBranch string) { continue } - if !PullRequestQueue.Exist(pr.ID) { - go func() { - PullRequestQueue.Add(pr.ID) - pr.Status = PULL_REQUEST_STATUS_CHECKING - if err = pr.UpdateCols("status"); err != nil { - log.Error(5, "AddTestPullRequestTask.UpdateCols[%d].(add to queue): %v", pr.ID, err) - } - }() - } + pr.addToTaskQueue() + } +} + +// AddTestPullRequestTask adds new test tasks by given head/base repository and head/base branch, +// and generate new patch for testing as needed. +func AddTestPullRequestTask(repoID int64, branch string) { + log.Trace("AddTestPullRequestTask[head_repo_id: %d, head_branch: %s]: finding pull requests", repoID, branch) + prs, err := GetUnmergedPullRequestsByHeadInfo(repoID, branch) + if err != nil { + log.Error(4, "Find pull requests[head_repo_id: %d, head_branch: %s]: %v", repoID, branch, err) + return + } + addHeadRepoTasks(prs) + + log.Trace("AddTestPullRequestTask[base_repo_id: %d, base_branch: %s]: finding pull requests", repoID, branch) + prs, err = GetUnmergedPullRequestsByBaseInfo(repoID, branch) + if err != nil { + log.Error(4, "Find pull requests[base_repo_id: %d, base_branch: %s]: %v", repoID, branch, err) + return + } + for _, pr := range prs { + pr.addToTaskQueue() } } diff --git a/models/webhook.go b/models/webhook.go index 7b6d7826e7..b4d7dc9c71 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -465,7 +465,7 @@ func (q *UniqueQueue) Remove(id interface{}) { delete(q.ids, com.ToStr(id)) } -func (q *UniqueQueue) Add(id interface{}) { +func (q *UniqueQueue) AddFunc(id interface{}, fn func()) { newid := com.ToStr(id) if q.Exist(id) { @@ -474,10 +474,17 @@ func (q *UniqueQueue) Add(id interface{}) { q.lock.Lock() q.ids[newid] = true + if fn != nil { + fn() + } q.lock.Unlock() q.queue <- newid } +func (q *UniqueQueue) Add(id interface{}) { + q.AddFunc(id, nil) +} + func (q *UniqueQueue) Exist(id interface{}) bool { q.lock.Lock() defer q.lock.Unlock()