From 7edde482875504b49769ad097eab7c572547ff21 Mon Sep 17 00:00:00 2001 From: huydx Date: Fri, 2 Dec 2016 12:29:50 +0900 Subject: [PATCH] Add PullRequests.GetRaw to download raw content of pull request. Closes #481. Updates #6. --- github/github.go | 18 ++++++++++++++ github/pulls.go | 27 +++++++++++++++++++++ github/pulls_test.go | 56 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) diff --git a/github/github.go b/github/github.go index d4f5069..3d7421f 100644 --- a/github/github.go +++ b/github/github.go @@ -42,6 +42,8 @@ const ( mediaTypeV3 = "application/vnd.github.v3+json" defaultMediaType = "application/octet-stream" mediaTypeV3SHA = "application/vnd.github.v3.sha" + mediaTypeV3Diff = "application/vnd.github.v3.diff" + mediaTypeV3Patch = "application/vnd.github.v3.patch" mediaTypeOrgPermissionRepo = "application/vnd.github.v3.repository+json" // Media Type values to access preview APIs @@ -154,6 +156,22 @@ type UploadOptions struct { Name string `url:"name,omitempty"` } +// RawType represents type of raw format of a request instead of JSON. +type RawType uint8 + +const ( + // Diff format. + Diff RawType = 1 + iota + // Patch format. + Patch +) + +// RawOptions specifies parameters when user wants to get raw format of +// a response instead of JSON. +type RawOptions struct { + Type RawType +} + // addOptions adds the parameters in opt as URL query parameters to s. opt // must be a struct whose fields may contain "url" tags. func addOptions(s string, opt interface{}) (string, error) { diff --git a/github/pulls.go b/github/pulls.go index 85e04f8..9fb65a7 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -6,6 +6,7 @@ package github import ( + "bytes" "fmt" "time" ) @@ -134,6 +135,32 @@ func (s *PullRequestsService) Get(owner string, repo string, number int) (*PullR return pull, resp, err } +// GetRaw gets raw (diff or patch) format of a pull request. +func (s *PullRequestsService) GetRaw(owner string, repo string, number int, opt RawOptions) (string, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return "", nil, err + } + + switch opt.Type { + case Diff: + req.Header.Set("Accept", mediaTypeV3Diff) + case Patch: + req.Header.Set("Accept", mediaTypeV3Patch) + default: + return "", nil, fmt.Errorf("unsupported raw type %d", opt.Type) + } + + ret := new(bytes.Buffer) + resp, err := s.client.Do(req, ret) + if err != nil { + return "", resp, err + } + + return ret.String(), resp, err +} + // NewPullRequest represents a new pull request to be created. type NewPullRequest struct { Title *string `json:"title,omitempty"` diff --git a/github/pulls_test.go b/github/pulls_test.go index 31d41e1..3eccd35 100644 --- a/github/pulls_test.go +++ b/github/pulls_test.go @@ -10,6 +10,7 @@ import ( "fmt" "net/http" "reflect" + "strings" "testing" ) @@ -67,6 +68,61 @@ func TestPullRequestsService_Get(t *testing.T) { } } +func TestPullRequestService_GetRawDiff(t *testing.T) { + setup() + defer teardown() + const rawStr = "@@diff content" + + mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeV3Diff) + fmt.Fprint(w, rawStr) + }) + + ret, _, err := client.PullRequests.GetRaw("o", "r", 1, RawOptions{Diff}) + if err != nil { + t.Fatalf("PullRequests.GetRaw returned error: %v", err) + } + + if ret != rawStr { + t.Errorf("PullRequests.GetRaw returned %s want %s", ret, rawStr) + } +} + +func TestPullRequestService_GetRawPatch(t *testing.T) { + setup() + defer teardown() + const rawStr = "@@patch content" + + mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeV3Patch) + fmt.Fprint(w, rawStr) + }) + + ret, _, err := client.PullRequests.GetRaw("o", "r", 1, RawOptions{Patch}) + if err != nil { + t.Fatalf("PullRequests.GetRaw returned error: %v", err) + } + + if ret != rawStr { + t.Errorf("PullRequests.GetRaw returned %s want %s", ret, rawStr) + } +} + +func TestPullRequestService_GetRawInvalid(t *testing.T) { + setup() + defer teardown() + + _, _, err := client.PullRequests.GetRaw("o", "r", 1, RawOptions{100}) + if err == nil { + t.Fatal("PullRequests.GetRaw should return error") + } + if !strings.Contains(err.Error(), "unsupported raw type") { + t.Error("PullRequests.GetRaw should return unsupported raw type error") + } +} + func TestPullRequestsService_Get_headAndBase(t *testing.T) { setup() defer teardown()