Add GetFileReader() & GetFile() support git-lfs (#595)

Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/595
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: KN4CK3R <kn4ck3r@noreply.gitea.io>
This commit is contained in:
6543 2022-07-29 18:51:05 +08:00
parent de34275bb6
commit cc14c63ccc
4 changed files with 57 additions and 8 deletions

View file

@ -341,10 +341,25 @@ func statusCodeToErr(resp *Response) (body []byte, err error) {
return data, fmt.Errorf("%s: %s", resp.Status, string(data))
}
func (c *Client) getResponseReader(method, path string, header http.Header, body io.Reader) (io.ReadCloser, *Response, error) {
resp, err := c.doRequest(method, path, header, body)
if err != nil {
return nil, resp, err
}
// check for errors
data, err := statusCodeToErr(resp)
if err != nil {
return io.NopCloser(bytes.NewReader(data)), resp, err
}
return resp.Body, resp, nil
}
func (c *Client) getResponse(method, path string, header http.Header, body io.Reader) ([]byte, *Response, error) {
resp, err := c.doRequest(method, path, header, body)
if err != nil {
return nil, nil, err
return nil, resp, err
}
defer resp.Body.Close()

View file

@ -9,6 +9,8 @@ import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/url"
"strings"
)
@ -117,17 +119,46 @@ type FileDeleteResponse struct {
}
// GetFile downloads a file of repository, ref can be branch/tag/commit.
// it optional can resolve lfs pointers and server the file instead
// e.g.: ref -> master, filepath -> README.md (no leading slash)
func (c *Client) GetFile(owner, repo, ref, filepath string) ([]byte, *Response, error) {
func (c *Client) GetFile(owner, repo, ref, filepath string, resolveLFS ...bool) ([]byte, *Response, error) {
reader, resp, err := c.GetFileReader(owner, repo, ref, filepath, resolveLFS...)
if reader == nil {
return nil, resp, err
}
defer reader.Close()
data, err2 := ioutil.ReadAll(reader)
if err2 != nil {
return nil, resp, err2
}
return data, resp, err
}
// GetFileReader return reader for download a file of repository, ref can be branch/tag/commit.
// it optional can resolve lfs pointers and server the file instead
// e.g.: ref -> master, filepath -> README.md (no leading slash)
func (c *Client) GetFileReader(owner, repo, ref, filepath string, resolveLFS ...bool) (io.ReadCloser, *Response, error) {
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
return nil, nil, err
}
// resolve lfs
if len(resolveLFS) != 0 && resolveLFS[0] {
if err := c.checkServerVersionGreaterThanOrEqual(version1_17_0); err != nil {
return nil, nil, err
}
return c.getResponseReader("GET", fmt.Sprintf("/repos/%s/%s/media/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), nil, nil)
}
// normal get
filepath = pathEscapeSegments(filepath)
if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil {
ref = pathEscapeSegments(ref)
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", owner, repo, ref, filepath), nil, nil)
return c.getResponseReader("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", owner, repo, ref, filepath), nil, nil)
}
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), nil, nil)
return c.getResponseReader("GET", fmt.Sprintf("/repos/%s/%s/raw/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), nil, nil)
}
// GetContents get the metadata and contents of a file in a repository

View file

@ -60,6 +60,7 @@ func TestFileCreateUpdateGet(t *testing.T) {
assert.NoError(t, err)
_, resp, err := c.GetFile(repo.Owner.UserName, repo.Name, "main", testFileName)
assert.Error(t, err)
assert.EqualValues(t, "The target couldn't be found.", err.Error())
assert.EqualValues(t, 404, resp.StatusCode)
licence, _, err := c.GetContents(repo.Owner.UserName, repo.Name, "", "LICENSE")

View file

@ -39,10 +39,12 @@ func TestGetGlobalSettings(t *testing.T) {
attachSettings, _, err := c.GetGlobalAttachmentSettings()
assert.NoError(t, err)
if assert.NotEmpty(t, attachSettings.AllowedTypes) {
attachSettings.AllowedTypes = ""
}
assert.EqualValues(t, &GlobalAttachmentSettings{
Enabled: true,
AllowedTypes: ".docx,.gif,.gz,.jpeg,.jpg,.mp4,.log,.pdf,.png,.pptx,.txt,.xlsx,.zip",
MaxSize: 4,
MaxFiles: 5,
Enabled: true,
MaxSize: 4,
MaxFiles: 5,
}, attachSettings)
}