func CalculatePrCherryPick()

in backend/plugins/refdiff/tasks/refs_pr_cherry_pick_calculator.go [41:189]


func CalculatePrCherryPick(taskCtx plugin.SubTaskContext) errors.Error {
	data := taskCtx.GetData().(*RefdiffTaskData)
	repoId := data.Options.RepoId
	ctx := taskCtx.GetContext()
	db := taskCtx.GetDal()

	if data.Options.ProjectName != "" {
		return nil
	}
	var prTitleRegex *regexp.Regexp
	var err error
	prTitlePattern := taskCtx.GetConfig("GITHUB_PR_TITLE_PATTERN")
	if len(prTitlePattern) > 0 {
		prTitleRegex, err = regexp.Compile(prTitlePattern)
		if err != nil {
			return errors.Default.Wrap(err, "regexp Compile prTitlePattern failed")
		}
	}

	cursor, err := db.Cursor(
		dal.From(&code.PullRequest{}),
		dal.Join("left join repos on pull_requests.base_repo_id = repos.id"),
		dal.Where("repos.id = ?", repoId),
	)
	if err != nil {
		return errors.Convert(err)
	}

	defer cursor.Close()

	var parentPrKeyInt int
	taskCtx.SetProgress(0, -1)

	// iterate all rows
	for cursor.Next() {
		select {
		case <-ctx.Done():
			return errors.Convert(ctx.Err())
		default:
		}
		pr := &code.PullRequest{}
		err = db.Fetch(cursor, pr)
		if err != nil {
			return errors.Convert(err)
		}

		parentPrKey := ""
		if prTitleRegex != nil {
			groups := prTitleRegex.FindStringSubmatch(pr.Title)
			if len(groups) > 1 {
				parentPrKey = groups[1]
			}
		}

		if parentPrKeyInt, err = strconv.Atoi(parentPrKey); err != nil {
			continue
		}

		var parentPrId string
		err = db.Pluck("id", &parentPrId,
			dal.Where("pull_request_key = ? and base_repo_id = ?", parentPrKeyInt, repoId),
			dal.From("pull_requests"),
		)
		if err != nil {
			return errors.Convert(err)
		}
		if len(parentPrId) == 0 {
			continue
		}
		pr.ParentPrId = parentPrId

		err = db.Update(pr)
		if err != nil {
			return errors.Convert(err)
		}
		taskCtx.IncProgress(1)
	}

	cursor2, err := db.Cursor(
		dal.Select(`
			pr2.pull_request_key                 AS parent_pr_key,
			pr1.parent_pr_id                     AS parent_pr_id,
			pr1.base_ref                         AS cherrypick_base_branch,
			pr1.pull_request_key                 AS cherrypick_pr_key,
			repos.NAME                           AS repo_name,
			Concat(repos.url, '/pull/', pr2.pull_request_key) AS parent_pr_url,
			pr2.created_date
		`),
		dal.From(`pull_requests pr1`),
		dal.Join(`LEFT JOIN pull_requests pr2 ON pr1.parent_pr_id = pr2.id`),
		dal.Join(`LEFT JOIN repos ON pr2.base_repo_id = repos.id`),

		dal.Where("pr1.parent_pr_id != ''"),
		dal.Orderby(`
			pr1.parent_pr_id,
			pr2.created_date,
			pr1.base_ref ASC
		`),
	)
	if err != nil {
		return errors.Convert(err)
	}
	defer cursor2.Close()

	var refsPrCherryPick *code.RefsPrCherrypick
	var lastParentPrId string
	var lastCreatedDate time.Time
	var cherrypickBaseBranches []string
	var cherrypickPrKeys []string
	for cursor2.Next() {
		var item cherryPick
		err = db.Fetch(cursor2, &item)
		if err != nil {
			return errors.Convert(err)
		}
		if item.ParentPrId == lastParentPrId && item.CreatedDate == lastCreatedDate {
			cherrypickBaseBranches = append(cherrypickBaseBranches, item.CherrypickBaseBranch)
			cherrypickPrKeys = append(cherrypickPrKeys, strconv.Itoa(item.CherrypickPrKey))
		} else {
			if refsPrCherryPick != nil {
				refsPrCherryPick.CherrypickBaseBranches = strings.Join(cherrypickBaseBranches, ",")
				refsPrCherryPick.CherrypickPrKeys = strings.Join(cherrypickPrKeys, ",")
				err = db.CreateOrUpdate(refsPrCherryPick)
				if err != nil {
					return errors.Convert(err)
				}
			}
			lastParentPrId = item.ParentPrId
			lastCreatedDate = item.CreatedDate
			cherrypickBaseBranches = []string{item.CherrypickBaseBranch}
			cherrypickPrKeys = []string{strconv.Itoa(item.CherrypickPrKey)}
			refsPrCherryPick = &code.RefsPrCherrypick{
				RepoName:    item.RepoName,
				ParentPrKey: item.ParentPrKey,
				ParentPrUrl: item.ParentPrUrl,
				ParentPrId:  item.ParentPrId,
			}
		}
	}

	if refsPrCherryPick != nil {
		err = db.CreateOrUpdate(refsPrCherryPick)
		if err != nil {
			return errors.Convert(err)
		}
	}

	return nil
}