From c9d6108f1456ea668b9543a40e63a0e88175e0e5 Mon Sep 17 00:00:00 2001 From: Michael Tiller Date: Tue, 28 Apr 2015 16:43:18 -0400 Subject: [PATCH] This adds an additional method to RepositoriesService to download a file --- github/repos_contents.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/github/repos_contents.go b/github/repos_contents.go index 0d0e4d9..80776f2 100644 --- a/github/repos_contents.go +++ b/github/repos_contents.go @@ -13,8 +13,10 @@ import ( "encoding/json" "errors" "fmt" + "io" "net/http" "net/url" + "path" ) // RepositoryContent represents a file or directory in a github repository. @@ -91,6 +93,32 @@ func (s *RepositoriesService) GetReadme(owner, repo string, opt *RepositoryConte return readme, resp, err } +// DownloadContents returns an io.ReadCloser that reads the contents of the +// specified file. This function will work with files of any size, as opposed +// to GetContents which is limited to 1 Mb files. It is the caller's +// responsibility to close the ReadCloser. +func (s *RepositoriesService) DownloadContents(owner, repo, filepath string, opt *RepositoryContentGetOptions) (io.ReadCloser, error) { + dir := path.Dir(filepath) + filename := path.Base(filepath) + _, dirContents, _, err := s.GetContents(owner, repo, dir, opt) + if err != nil { + return nil, err + } + for _, contents := range dirContents { + if *contents.Name == filename { + if contents.DownloadURL == nil || *contents.DownloadURL == "" { + return nil, fmt.Errorf("No download link found for %s", filepath) + } + resp, err := s.client.client.Get(*contents.DownloadURL) + if err != nil { + return nil, err + } + return resp.Body, nil + } + } + return nil, fmt.Errorf("No file named %s found in %s", filename, dir) +} + // GetContents can return either the metadata and content of a single file // (when path references a file) or the metadata of all the files and/or // subdirectories of a directory (when path references a directory). To make it