From fa53bea7f7fb8aaec896461ddf157feeda67192a Mon Sep 17 00:00:00 2001 From: Ali Date: Wed, 22 Jan 2014 15:44:38 -0800 Subject: [PATCH] Add support for getting repository README files. --- github/repos_contents.go | 62 +++++++++++++++++++++++++++++++++++ github/repos_contents_test.go | 55 +++++++++++++++++++++++++++++++ github/strings_test.go | 7 ++-- 3 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 github/repos_contents.go create mode 100644 github/repos_contents_test.go diff --git a/github/repos_contents.go b/github/repos_contents.go new file mode 100644 index 0000000..671587c --- /dev/null +++ b/github/repos_contents.go @@ -0,0 +1,62 @@ +// Copyright 2013 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Repository contents API methods. +// http://developer.github.com/v3/repos/contents/ + +package github + +import ( + "encoding/base64" + "errors" + "fmt" +) + +// RepositoryContent represents a file or directory in a github repository. +type RepositoryContent struct { + Type *string `json:"type,omitempty"` + Encoding *string `json:"encoding,omitempty"` + Size *int `json:"size,omitempty"` + Name *string `json:"name,omitempty"` + Path *string `json:"path,omitempty"` + Content *string `json:"content,omitempty"` + SHA *string `json:"sha,omitempty"` + URL *string `json:"url,omitempty"` + GitURL *string `json:"giturl,omitempty"` + HTMLURL *string `json:"htmlurl,omitempty"` +} + +func (r RepositoryContent) String() string { + return Stringify(r) +} + +// Decode decodes the file content if it is base64 encoded. +func (c *RepositoryContent) Decode() ([]byte, error) { + if *c.Encoding != "base64" { + return nil, errors.New("Cannot decode non-base64") + } + o, err := base64.StdEncoding.DecodeString(*c.Content) + if err != nil { + return nil, err + } + return o, nil +} + +// GetReadme gets the Readme file for the repository. +// +// GitHub API docs: http://developer.github.com/v3/repos/contents/#get-the-readme +func (s *RepositoriesService) GetReadme(owner, repo string) (*RepositoryContent, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/readme", owner, repo) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + readme := new(RepositoryContent) + resp, err := s.client.Do(req, readme) + if err != nil { + return nil, resp, err + } + return readme, resp, err +} diff --git a/github/repos_contents_test.go b/github/repos_contents_test.go new file mode 100644 index 0000000..22f4fd9 --- /dev/null +++ b/github/repos_contents_test.go @@ -0,0 +1,55 @@ +package github + +import ( + "fmt" + "net/http" + "reflect" + "testing" +) + +func TestRepositoriesService_GetReadme(t *testing.T) { + setup() + defer teardown() + mux.HandleFunc("/repos/o/r/readme", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{ + "type": "file", + "encoding": "base64", + "size": 5362, + "name": "README.md", + "path": "README.md" + }`) + }) + readme, _, err := client.Repositories.GetReadme("o", "r") + if err != nil { + t.Errorf("Repositories.GetReadme returned error: %v", err) + } + want := &RepositoryContent{Type: String("file"), Name: String("README.md"), Size: Int(5362), Encoding: String("base64"), Path: String("README.md")} + if !reflect.DeepEqual(readme, want) { + t.Errorf("Repositories.GetReadme returned %+v, want %+v", readme, want) + } +} + +func TestDecodeBadEncoding(t *testing.T) { + setup() + defer teardown() + r := RepositoryContent{Encoding: String("bad")} + _, err := r.Decode() + if err == nil { + t.Errorf("Should fail to decode non-base64") + } +} + +func TestDecode(t *testing.T) { + setup() + defer teardown() + r := RepositoryContent{Encoding: String("base64"), Content: String("aGVsbG8=")} + o, err := r.Decode() + if err != nil { + t.Errorf("Failed to decode content.") + } + want := "hello" + if string(o) != want { + t.Errorf("RepositoryContent.Decode returned %+v, want %+v", string(o), want) + } +} diff --git a/github/strings_test.go b/github/strings_test.go index 91c1963..a393eb6 100644 --- a/github/strings_test.go +++ b/github/strings_test.go @@ -99,8 +99,8 @@ func TestString(t *testing.T) { {GistComment{ID: Int(1)}, `github.GistComment{ID:1}`}, {GistFile{Size: Int(1)}, `github.GistFile{Size:1}`}, {Gist{ID: String("1")}, `github.Gist{ID:"1", Files:map[]}`}, - {Gitignore{Name: String("n")}, `github.Gitignore{Name:"n"}`}, {GitObject{SHA: String("s")}, `github.GitObject{SHA:"s"}`}, + {Gitignore{Name: String("n")}, `github.Gitignore{Name:"n"}`}, {Hook{ID: Int(1)}, `github.Hook{Config:map[], ID:1}`}, {IssueComment{ID: Int(1)}, `github.IssueComment{ID:1}`}, {Issue{Number: Int(1)}, `github.Issue{Number:1}`}, @@ -112,9 +112,12 @@ func TestString(t *testing.T) { {PushEventCommit{SHA: String("s")}, `github.PushEventCommit{SHA:"s"}`}, {PushEvent{PushID: Int(1)}, `github.PushEvent{PushID:1}`}, {Reference{Ref: String("r")}, `github.Reference{Ref:"r"}`}, + {ReleaseAsset{ID: Int(1)}, `github.ReleaseAsset{ID:1}`}, {RepoStatus{ID: Int(1)}, `github.RepoStatus{ID:1}`}, {RepositoryComment{ID: Int(1)}, `github.RepositoryComment{ID:1}`}, {RepositoryCommit{SHA: String("s")}, `github.RepositoryCommit{SHA:"s"}`}, + {RepositoryContent{Name: String("n")}, `github.RepositoryContent{Name:"n"}`}, + {RepositoryRelease{ID: Int(1)}, `github.RepositoryRelease{ID:1}`}, {Repository{ID: Int(1)}, `github.Repository{ID:1}`}, {Team{ID: Int(1)}, `github.Team{ID:1}`}, {TreeEntry{SHA: String("s")}, `github.TreeEntry{SHA:"s"}`}, @@ -123,8 +126,6 @@ func TestString(t *testing.T) { {WebHookAuthor{Name: String("n")}, `github.WebHookAuthor{Name:"n"}`}, {WebHookCommit{ID: String("1")}, `github.WebHookCommit{ID:"1"}`}, {WebHookPayload{Ref: String("r")}, `github.WebHookPayload{Ref:"r"}`}, - {RepositoryRelease{ID: Int(1)}, `github.RepositoryRelease{ID:1}`}, - {ReleaseAsset{ID: Int(1)}, `github.ReleaseAsset{ID:1}`}, } for i, tt := range tests {