GetFile: Use "ref" in-query if posible (#491)
based on https://github.com/go-gitea/gitea/pull/14563 Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/491 Reviewed-by: techknowlogick <techknowlogick@gitea.io> Reviewed-by: Andrew Thornton <art27@cantab.net> Co-authored-by: 6543 <6543@obermui.de> Co-committed-by: 6543 <6543@obermui.de>
This commit is contained in:
parent
757f8bdb90
commit
32b0722f98
2 changed files with 57 additions and 13 deletions
|
@ -9,6 +9,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -115,32 +116,49 @@ type FileDeleteResponse struct {
|
||||||
Verification *PayloadCommitVerification `json:"verification"`
|
Verification *PayloadCommitVerification `json:"verification"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pathEscapeSegments escapes segments of a path while not escaping forward slash
|
||||||
|
func pathEscapeSegments(path string) string {
|
||||||
|
slice := strings.Split(path, "/")
|
||||||
|
for index := range slice {
|
||||||
|
slice[index] = url.PathEscape(slice[index])
|
||||||
|
}
|
||||||
|
escapedPath := strings.Join(slice, "/")
|
||||||
|
return escapedPath
|
||||||
|
}
|
||||||
|
|
||||||
// GetFile downloads a file of repository, ref can be branch/tag/commit.
|
// GetFile downloads a file of repository, ref can be branch/tag/commit.
|
||||||
// e.g.: ref -> master, tree -> macaron.go(no leading slash)
|
// e.g.: ref -> master, filepath -> README.md (no leading slash)
|
||||||
func (c *Client) GetFile(user, repo, ref, tree string) ([]byte, *Response, error) {
|
func (c *Client) GetFile(owner, repo, ref, filepath string) ([]byte, *Response, error) {
|
||||||
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", user, repo, ref, tree), nil, nil)
|
filepath = pathEscapeSegments(filepath)
|
||||||
|
if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil {
|
||||||
|
return c.getResponse("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)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetContents get the metadata and contents of a file in a repository
|
// GetContents get the metadata and contents of a file in a repository
|
||||||
// ref is optional
|
// ref is optional
|
||||||
func (c *Client) GetContents(owner, repo, ref, filepath string) (*ContentsResponse, *Response, error) {
|
func (c *Client) GetContents(owner, repo, ref, filepath string) (*ContentsResponse, *Response, error) {
|
||||||
|
filepath = pathEscapeSegments(filepath)
|
||||||
cr := new(ContentsResponse)
|
cr := new(ContentsResponse)
|
||||||
filepath = strings.TrimPrefix(filepath, "/")
|
filepath = strings.TrimPrefix(filepath, "/")
|
||||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, ref), jsonHeader, nil, cr)
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), jsonHeader, nil, cr)
|
||||||
return cr, resp, err
|
return cr, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListContents gets a list of entries in a dir
|
// ListContents gets a list of entries in a dir
|
||||||
// ref is optional
|
// ref is optional
|
||||||
func (c *Client) ListContents(owner, repo, ref, filepath string) ([]*ContentsResponse, *Response, error) {
|
func (c *Client) ListContents(owner, repo, ref, filepath string) ([]*ContentsResponse, *Response, error) {
|
||||||
|
filepath = pathEscapeSegments(filepath)
|
||||||
cr := make([]*ContentsResponse, 0)
|
cr := make([]*ContentsResponse, 0)
|
||||||
filepath = strings.TrimPrefix(filepath, "/")
|
filepath = strings.TrimPrefix(filepath, "/")
|
||||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, ref), jsonHeader, nil, &cr)
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), jsonHeader, nil, &cr)
|
||||||
return cr, resp, err
|
return cr, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateFile create a file in a repository
|
// CreateFile create a file in a repository
|
||||||
func (c *Client) CreateFile(owner, repo, filepath string, opt CreateFileOptions) (*FileResponse, *Response, error) {
|
func (c *Client) CreateFile(owner, repo, filepath string, opt CreateFileOptions) (*FileResponse, *Response, error) {
|
||||||
|
filepath = pathEscapeSegments(filepath)
|
||||||
var err error
|
var err error
|
||||||
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
|
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -157,6 +175,7 @@ func (c *Client) CreateFile(owner, repo, filepath string, opt CreateFileOptions)
|
||||||
|
|
||||||
// UpdateFile update a file in a repository
|
// UpdateFile update a file in a repository
|
||||||
func (c *Client) UpdateFile(owner, repo, filepath string, opt UpdateFileOptions) (*FileResponse, *Response, error) {
|
func (c *Client) UpdateFile(owner, repo, filepath string, opt UpdateFileOptions) (*FileResponse, *Response, error) {
|
||||||
|
filepath = pathEscapeSegments(filepath)
|
||||||
var err error
|
var err error
|
||||||
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
|
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -173,6 +192,7 @@ func (c *Client) UpdateFile(owner, repo, filepath string, opt UpdateFileOptions)
|
||||||
|
|
||||||
// DeleteFile delete a file from repository
|
// DeleteFile delete a file from repository
|
||||||
func (c *Client) DeleteFile(owner, repo, filepath string, opt DeleteFileOptions) (*Response, error) {
|
func (c *Client) DeleteFile(owner, repo, filepath string, opt DeleteFileOptions) (*Response, error) {
|
||||||
|
filepath = pathEscapeSegments(filepath)
|
||||||
var err error
|
var err error
|
||||||
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
|
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package gitea
|
package gitea
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"log"
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -24,17 +25,18 @@ func TestFileCreateUpdateGet(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, "IyBDaGFuZ2VGaWxlcwoKQSB0ZXN0IFJlcG86IENoYW5nZUZpbGVz", base64.StdEncoding.EncodeToString(raw))
|
assert.EqualValues(t, "IyBDaGFuZ2VGaWxlcwoKQSB0ZXN0IFJlcG86IENoYW5nZUZpbGVz", base64.StdEncoding.EncodeToString(raw))
|
||||||
|
|
||||||
newFile, _, err := c.CreateFile(repo.Owner.UserName, repo.Name, "A", CreateFileOptions{
|
testFileName := "A+#&ä"
|
||||||
|
newFile, _, err := c.CreateFile(repo.Owner.UserName, repo.Name, testFileName, CreateFileOptions{
|
||||||
FileOptions: FileOptions{
|
FileOptions: FileOptions{
|
||||||
Message: "create file A",
|
Message: "create file " + testFileName,
|
||||||
},
|
},
|
||||||
Content: "ZmlsZUEK",
|
Content: "ZmlsZUEK",
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
raw, _, _ = c.GetFile(repo.Owner.UserName, repo.Name, "master", "A")
|
raw, _, _ = c.GetFile(repo.Owner.UserName, repo.Name, "master", testFileName)
|
||||||
assert.EqualValues(t, "ZmlsZUEK", base64.StdEncoding.EncodeToString(raw))
|
assert.EqualValues(t, "ZmlsZUEK", base64.StdEncoding.EncodeToString(raw))
|
||||||
|
|
||||||
updatedFile, _, err := c.UpdateFile(repo.Owner.UserName, repo.Name, "A", UpdateFileOptions{
|
updatedFile, _, err := c.UpdateFile(repo.Owner.UserName, repo.Name, testFileName, UpdateFileOptions{
|
||||||
FileOptions: FileOptions{
|
FileOptions: FileOptions{
|
||||||
Message: "add a new line",
|
Message: "add a new line",
|
||||||
},
|
},
|
||||||
|
@ -44,18 +46,40 @@ func TestFileCreateUpdateGet(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, updatedFile)
|
assert.NotNil(t, updatedFile)
|
||||||
|
|
||||||
file, _, err := c.GetContents(repo.Owner.UserName, repo.Name, "master", "A")
|
file, _, err := c.GetContents(repo.Owner.UserName, repo.Name, "master", testFileName)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, updatedFile.Content.SHA, file.SHA)
|
assert.EqualValues(t, updatedFile.Content.SHA, file.SHA)
|
||||||
assert.EqualValues(t, &updatedFile.Content.Content, &file.Content)
|
assert.EqualValues(t, &updatedFile.Content.Content, &file.Content)
|
||||||
|
|
||||||
_, err = c.DeleteFile(repo.Owner.UserName, repo.Name, "A", DeleteFileOptions{
|
_, err = c.DeleteFile(repo.Owner.UserName, repo.Name, testFileName, DeleteFileOptions{
|
||||||
FileOptions: FileOptions{
|
FileOptions: FileOptions{
|
||||||
Message: "Delete File A",
|
Message: "Delete File " + testFileName,
|
||||||
},
|
},
|
||||||
SHA: updatedFile.Content.SHA,
|
SHA: updatedFile.Content.SHA,
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
_, _, err = c.GetFile(repo.Owner.UserName, repo.Name, "master", "A")
|
_, resp, err := c.GetFile(repo.Owner.UserName, repo.Name, "master", testFileName)
|
||||||
assert.EqualValues(t, "404 Not Found", err.Error())
|
assert.EqualValues(t, "404 Not Found", err.Error())
|
||||||
|
assert.EqualValues(t, 404, resp.StatusCode)
|
||||||
|
|
||||||
|
licence, _, err := c.GetContents(repo.Owner.UserName, repo.Name, "", "LICENSE")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
licenceRaw, _, err := c.GetFile(repo.Owner.UserName, repo.Name, "", "LICENSE")
|
||||||
|
testContent := "Tk9USElORyBJUyBIRVJFIEFOWU1PUkUKSUYgWU9VIExJS0UgVE8gRklORCBTT01FVEhJTkcKV0FJVCBGT1IgVEhFIEZVVFVSRQo="
|
||||||
|
updatedFile, _, err = c.UpdateFile(repo.Owner.UserName, repo.Name, "LICENSE", UpdateFileOptions{
|
||||||
|
FileOptions: FileOptions{
|
||||||
|
Message: "Overwrite",
|
||||||
|
BranchName: "master",
|
||||||
|
NewBranchName: "overwrite-a+/&licence",
|
||||||
|
},
|
||||||
|
SHA: licence.SHA,
|
||||||
|
Content: testContent,
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, updatedFile)
|
||||||
|
licenceRawNew, _, err := c.GetFile(repo.Owner.UserName, repo.Name, "overwrite-a+/&licence", "LICENSE")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, licence)
|
||||||
|
assert.False(t, bytes.Equal(licenceRaw, licenceRawNew))
|
||||||
|
assert.EqualValues(t, testContent, base64.StdEncoding.EncodeToString(licenceRawNew))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue