diff --git a/gitea/client.go b/gitea/client.go index 785f7bf..b8c610b 100644 --- a/gitea/client.go +++ b/gitea/client.go @@ -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() diff --git a/gitea/repo_file.go b/gitea/repo_file.go index 6f99ea0..bcba705 100644 --- a/gitea/repo_file.go +++ b/gitea/repo_file.go @@ -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 diff --git a/gitea/repo_file_test.go b/gitea/repo_file_test.go index 9e606d6..32c0137 100644 --- a/gitea/repo_file_test.go +++ b/gitea/repo_file_test.go @@ -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") diff --git a/gitea/settings_test.go b/gitea/settings_test.go index e75d401..e025464 100644 --- a/gitea/settings_test.go +++ b/gitea/settings_test.go @@ -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) }