Skip to content

Add support for gh pr merge - #873

Merged
probablycorey merged 19 commits into
masterfrom
the-merge-dubai
May 12, 2020
Merged

probablycorey merged 19 commits into
masterfrom
the-merge-dubai

Conversation

@probablycorey

@probablycorey probablycorey commented May 6, 2020 •

Copy link
Copy Markdown
Contributor

This adds the gh pr merge command and it works like this.

gh pr merge merges the current PR
gh pr merge 54 merges PR #54

It has three mutually exclusive flags --rebase, --merge, and --squash. The default flag is --merge

Here is what it looks like:

CleanShot 2020-05-06 at 11 24 03@2x

CleanShot 2020-05-06 at 11 24 21@2x

What will be in follow up PRs

  1. Making gh pr merge [number | url] interactive if there are no flags
  2. Investigate how much work it is to follow the merge rules setup for a branch

Part 1 of closing #373

@probablycorey
probablycorey requested review from mislav and vilmibm May 6, 2020 18:26
@probablycorey probablycorey self-assigned this May 6, 2020
Comment thread command/pr_test.go
Comment on lines +960 to +965
initWithStubs("master",
stubResponse{200, bytes.NewBufferString(`{ "data": { "repository": {
"pullRequest": { "number": 1, "closed": false, "state": "OPEN"}
} } }`)},
stubResponse{200, bytes.NewBufferString(`{"id": "THE-ID"}`)},
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering what people think about this. Creating the blank context and the fake http instance seemed like it was getting very repetitive in tests with not much added benefit. Are helpers like this helpful?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it's getting really repetitive, especially because we are forced to copy-paste JSON response stubs for API calls that are not even being exercised in the current test. I think that initWithStubs, but not that we might be moving away from sequential stubs to those that match specific requests based on their contents #874 which means we might need access to additional apis other than just http.StubResponse

Comment thread command/pr.go Outdated
}

var prMergeCmd = &cobra.Command{
Use: "merge [number | url] [--rebase | --merge | --squash]",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure how to document the idea of a mutually exclusive optional variable.
[{number | url}] seems like it might be correct, but [number | url] is easier to read and still seems unambiguous to me. It's hard to tell from command line docs what the correct syntax is.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 1st argument is the same as the optional argument to view and checkout, right? So it would be

[{<number> | <url> | <branch>}]

what follows are flags that are optional & mutually exclusive:

[{--rebase | --merge | --squash}]

however, if all this is getting unwieldy, I don't think we strictly need to document these flags in command synopsis line. Users will read about the available flags in the FLAGS section.

Comment thread command/pr.go Outdated
Comment thread command/pr.go Outdated
}

var prMergeCmd = &cobra.Command{
Use: "merge [number | url] [--rebase | --merge | --squash]",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 1st argument is the same as the optional argument to view and checkout, right? So it would be

[{<number> | <url> | <branch>}]

what follows are flags that are optional & mutually exclusive:

[{--rebase | --merge | --squash}]

however, if all this is getting unwieldy, I don't think we strictly need to document these flags in command synopsis line. Users will read about the available flags in the FLAGS section.

Comment thread command/pr.go
Comment thread command/pr.go Outdated
Comment thread command/pr.go Outdated
Comment thread command/pr.go Outdated
Comment thread command/pr_test.go
Comment on lines +960 to +965
initWithStubs("master",
stubResponse{200, bytes.NewBufferString(`{ "data": { "repository": {
"pullRequest": { "number": 1, "closed": false, "state": "OPEN"}
} } }`)},
stubResponse{200, bytes.NewBufferString(`{"id": "THE-ID"}`)},
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it's getting really repetitive, especially because we are forced to copy-paste JSON response stubs for API calls that are not even being exercised in the current test. I think that initWithStubs, but not that we might be moving away from sequential stubs to those that match specific requests based on their contents #874 which means we might need access to additional apis other than just http.StubResponse

Comment thread api/queries_pr.go Outdated

func merge(client *Client, repo ghrepo.Interface, pr *PullRequest, mergeMethod githubv4.PullRequestMergeMethod) error {
var mutation struct {
ReopenPullRequest struct {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: copy-pasta

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little scary that everything worked fine with that error!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, well, you can name your struct fields anything you like, and the GraphQL library will either request a field/connection/mutation based on that field name or based on the graphql:"..." struct tag. Since this field has a tag graphql:"mergePullRequest(input: $input)", the mutation that is requested is always mergePullRequest and technically your overall query is correct regardless of the struct field name you choose.

Comment thread command/pr.go Outdated
@probablycorey

Copy link
Copy Markdown
Contributor Author

This should be good to go now.

@mislav mislav left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Thank you

Comment thread command/pr.go Outdated
}

var prMergeCmd = &cobra.Command{
Use: "merge [{<number> | <url>}] [<flags>]",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. PR commands generally also accept <branch> value as alternative to <number> and <url>, so it should be listed here for consistency
  2. Should we ever note [<flags>] explicitly? It used to be added automatically for us by Cobra output for any command that supports flags, but not anymore it seems due to Help output for individual commands is broken #883

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we don't need to add flag to the usage string. I'll add branch and get rid of flag.

Comment thread api/queries_pr.go Outdated
return merge(client, repo, pr, githubv4.PullRequestMergeMethodRebase)
}

func PullRequestSquash(client *Client, repo ghrepo.Interface, pr *PullRequest) error {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having a separate method for each of the merge options, could we pass a constant as an argument to a single method called e.g. PullRequestMerge()? We'd define 3 constants in the api package and then inside the method we would translate them to appropriate githubv4 constants. This is the approach @vilmibm took in pr review and I dig it!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally tried something like this but ended up having lots of type conversion issues. I'll try this switch statement idea

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhh... this worked great. Thanks for the example link.

@probablycorey

Copy link
Copy Markdown
Contributor Author

This is ready to go. But I'm going to hold off on merging it until after we release on monday

@probablycorey
probablycorey merged commit ad3a590 into master May 12, 2020
@TomasVotruba

TomasVotruba commented May 27, 2020 •

Copy link
Copy Markdown

I missed this for so long! Thank you for adding it 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants