Add latest commit's SHA to content response (#20398)
* Add latest commit's SHA to content response - When requesting the contents of a filepath, add the latest commit's SHA to the requested file. - Resolves #12840 * Add swagger * Fix NPE * Fix tests * Hook into LastCommitCache * Move AddLastCommitCache to a common nogogit and gogit file Signed-off-by: Andrew Thornton <art27@cantab.net> * Prevent NPE Co-authored-by: Andrew Thornton <art27@cantab.net> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
parent
2b94b02f33
commit
692707f145
12 changed files with 187 additions and 131 deletions
|
@ -50,7 +50,7 @@ func getCreateFileOptions() api.CreateFileOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExpectedFileResponseForCreate(repoFullName, commitID, treePath string) *api.FileResponse {
|
func getExpectedFileResponseForCreate(repoFullName, commitID, treePath, latestCommitSHA string) *api.FileResponse {
|
||||||
sha := "a635aa942442ddfdba07468cf9661c08fbdf0ebf"
|
sha := "a635aa942442ddfdba07468cf9661c08fbdf0ebf"
|
||||||
encoding := "base64"
|
encoding := "base64"
|
||||||
content := "VGhpcyBpcyBuZXcgdGV4dA=="
|
content := "VGhpcyBpcyBuZXcgdGV4dA=="
|
||||||
|
@ -60,17 +60,18 @@ func getExpectedFileResponseForCreate(repoFullName, commitID, treePath string) *
|
||||||
downloadURL := setting.AppURL + repoFullName + "/raw/branch/master/" + treePath
|
downloadURL := setting.AppURL + repoFullName + "/raw/branch/master/" + treePath
|
||||||
return &api.FileResponse{
|
return &api.FileResponse{
|
||||||
Content: &api.ContentsResponse{
|
Content: &api.ContentsResponse{
|
||||||
Name: filepath.Base(treePath),
|
Name: filepath.Base(treePath),
|
||||||
Path: treePath,
|
Path: treePath,
|
||||||
SHA: sha,
|
SHA: sha,
|
||||||
Size: 16,
|
LastCommitSHA: latestCommitSHA,
|
||||||
Type: "file",
|
Size: 16,
|
||||||
Encoding: &encoding,
|
Type: "file",
|
||||||
Content: &content,
|
Encoding: &encoding,
|
||||||
URL: &selfURL,
|
Content: &content,
|
||||||
HTMLURL: &htmlURL,
|
URL: &selfURL,
|
||||||
GitURL: &gitURL,
|
HTMLURL: &htmlURL,
|
||||||
DownloadURL: &downloadURL,
|
GitURL: &gitURL,
|
||||||
|
DownloadURL: &downloadURL,
|
||||||
Links: &api.FileLinksResponse{
|
Links: &api.FileLinksResponse{
|
||||||
Self: &selfURL,
|
Self: &selfURL,
|
||||||
GitURL: &gitURL,
|
GitURL: &gitURL,
|
||||||
|
@ -170,7 +171,8 @@ func TestAPICreateFile(t *testing.T) {
|
||||||
resp := session.MakeRequest(t, req, http.StatusCreated)
|
resp := session.MakeRequest(t, req, http.StatusCreated)
|
||||||
gitRepo, _ := git.OpenRepository(stdCtx.Background(), repo1.RepoPath())
|
gitRepo, _ := git.OpenRepository(stdCtx.Background(), repo1.RepoPath())
|
||||||
commitID, _ := gitRepo.GetBranchCommitID(createFileOptions.NewBranchName)
|
commitID, _ := gitRepo.GetBranchCommitID(createFileOptions.NewBranchName)
|
||||||
expectedFileResponse := getExpectedFileResponseForCreate("user2/repo1", commitID, treePath)
|
latestCommit, _ := gitRepo.GetCommitByPath(treePath)
|
||||||
|
expectedFileResponse := getExpectedFileResponseForCreate("user2/repo1", commitID, treePath, latestCommit.ID.String())
|
||||||
var fileResponse api.FileResponse
|
var fileResponse api.FileResponse
|
||||||
DecodeJSON(t, resp, &fileResponse)
|
DecodeJSON(t, resp, &fileResponse)
|
||||||
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
||||||
|
@ -289,7 +291,8 @@ func TestAPICreateFile(t *testing.T) {
|
||||||
emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "empty-repo"}).(*repo_model.Repository) // public repo
|
emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "empty-repo"}).(*repo_model.Repository) // public repo
|
||||||
gitRepo, _ := git.OpenRepository(stdCtx.Background(), emptyRepo.RepoPath())
|
gitRepo, _ := git.OpenRepository(stdCtx.Background(), emptyRepo.RepoPath())
|
||||||
commitID, _ := gitRepo.GetBranchCommitID(createFileOptions.NewBranchName)
|
commitID, _ := gitRepo.GetBranchCommitID(createFileOptions.NewBranchName)
|
||||||
expectedFileResponse := getExpectedFileResponseForCreate("user2/empty-repo", commitID, treePath)
|
latestCommit, _ := gitRepo.GetCommitByPath(treePath)
|
||||||
|
expectedFileResponse := getExpectedFileResponseForCreate("user2/empty-repo", commitID, treePath, latestCommit.ID.String())
|
||||||
DecodeJSON(t, resp, &fileResponse)
|
DecodeJSON(t, resp, &fileResponse)
|
||||||
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
||||||
assert.EqualValues(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA)
|
assert.EqualValues(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA)
|
||||||
|
|
|
@ -48,7 +48,7 @@ func getUpdateFileOptions() *api.UpdateFileOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExpectedFileResponseForUpdate(commitID, treePath string) *api.FileResponse {
|
func getExpectedFileResponseForUpdate(commitID, treePath, lastCommitSHA string) *api.FileResponse {
|
||||||
sha := "08bd14b2e2852529157324de9c226b3364e76136"
|
sha := "08bd14b2e2852529157324de9c226b3364e76136"
|
||||||
encoding := "base64"
|
encoding := "base64"
|
||||||
content := "VGhpcyBpcyB1cGRhdGVkIHRleHQ="
|
content := "VGhpcyBpcyB1cGRhdGVkIHRleHQ="
|
||||||
|
@ -58,17 +58,18 @@ func getExpectedFileResponseForUpdate(commitID, treePath string) *api.FileRespon
|
||||||
downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath
|
downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath
|
||||||
return &api.FileResponse{
|
return &api.FileResponse{
|
||||||
Content: &api.ContentsResponse{
|
Content: &api.ContentsResponse{
|
||||||
Name: filepath.Base(treePath),
|
Name: filepath.Base(treePath),
|
||||||
Path: treePath,
|
Path: treePath,
|
||||||
SHA: sha,
|
SHA: sha,
|
||||||
Type: "file",
|
LastCommitSHA: lastCommitSHA,
|
||||||
Size: 20,
|
Type: "file",
|
||||||
Encoding: &encoding,
|
Size: 20,
|
||||||
Content: &content,
|
Encoding: &encoding,
|
||||||
URL: &selfURL,
|
Content: &content,
|
||||||
HTMLURL: &htmlURL,
|
URL: &selfURL,
|
||||||
GitURL: &gitURL,
|
HTMLURL: &htmlURL,
|
||||||
DownloadURL: &downloadURL,
|
GitURL: &gitURL,
|
||||||
|
DownloadURL: &downloadURL,
|
||||||
Links: &api.FileLinksResponse{
|
Links: &api.FileLinksResponse{
|
||||||
Self: &selfURL,
|
Self: &selfURL,
|
||||||
GitURL: &gitURL,
|
GitURL: &gitURL,
|
||||||
|
@ -137,7 +138,8 @@ func TestAPIUpdateFile(t *testing.T) {
|
||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
gitRepo, _ := git.OpenRepository(stdCtx.Background(), repo1.RepoPath())
|
gitRepo, _ := git.OpenRepository(stdCtx.Background(), repo1.RepoPath())
|
||||||
commitID, _ := gitRepo.GetBranchCommitID(updateFileOptions.NewBranchName)
|
commitID, _ := gitRepo.GetBranchCommitID(updateFileOptions.NewBranchName)
|
||||||
expectedFileResponse := getExpectedFileResponseForUpdate(commitID, treePath)
|
lasCommit, _ := gitRepo.GetCommitByPath(treePath)
|
||||||
|
expectedFileResponse := getExpectedFileResponseForUpdate(commitID, treePath, lasCommit.ID.String())
|
||||||
var fileResponse api.FileResponse
|
var fileResponse api.FileResponse
|
||||||
DecodeJSON(t, resp, &fileResponse)
|
DecodeJSON(t, resp, &fileResponse)
|
||||||
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getExpectedContentsListResponseForContents(ref, refType string) []*api.ContentsResponse {
|
func getExpectedContentsListResponseForContents(ref, refType, lastCommitSHA string) []*api.ContentsResponse {
|
||||||
treePath := "README.md"
|
treePath := "README.md"
|
||||||
sha := "4b4851ad51df6a7d9f25c979345979eaeb5b349f"
|
sha := "4b4851ad51df6a7d9f25c979345979eaeb5b349f"
|
||||||
selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath + "?ref=" + ref
|
selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath + "?ref=" + ref
|
||||||
|
@ -30,15 +30,16 @@ func getExpectedContentsListResponseForContents(ref, refType string) []*api.Cont
|
||||||
downloadURL := setting.AppURL + "user2/repo1/raw/" + refType + "/" + ref + "/" + treePath
|
downloadURL := setting.AppURL + "user2/repo1/raw/" + refType + "/" + ref + "/" + treePath
|
||||||
return []*api.ContentsResponse{
|
return []*api.ContentsResponse{
|
||||||
{
|
{
|
||||||
Name: filepath.Base(treePath),
|
Name: filepath.Base(treePath),
|
||||||
Path: treePath,
|
Path: treePath,
|
||||||
SHA: sha,
|
SHA: sha,
|
||||||
Type: "file",
|
LastCommitSHA: lastCommitSHA,
|
||||||
Size: 30,
|
Type: "file",
|
||||||
URL: &selfURL,
|
Size: 30,
|
||||||
HTMLURL: &htmlURL,
|
URL: &selfURL,
|
||||||
GitURL: &gitURL,
|
HTMLURL: &htmlURL,
|
||||||
DownloadURL: &downloadURL,
|
GitURL: &gitURL,
|
||||||
|
DownloadURL: &downloadURL,
|
||||||
Links: &api.FileLinksResponse{
|
Links: &api.FileLinksResponse{
|
||||||
Self: &selfURL,
|
Self: &selfURL,
|
||||||
GitURL: &gitURL,
|
GitURL: &gitURL,
|
||||||
|
@ -94,7 +95,9 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) {
|
||||||
var contentsListResponse []*api.ContentsResponse
|
var contentsListResponse []*api.ContentsResponse
|
||||||
DecodeJSON(t, resp, &contentsListResponse)
|
DecodeJSON(t, resp, &contentsListResponse)
|
||||||
assert.NotNil(t, contentsListResponse)
|
assert.NotNil(t, contentsListResponse)
|
||||||
expectedContentsListResponse := getExpectedContentsListResponseForContents(ref, refType)
|
lastCommit, err := gitRepo.GetCommitByPath("README.md")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
expectedContentsListResponse := getExpectedContentsListResponseForContents(ref, refType, lastCommit.ID.String())
|
||||||
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
|
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
|
||||||
|
|
||||||
// No ref
|
// No ref
|
||||||
|
@ -103,17 +106,22 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) {
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &contentsListResponse)
|
DecodeJSON(t, resp, &contentsListResponse)
|
||||||
assert.NotNil(t, contentsListResponse)
|
assert.NotNil(t, contentsListResponse)
|
||||||
expectedContentsListResponse = getExpectedContentsListResponseForContents(repo1.DefaultBranch, refType)
|
|
||||||
|
expectedContentsListResponse = getExpectedContentsListResponseForContents(repo1.DefaultBranch, refType, lastCommit.ID.String())
|
||||||
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
|
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
|
||||||
|
|
||||||
// ref is the branch we created above in setup
|
// ref is the branch we created above in setup
|
||||||
ref = newBranch
|
ref = newBranch
|
||||||
refType = "branch"
|
refType = "branch"
|
||||||
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref)
|
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref)
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &contentsListResponse)
|
DecodeJSON(t, resp, &contentsListResponse)
|
||||||
assert.NotNil(t, contentsListResponse)
|
assert.NotNil(t, contentsListResponse)
|
||||||
expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType)
|
branchCommit, err := gitRepo.GetBranchCommit(ref)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
lastCommit, err = branchCommit.GetCommitByPath("README.md")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType, lastCommit.ID.String())
|
||||||
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
|
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
|
||||||
|
|
||||||
// ref is the new tag we created above in setup
|
// ref is the new tag we created above in setup
|
||||||
|
@ -123,7 +131,11 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) {
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &contentsListResponse)
|
DecodeJSON(t, resp, &contentsListResponse)
|
||||||
assert.NotNil(t, contentsListResponse)
|
assert.NotNil(t, contentsListResponse)
|
||||||
expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType)
|
tagCommit, err := gitRepo.GetTagCommit(ref)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
lastCommit, err = tagCommit.GetCommitByPath("README.md")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType, lastCommit.ID.String())
|
||||||
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
|
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
|
||||||
|
|
||||||
// ref is a commit
|
// ref is a commit
|
||||||
|
@ -133,7 +145,7 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) {
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &contentsListResponse)
|
DecodeJSON(t, resp, &contentsListResponse)
|
||||||
assert.NotNil(t, contentsListResponse)
|
assert.NotNil(t, contentsListResponse)
|
||||||
expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType)
|
expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType, commitID)
|
||||||
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
|
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
|
||||||
|
|
||||||
// Test file contents a file with a bad ref
|
// Test file contents a file with a bad ref
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getExpectedContentsResponseForContents(ref, refType string) *api.ContentsResponse {
|
func getExpectedContentsResponseForContents(ref, refType, lastCommitSHA string) *api.ContentsResponse {
|
||||||
treePath := "README.md"
|
treePath := "README.md"
|
||||||
sha := "4b4851ad51df6a7d9f25c979345979eaeb5b349f"
|
sha := "4b4851ad51df6a7d9f25c979345979eaeb5b349f"
|
||||||
encoding := "base64"
|
encoding := "base64"
|
||||||
|
@ -30,17 +30,18 @@ func getExpectedContentsResponseForContents(ref, refType string) *api.ContentsRe
|
||||||
gitURL := setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha
|
gitURL := setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha
|
||||||
downloadURL := setting.AppURL + "user2/repo1/raw/" + refType + "/" + ref + "/" + treePath
|
downloadURL := setting.AppURL + "user2/repo1/raw/" + refType + "/" + ref + "/" + treePath
|
||||||
return &api.ContentsResponse{
|
return &api.ContentsResponse{
|
||||||
Name: treePath,
|
Name: treePath,
|
||||||
Path: treePath,
|
Path: treePath,
|
||||||
SHA: sha,
|
SHA: sha,
|
||||||
Type: "file",
|
LastCommitSHA: lastCommitSHA,
|
||||||
Size: 30,
|
Type: "file",
|
||||||
Encoding: &encoding,
|
Size: 30,
|
||||||
Content: &content,
|
Encoding: &encoding,
|
||||||
URL: &selfURL,
|
Content: &content,
|
||||||
HTMLURL: &htmlURL,
|
URL: &selfURL,
|
||||||
GitURL: &gitURL,
|
HTMLURL: &htmlURL,
|
||||||
DownloadURL: &downloadURL,
|
GitURL: &gitURL,
|
||||||
|
DownloadURL: &downloadURL,
|
||||||
Links: &api.FileLinksResponse{
|
Links: &api.FileLinksResponse{
|
||||||
Self: &selfURL,
|
Self: &selfURL,
|
||||||
GitURL: &gitURL,
|
GitURL: &gitURL,
|
||||||
|
@ -96,7 +97,8 @@ func testAPIGetContents(t *testing.T, u *url.URL) {
|
||||||
var contentsResponse api.ContentsResponse
|
var contentsResponse api.ContentsResponse
|
||||||
DecodeJSON(t, resp, &contentsResponse)
|
DecodeJSON(t, resp, &contentsResponse)
|
||||||
assert.NotNil(t, contentsResponse)
|
assert.NotNil(t, contentsResponse)
|
||||||
expectedContentsResponse := getExpectedContentsResponseForContents(ref, refType)
|
lastCommit, _ := gitRepo.GetCommitByPath("README.md")
|
||||||
|
expectedContentsResponse := getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String())
|
||||||
assert.EqualValues(t, *expectedContentsResponse, contentsResponse)
|
assert.EqualValues(t, *expectedContentsResponse, contentsResponse)
|
||||||
|
|
||||||
// No ref
|
// No ref
|
||||||
|
@ -105,7 +107,7 @@ func testAPIGetContents(t *testing.T, u *url.URL) {
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &contentsResponse)
|
DecodeJSON(t, resp, &contentsResponse)
|
||||||
assert.NotNil(t, contentsResponse)
|
assert.NotNil(t, contentsResponse)
|
||||||
expectedContentsResponse = getExpectedContentsResponseForContents(repo1.DefaultBranch, refType)
|
expectedContentsResponse = getExpectedContentsResponseForContents(repo1.DefaultBranch, refType, lastCommit.ID.String())
|
||||||
assert.EqualValues(t, *expectedContentsResponse, contentsResponse)
|
assert.EqualValues(t, *expectedContentsResponse, contentsResponse)
|
||||||
|
|
||||||
// ref is the branch we created above in setup
|
// ref is the branch we created above in setup
|
||||||
|
@ -115,7 +117,9 @@ func testAPIGetContents(t *testing.T, u *url.URL) {
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &contentsResponse)
|
DecodeJSON(t, resp, &contentsResponse)
|
||||||
assert.NotNil(t, contentsResponse)
|
assert.NotNil(t, contentsResponse)
|
||||||
expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType)
|
branchCommit, _ := gitRepo.GetBranchCommit(ref)
|
||||||
|
lastCommit, _ = branchCommit.GetCommitByPath("README.md")
|
||||||
|
expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String())
|
||||||
assert.EqualValues(t, *expectedContentsResponse, contentsResponse)
|
assert.EqualValues(t, *expectedContentsResponse, contentsResponse)
|
||||||
|
|
||||||
// ref is the new tag we created above in setup
|
// ref is the new tag we created above in setup
|
||||||
|
@ -125,7 +129,9 @@ func testAPIGetContents(t *testing.T, u *url.URL) {
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &contentsResponse)
|
DecodeJSON(t, resp, &contentsResponse)
|
||||||
assert.NotNil(t, contentsResponse)
|
assert.NotNil(t, contentsResponse)
|
||||||
expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType)
|
tagCommit, _ := gitRepo.GetTagCommit(ref)
|
||||||
|
lastCommit, _ = tagCommit.GetCommitByPath("README.md")
|
||||||
|
expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String())
|
||||||
assert.EqualValues(t, *expectedContentsResponse, contentsResponse)
|
assert.EqualValues(t, *expectedContentsResponse, contentsResponse)
|
||||||
|
|
||||||
// ref is a commit
|
// ref is a commit
|
||||||
|
@ -135,7 +141,7 @@ func testAPIGetContents(t *testing.T, u *url.URL) {
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &contentsResponse)
|
DecodeJSON(t, resp, &contentsResponse)
|
||||||
assert.NotNil(t, contentsResponse)
|
assert.NotNil(t, contentsResponse)
|
||||||
expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType)
|
expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, commitID)
|
||||||
assert.EqualValues(t, *expectedContentsResponse, contentsResponse)
|
assert.EqualValues(t, *expectedContentsResponse, contentsResponse)
|
||||||
|
|
||||||
// Test file contents a file with a bad ref
|
// Test file contents a file with a bad ref
|
||||||
|
|
|
@ -47,7 +47,7 @@ func getUpdateRepoFileOptions(repo *repo_model.Repository) *files_service.Update
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExpectedFileResponseForRepofilesCreate(commitID string) *api.FileResponse {
|
func getExpectedFileResponseForRepofilesCreate(commitID, lastCommitSHA string) *api.FileResponse {
|
||||||
treePath := "new/file.txt"
|
treePath := "new/file.txt"
|
||||||
encoding := "base64"
|
encoding := "base64"
|
||||||
content := "VGhpcyBpcyBhIE5FVyBmaWxl"
|
content := "VGhpcyBpcyBhIE5FVyBmaWxl"
|
||||||
|
@ -57,17 +57,18 @@ func getExpectedFileResponseForRepofilesCreate(commitID string) *api.FileRespons
|
||||||
downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath
|
downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath
|
||||||
return &api.FileResponse{
|
return &api.FileResponse{
|
||||||
Content: &api.ContentsResponse{
|
Content: &api.ContentsResponse{
|
||||||
Name: filepath.Base(treePath),
|
Name: filepath.Base(treePath),
|
||||||
Path: treePath,
|
Path: treePath,
|
||||||
SHA: "103ff9234cefeee5ec5361d22b49fbb04d385885",
|
SHA: "103ff9234cefeee5ec5361d22b49fbb04d385885",
|
||||||
Type: "file",
|
LastCommitSHA: lastCommitSHA,
|
||||||
Size: 18,
|
Type: "file",
|
||||||
Encoding: &encoding,
|
Size: 18,
|
||||||
Content: &content,
|
Encoding: &encoding,
|
||||||
URL: &selfURL,
|
Content: &content,
|
||||||
HTMLURL: &htmlURL,
|
URL: &selfURL,
|
||||||
GitURL: &gitURL,
|
HTMLURL: &htmlURL,
|
||||||
DownloadURL: &downloadURL,
|
GitURL: &gitURL,
|
||||||
|
DownloadURL: &downloadURL,
|
||||||
Links: &api.FileLinksResponse{
|
Links: &api.FileLinksResponse{
|
||||||
Self: &selfURL,
|
Self: &selfURL,
|
||||||
GitURL: &gitURL,
|
GitURL: &gitURL,
|
||||||
|
@ -115,7 +116,7 @@ func getExpectedFileResponseForRepofilesCreate(commitID string) *api.FileRespons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExpectedFileResponseForRepofilesUpdate(commitID, filename string) *api.FileResponse {
|
func getExpectedFileResponseForRepofilesUpdate(commitID, filename, lastCommitSHA string) *api.FileResponse {
|
||||||
encoding := "base64"
|
encoding := "base64"
|
||||||
content := "VGhpcyBpcyBVUERBVEVEIGNvbnRlbnQgZm9yIHRoZSBSRUFETUUgZmlsZQ=="
|
content := "VGhpcyBpcyBVUERBVEVEIGNvbnRlbnQgZm9yIHRoZSBSRUFETUUgZmlsZQ=="
|
||||||
selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + filename + "?ref=master"
|
selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + filename + "?ref=master"
|
||||||
|
@ -124,17 +125,18 @@ func getExpectedFileResponseForRepofilesUpdate(commitID, filename string) *api.F
|
||||||
downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + filename
|
downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + filename
|
||||||
return &api.FileResponse{
|
return &api.FileResponse{
|
||||||
Content: &api.ContentsResponse{
|
Content: &api.ContentsResponse{
|
||||||
Name: filename,
|
Name: filename,
|
||||||
Path: filename,
|
Path: filename,
|
||||||
SHA: "dbf8d00e022e05b7e5cf7e535de857de57925647",
|
SHA: "dbf8d00e022e05b7e5cf7e535de857de57925647",
|
||||||
Type: "file",
|
LastCommitSHA: lastCommitSHA,
|
||||||
Size: 43,
|
Type: "file",
|
||||||
Encoding: &encoding,
|
Size: 43,
|
||||||
Content: &content,
|
Encoding: &encoding,
|
||||||
URL: &selfURL,
|
Content: &content,
|
||||||
HTMLURL: &htmlURL,
|
URL: &selfURL,
|
||||||
GitURL: &gitURL,
|
HTMLURL: &htmlURL,
|
||||||
DownloadURL: &downloadURL,
|
GitURL: &gitURL,
|
||||||
|
DownloadURL: &downloadURL,
|
||||||
Links: &api.FileLinksResponse{
|
Links: &api.FileLinksResponse{
|
||||||
Self: &selfURL,
|
Self: &selfURL,
|
||||||
GitURL: &gitURL,
|
GitURL: &gitURL,
|
||||||
|
@ -206,7 +208,8 @@ func TestCreateOrUpdateRepoFileForCreate(t *testing.T) {
|
||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
|
|
||||||
commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch)
|
commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch)
|
||||||
expectedFileResponse := getExpectedFileResponseForRepofilesCreate(commitID)
|
lastCommit, _ := gitRepo.GetCommitByPath("new/file.txt")
|
||||||
|
expectedFileResponse := getExpectedFileResponseForRepofilesCreate(commitID, lastCommit.ID.String())
|
||||||
assert.NotNil(t, expectedFileResponse)
|
assert.NotNil(t, expectedFileResponse)
|
||||||
if expectedFileResponse != nil {
|
if expectedFileResponse != nil {
|
||||||
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
||||||
|
@ -241,8 +244,9 @@ func TestCreateOrUpdateRepoFileForUpdate(t *testing.T) {
|
||||||
gitRepo, _ := git.OpenRepository(git.DefaultContext, repo.RepoPath())
|
gitRepo, _ := git.OpenRepository(git.DefaultContext, repo.RepoPath())
|
||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
|
|
||||||
commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch)
|
commit, _ := gitRepo.GetBranchCommit(opts.NewBranch)
|
||||||
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commitID, opts.TreePath)
|
lastCommit, _ := commit.GetCommitByPath(opts.TreePath)
|
||||||
|
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.TreePath, lastCommit.ID.String())
|
||||||
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
||||||
assert.EqualValues(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA)
|
assert.EqualValues(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA)
|
||||||
assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL)
|
assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL)
|
||||||
|
@ -277,7 +281,8 @@ func TestCreateOrUpdateRepoFileForUpdateWithFileMove(t *testing.T) {
|
||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
|
|
||||||
commit, _ := gitRepo.GetBranchCommit(opts.NewBranch)
|
commit, _ := gitRepo.GetBranchCommit(opts.NewBranch)
|
||||||
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.TreePath)
|
lastCommit, _ := commit.GetCommitByPath(opts.TreePath)
|
||||||
|
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.TreePath, lastCommit.ID.String())
|
||||||
// assert that the old file no longer exists in the last commit of the branch
|
// assert that the old file no longer exists in the last commit of the branch
|
||||||
fromEntry, err := commit.GetTreeEntryByPath(opts.FromTreePath)
|
fromEntry, err := commit.GetTreeEntryByPath(opts.FromTreePath)
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
|
@ -326,8 +331,9 @@ func TestCreateOrUpdateRepoFileWithoutBranchNames(t *testing.T) {
|
||||||
gitRepo, _ := git.OpenRepository(git.DefaultContext, repo.RepoPath())
|
gitRepo, _ := git.OpenRepository(git.DefaultContext, repo.RepoPath())
|
||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
|
|
||||||
commitID, _ := gitRepo.GetBranchCommitID(repo.DefaultBranch)
|
commit, _ := gitRepo.GetBranchCommit(repo.DefaultBranch)
|
||||||
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commitID, opts.TreePath)
|
lastCommit, _ := commit.GetCommitByPath(opts.TreePath)
|
||||||
|
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.TreePath, lastCommit.ID.String())
|
||||||
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/cache"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -434,3 +435,20 @@ func (repo *Repository) IsCommitInBranch(commitID, branch string) (r bool, err e
|
||||||
}
|
}
|
||||||
return len(stdout) > 0, err
|
return len(stdout) > 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *Repository) AddLastCommitCache(cacheKey, fullName, sha string) error {
|
||||||
|
if repo.LastCommitCache == nil {
|
||||||
|
commitsCount, err := cache.GetInt64(cacheKey, func() (int64, error) {
|
||||||
|
commit, err := repo.GetCommit(sha)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return commit.CommitsCount()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
repo.LastCommitCache = NewLastCommitCache(commitsCount, fullName, repo, cache.GetCache())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -87,9 +87,10 @@ type FileLinksResponse struct {
|
||||||
|
|
||||||
// ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content
|
// ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content
|
||||||
type ContentsResponse struct {
|
type ContentsResponse struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
SHA string `json:"sha"`
|
SHA string `json:"sha"`
|
||||||
|
LastCommitSHA string `json:"last_commit_sha"`
|
||||||
// `type` will be `file`, `dir`, `symlink`, or `submodule`
|
// `type` will be `file`, `dir`, `symlink`, or `submodule`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Size int64 `json:"size"`
|
Size int64 `json:"size"`
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/cache"
|
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
@ -35,19 +34,11 @@ func ResolveRefOrSha(ctx *context.APIContext, ref string) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Repo.GitRepo != nil && ctx.Repo.GitRepo.LastCommitCache == nil {
|
if ctx.Repo.GitRepo != nil {
|
||||||
commitsCount, err := cache.GetInt64(ctx.Repo.Repository.GetCommitsCountCacheKey(ref, true), func() (int64, error) {
|
err := ctx.Repo.GitRepo.AddLastCommitCache(ctx.Repo.Repository.GetCommitsCountCacheKey(ref, ref != sha), ctx.Repo.Repository.FullName(), sha)
|
||||||
commit, err := ctx.Repo.GitRepo.GetCommit(sha)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return commit.CommitsCount()
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to get commits count for %s in %s. Error: %v", sha, ctx.Repo.Repository.FullName(), err)
|
log.Error("Unable to get commits count for %s in %s. Error: %v", sha, ctx.Repo.Repository.FullName(), err)
|
||||||
return sha
|
|
||||||
}
|
}
|
||||||
ctx.Repo.GitRepo.LastCommitCache = git.NewLastCommitCache(commitsCount, ctx.Repo.Repository.FullName(), ctx.Repo.GitRepo, cache.GetCache())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sha
|
return sha
|
||||||
|
|
|
@ -165,13 +165,24 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref
|
||||||
}
|
}
|
||||||
selfURLString := selfURL.String()
|
selfURLString := selfURL.String()
|
||||||
|
|
||||||
|
err = gitRepo.AddLastCommitCache(repo.GetCommitsCountCacheKey(ref, refType != git.ObjectCommit), repo.FullName(), commitID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
lastCommit, err := commit.GetCommitByPath(treePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// All content types have these fields in populated
|
// All content types have these fields in populated
|
||||||
contentsResponse := &api.ContentsResponse{
|
contentsResponse := &api.ContentsResponse{
|
||||||
Name: entry.Name(),
|
Name: entry.Name(),
|
||||||
Path: treePath,
|
Path: treePath,
|
||||||
SHA: entry.ID.String(),
|
SHA: entry.ID.String(),
|
||||||
Size: entry.Size(),
|
LastCommitSHA: lastCommit.ID.String(),
|
||||||
URL: &selfURLString,
|
Size: entry.Size(),
|
||||||
|
URL: &selfURLString,
|
||||||
Links: &api.FileLinksResponse{
|
Links: &api.FileLinksResponse{
|
||||||
Self: &selfURLString,
|
Self: &selfURLString,
|
||||||
},
|
},
|
||||||
|
|
|
@ -33,17 +33,18 @@ func getExpectedReadmeContentsResponse() *api.ContentsResponse {
|
||||||
gitURL := "https://try.gitea.io/api/v1/repos/user2/repo1/git/blobs/" + sha
|
gitURL := "https://try.gitea.io/api/v1/repos/user2/repo1/git/blobs/" + sha
|
||||||
downloadURL := "https://try.gitea.io/user2/repo1/raw/branch/master/" + treePath
|
downloadURL := "https://try.gitea.io/user2/repo1/raw/branch/master/" + treePath
|
||||||
return &api.ContentsResponse{
|
return &api.ContentsResponse{
|
||||||
Name: treePath,
|
Name: treePath,
|
||||||
Path: treePath,
|
Path: treePath,
|
||||||
SHA: "4b4851ad51df6a7d9f25c979345979eaeb5b349f",
|
SHA: "4b4851ad51df6a7d9f25c979345979eaeb5b349f",
|
||||||
Type: "file",
|
LastCommitSHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d",
|
||||||
Size: 30,
|
Type: "file",
|
||||||
Encoding: &encoding,
|
Size: 30,
|
||||||
Content: &content,
|
Encoding: &encoding,
|
||||||
URL: &selfURL,
|
Content: &content,
|
||||||
HTMLURL: &htmlURL,
|
URL: &selfURL,
|
||||||
GitURL: &gitURL,
|
HTMLURL: &htmlURL,
|
||||||
DownloadURL: &downloadURL,
|
GitURL: &gitURL,
|
||||||
|
DownloadURL: &downloadURL,
|
||||||
Links: &api.FileLinksResponse{
|
Links: &api.FileLinksResponse{
|
||||||
Self: &selfURL,
|
Self: &selfURL,
|
||||||
GitURL: &gitURL,
|
GitURL: &gitURL,
|
||||||
|
|
|
@ -43,17 +43,18 @@ func getExpectedFileResponse() *api.FileResponse {
|
||||||
downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath
|
downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath
|
||||||
return &api.FileResponse{
|
return &api.FileResponse{
|
||||||
Content: &api.ContentsResponse{
|
Content: &api.ContentsResponse{
|
||||||
Name: treePath,
|
Name: treePath,
|
||||||
Path: treePath,
|
Path: treePath,
|
||||||
SHA: sha,
|
SHA: sha,
|
||||||
Type: "file",
|
LastCommitSHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d",
|
||||||
Size: 30,
|
Type: "file",
|
||||||
Encoding: &encoding,
|
Size: 30,
|
||||||
Content: &content,
|
Encoding: &encoding,
|
||||||
URL: &selfURL,
|
Content: &content,
|
||||||
HTMLURL: &htmlURL,
|
URL: &selfURL,
|
||||||
GitURL: &gitURL,
|
HTMLURL: &htmlURL,
|
||||||
DownloadURL: &downloadURL,
|
GitURL: &gitURL,
|
||||||
|
DownloadURL: &downloadURL,
|
||||||
Links: &api.FileLinksResponse{
|
Links: &api.FileLinksResponse{
|
||||||
Self: &selfURL,
|
Self: &selfURL,
|
||||||
GitURL: &gitURL,
|
GitURL: &gitURL,
|
||||||
|
|
|
@ -13779,6 +13779,10 @@
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "HTMLURL"
|
"x-go-name": "HTMLURL"
|
||||||
},
|
},
|
||||||
|
"last_commit_sha": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "LastCommitSHA"
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Name"
|
"x-go-name": "Name"
|
||||||
|
|
Reference in a new issue