Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pulls: Support updating base branch #528

Merged
merged 5 commits into from
Feb 1, 2017
Merged

pulls: Support updating base branch #528

merged 5 commits into from
Feb 1, 2017

Conversation

abhinav
Copy link
Contributor

@abhinav abhinav commented Jan 22, 2017

This adds support for changing the base branch of a PR.

As per the discussion in #421, the PullRequest is converted into an
unexported type pullRequestUpdate which matches the shape expected by the
pulls PATCH endpoint.

Resolves issue #421.

This adds support for changing the base branch of a PR.

As per the discussion in #421, the `PullRequest` is converted into an
unexported type `pullRequestUpdate` which matches the shape expected by the
pulls PATCH endpoint.

Issue: #421
Copy link
Member

@dmitshur dmitshur left a comment

Choose a reason for hiding this comment

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

Thanks for making this PR @abhinav, this looks really good. I think we need to improve documentation, then this can be merged. See other comments about an optional enhancement to the tests.

State *string `json:"state,omitempty"`
Base *string `json:"base,omitempty"`
}

// Edit a pull request.
//
// GitHub API docs: https://developer.github.com/v3/pulls/#update-a-pull-request
Copy link
Member

Choose a reason for hiding this comment

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

I think we should document which fields we currently support. It's not obvious that passing github.&PullRequest{Base: &github.PullRequestBranch{Ref: "belong-to-us"}, out out of all other fields inside PullRequest struct, will update the base.

Something like:

// Edit a pull request.
//
// Fields that can be edited are: Title, Body, State, Base.Ref to edit base branch.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed. Added docs for this.

input *PullRequest
sendResponse string

wantUpdate *pullRequestUpdate
Copy link
Member

Choose a reason for hiding this comment

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

This is optional, but I think it'd be better if you made the type of wantUpdate a string and have it contain the expected JSON.

There's no need to decode the update JSON into our own struct that we used for encoding, and compare those.

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was concerned that the order in which the struct fields would
be serialized is not deterministic but that doesn't appear to be
the case upon trial. Updated.

Copy link
Member

@dmitshur dmitshur Jan 28, 2017

Choose a reason for hiding this comment

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

I see.

Yeah, encoding/json encoder uses the order of fields in a struct when encoding, so it is deterministic. It even sorts map keys, so everything's always deterministic.

{
input: &PullRequest{Title: String("t")},
sendResponse: `{"number":1}`,
wantUpdate: &pullRequestUpdate{Title: String("t")},
Copy link
Member

Choose a reason for hiding this comment

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

Then, the value for wantUpdate here would be something like {"title":"t"}.

It's easier to reason about it being correct, since GitHub API deals with JSON input and we can compare its documentation with this.

Copy link
Member

@dmitshur dmitshur left a comment

Choose a reason for hiding this comment

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

LGTM. Thank you!

See line comment for another simplification opportunity.

gotUpdate, _ := ioutil.ReadAll(r.Body)
wantUpdate := tt.wantUpdate + "\n" // json encoder adds a newline
if string(gotUpdate) != wantUpdate {
t.Errorf("Request body = %q, want %q", gotUpdate, wantUpdate)
}
Copy link
Member

Choose a reason for hiding this comment

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

You can use testBody helper to simplify this.

See

testBody(t, r, test.wantBody+"\n")
for example.

for _, tt := range tests {
func() {
setup()
defer teardown()
Copy link
Member

@dmitshur dmitshur Jan 28, 2017

Choose a reason for hiding this comment

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

In fact, you can use the idea from TestPullRequestsService_Merge_options to remove the need for the nested closure with per-testcase setup()/defer teardown(). The idea there is to use i as the pull request ID, so that registered routes don't overlap.

It also tests that the handler gets called (instead of not being called).

See

// Test that different merge options produce expected PUT requests. See issue https://github.com/google/go-github/issues/500.
func TestPullRequestsService_Merge_options(t *testing.T) {
setup()
defer teardown()
tests := []struct {
options *PullRequestOptions
wantBody string
}{
{
options: nil,
wantBody: `{"commit_message":"merging pull request"}`,
},
{
options: &PullRequestOptions{},
wantBody: `{"commit_message":"merging pull request"}`,
},
{
options: &PullRequestOptions{MergeMethod: "rebase"},
wantBody: `{"commit_message":"merging pull request","merge_method":"rebase"}`,
},
{
options: &PullRequestOptions{SHA: "6dcb09b5b57875f334f61aebed695e2e4193db5e"},
wantBody: `{"commit_message":"merging pull request","sha":"6dcb09b5b57875f334f61aebed695e2e4193db5e"}`,
},
{
options: &PullRequestOptions{
CommitTitle: "Extra detail",
SHA: "6dcb09b5b57875f334f61aebed695e2e4193db5e",
MergeMethod: "squash",
},
wantBody: `{"commit_message":"merging pull request","commit_title":"Extra detail","merge_method":"squash","sha":"6dcb09b5b57875f334f61aebed695e2e4193db5e"}`,
},
}
for i, test := range tests {
madeRequest := false
mux.HandleFunc(fmt.Sprintf("/repos/o/r/pulls/%d/merge", i), func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
testHeader(t, r, "Accept", mediaTypeSquashPreview)
testBody(t, r, test.wantBody+"\n")
madeRequest = true
})
_, _, _ = client.PullRequests.Merge("o", "r", i, "merging pull request", test.options)
if !madeRequest {
t.Errorf("%d: PullRequests.Merge(%#v): expected request was not made", i, test.options)
}
}
}
.

Optional, if you're interested in doing this.

Also test whether the request was acually made.
Copy link
Member

@dmitshur dmitshur left a comment

Choose a reason for hiding this comment

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

Looks great, thanks for doing this!

LGTM.

Copy link
Collaborator

@gmlewis gmlewis left a comment

Choose a reason for hiding this comment

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

LGTM (apart from a tiny nit).
Thank you @abhinav and @shurcooL!

v := new(PullRequest)
json.NewDecoder(r.Body).Decode(v)
wantUpdate string
wantResponse *PullRequest
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: I find wantResponse a bit confusing here... what if we just called it want ?
Either way is fine, though... your call.

@dmitshur dmitshur self-assigned this Feb 1, 2017
@dmitshur dmitshur merged commit 1d8328d into google:master Feb 1, 2017
@abhinav abhinav deleted the pull-request-update-base branch February 8, 2017 07:20
bubg-dev pushed a commit to bubg-dev/go-github that referenced this pull request Jun 16, 2017
As per the discussion in google#421, the PullRequest parameter is converted into
an unexported type pullRequestUpdate which matches the shape expected by
the pulls PATCH endpoint.

Resolves google#421.
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