From 100c5a9eee44e927c8fba90312f48c2d33bf81be Mon Sep 17 00:00:00 2001 From: harryzcy Date: Fri, 26 Jul 2024 19:21:48 +0000 Subject: [PATCH] Support auto detecting branch for PRs (#525) Fix #524 Co-authored-by: harryzcy Co-authored-by: techknowlogick Reviewed-on: https://gitea.com/gitea/tea/pulls/525 Co-authored-by: harryzcy Co-committed-by: harryzcy --- cmd/pulls/merge.go | 17 ++---- modules/interact/pull_merge.go | 102 +++++++++++++++++++++++++++++++++ modules/task/pull_merge.go | 24 ++++++++ 3 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 modules/interact/pull_merge.go create mode 100644 modules/task/pull_merge.go diff --git a/cmd/pulls/merge.go b/cmd/pulls/merge.go index ecd84f0..9530b10 100644 --- a/cmd/pulls/merge.go +++ b/cmd/pulls/merge.go @@ -4,11 +4,11 @@ package pulls import ( - "fmt" - "code.gitea.io/sdk/gitea" "code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/modules/context" + "code.gitea.io/tea/modules/interact" + "code.gitea.io/tea/modules/task" "code.gitea.io/tea/modules/utils" "github.com/urfave/cli/v2" @@ -44,7 +44,8 @@ var CmdPullsMerge = cli.Command{ ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) if ctx.Args().Len() != 1 { - return fmt.Errorf("Must specify a PR index") + // If no PR index is provided, try interactive mode + return interact.MergePull(ctx) } idx, err := utils.ArgToIndex(ctx.Args().First()) @@ -52,18 +53,10 @@ var CmdPullsMerge = cli.Command{ return err } - success, _, err := ctx.Login.Client().MergePullRequest(ctx.Owner, ctx.Repo, idx, gitea.MergePullRequestOption{ + return task.PullMerge(ctx.Login, ctx.Owner, ctx.Repo, idx, gitea.MergePullRequestOption{ Style: gitea.MergeStyle(ctx.String("style")), Title: ctx.String("title"), Message: ctx.String("message"), }) - - if err != nil { - return err - } - if !success { - return fmt.Errorf("Failed to merge PR. Is it still open?") - } - return nil }, } diff --git a/modules/interact/pull_merge.go b/modules/interact/pull_merge.go new file mode 100644 index 0000000..c994274 --- /dev/null +++ b/modules/interact/pull_merge.go @@ -0,0 +1,102 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package interact + +import ( + "fmt" + "strings" + + "code.gitea.io/sdk/gitea" + "code.gitea.io/tea/modules/context" + "code.gitea.io/tea/modules/task" + "code.gitea.io/tea/modules/utils" + + "github.com/AlecAivazis/survey/v2" +) + +// MergePull interactively creates a PR +func MergePull(ctx *context.TeaContext) error { + if ctx.LocalRepo == nil { + return fmt.Errorf("Must specify a PR index") + } + + branch, _, err := ctx.LocalRepo.TeaGetCurrentBranchNameAndSHA() + if err != nil { + return err + } + + idx, err := getPullIndex(ctx, branch) + if err != nil { + return err + } + + return task.PullMerge(ctx.Login, ctx.Owner, ctx.Repo, idx, gitea.MergePullRequestOption{ + Style: gitea.MergeStyle(ctx.String("style")), + Title: ctx.String("title"), + Message: ctx.String("message"), + }) +} + +// getPullIndex interactively determines the PR index +func getPullIndex(ctx *context.TeaContext, branch string) (int64, error) { + c := ctx.Login.Client() + opts := gitea.ListPullRequestsOptions{ + State: gitea.StateOpen, + ListOptions: ctx.GetListOptions(), + } + selected := "" + loadMoreOption := "PR not found? Load more PRs..." + + // paginated fetch + var prs []*gitea.PullRequest + var err error + for { + prs, _, err = c.ListRepoPullRequests(ctx.Owner, ctx.Repo, opts) + if len(prs) == 0 { + return 0, fmt.Errorf("No open PRs found") + } + opts.ListOptions.Page++ + prOptions := make([]string, 0) + + // get the PR indexes where head branch is the current branch + for _, pr := range prs { + if pr.Head.Ref == branch { + prOptions = append(prOptions, fmt.Sprintf("#%d: %s", pr.Index, pr.Title)) + } + } + + // then get the PR indexes where base branch is the current branch + for _, pr := range prs { + // don't add the same PR twice, so `pr.Head.Ref != branch` + if pr.Base.Ref == branch && pr.Head.Ref != branch { + prOptions = append(prOptions, fmt.Sprintf("#%d: %s", pr.Index, pr.Title)) + } + } + + prOptions = append(prOptions, loadMoreOption) + + q := &survey.Select{ + Message: "Select a PR to merge", + Options: prOptions, + PageSize: 10, + } + err = survey.AskOne(q, &selected) + if err != nil { + return 0, err + } + if selected != loadMoreOption { + break + } + } + + // get the index from the selected option + before, _, _ := strings.Cut(selected, ":") + before = strings.TrimPrefix(before, "#") + idx, err := utils.ArgToIndex(before) + if err != nil { + return 0, err + } + + return idx, nil +} diff --git a/modules/task/pull_merge.go b/modules/task/pull_merge.go new file mode 100644 index 0000000..8a2018a --- /dev/null +++ b/modules/task/pull_merge.go @@ -0,0 +1,24 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package task + +import ( + "fmt" + + "code.gitea.io/sdk/gitea" + "code.gitea.io/tea/modules/config" +) + +// PullMerge merges a PR +func PullMerge(login *config.Login, repoOwner, repoName string, index int64, opt gitea.MergePullRequestOption) error { + client := login.Client() + success, _, err := client.MergePullRequest(repoOwner, repoName, index, opt) + if err != nil { + return err + } + if !success { + return fmt.Errorf("Failed to merge PR. Is it still open?") + } + return nil +}