aboutsummaryrefslogtreecommitdiffstats
path: root/routers/api
diff options
context:
space:
mode:
authorRichard Mahn <richmahn@users.noreply.github.com>2019-02-06 11:19:26 -0700
committerzeripath <art27@cantab.net>2019-02-06 18:19:26 +0000
commitda1edbfb79566e9d31f43ee85eb2e9fc9b52695b (patch)
tree6e81098a8ddb5695b52a6a136bb24286fb8a8c9b /routers/api
parent0c840a924a9a78556dafdc3e558bdcfe3c704201 (diff)
downloadgitea-da1edbfb79566e9d31f43ee85eb2e9fc9b52695b.tar.gz
gitea-da1edbfb79566e9d31f43ee85eb2e9fc9b52695b.zip
Feature - Pagination for git tree API (#5838)
* Feature - Pagination for git tree API * Handles case when page is negative * Does a for loop over the start and end rather than all entries * Removed redundent logic * Adds per_page as a query parameter * Adds DEFAULT_GIT_TREES_PER_PAGE for settings, ran make fmt * Fix typo in cheat-sheet en * Makes page start at 1, generated swagger * Use updates to SDK * Updates to use latest sdk * Updates swagger for tree api * Adds test for GetTreeBySHA * Updates per PR reviews * Updates per PR reviews * Remove file * Formatting * Fix to swagger file * Fix to swagger * Update v1_json.tmpl * Fix to swagger file
Diffstat (limited to 'routers/api')
-rw-r--r--routers/api/v1/repo/tree.go66
-rw-r--r--routers/api/v1/repo/tree_test.go48
2 files changed, 96 insertions, 18 deletions
diff --git a/routers/api/v1/repo/tree.go b/routers/api/v1/repo/tree.go
index 7288d6caed..8a5d0c4b01 100644
--- a/routers/api/v1/repo/tree.go
+++ b/routers/api/v1/repo/tree.go
@@ -37,19 +37,34 @@ func GetTree(ctx *context.APIContext) {
// description: sha of the commit
// type: string
// required: true
+ // - name: recursive
+ // in: query
+ // description: show all directories and files
+ // required: false
+ // type: boolean
+ // - name: page
+ // in: query
+ // description: page number; the 'truncated' field in the response will be true if there are still more items after this page, false if the last page
+ // required: false
+ // type: integer
+ // - name: per_page
+ // in: query
+ // description: number of items per page; default is 1000 or what is set in app.ini as DEFAULT_GIT_TREES_PER_PAGE
+ // required: false
+ // type: integer
// responses:
// "200":
// "$ref": "#/responses/GitTreeResponse"
sha := ctx.Params("sha")
if len(sha) == 0 {
- ctx.Error(400, "sha not provided", nil)
+ ctx.Error(400, "", "sha not provided")
return
}
tree := GetTreeBySHA(ctx, sha)
if tree != nil {
ctx.JSON(200, tree)
} else {
- ctx.Error(400, "sha invalid", nil)
+ ctx.Error(400, "", "sha invalid")
}
}
@@ -87,29 +102,44 @@ func GetTreeBySHA(ctx *context.APIContext, sha string) *gitea.GitTreeResponse {
// 40 is the size of the sha1 hash in hexadecimal format.
copyPos := len(treeURL) - 40
- if len(entries) > 1000 {
- tree.Entries = make([]gitea.GitEntry, 1000)
+ page := ctx.QueryInt("page")
+ perPage := ctx.QueryInt("per_page")
+ if perPage <= 0 || perPage > setting.API.DefaultGitTreesPerPage {
+ perPage = setting.API.DefaultGitTreesPerPage
+ }
+ if page <= 0 {
+ page = 1
+ }
+ tree.Page = page
+ tree.TotalCount = len(entries)
+ rangeStart := perPage * (page - 1)
+ if rangeStart >= len(entries) {
+ return tree
+ }
+ var rangeEnd int
+ if len(entries) > perPage {
+ tree.Truncated = true
+ }
+ if rangeStart+perPage < len(entries) {
+ rangeEnd = rangeStart + perPage
} else {
- tree.Entries = make([]gitea.GitEntry, len(entries))
+ rangeEnd = len(entries)
}
- for e := range entries {
- if e > 1000 {
- tree.Truncated = true
- break
- }
-
- tree.Entries[e].Path = entries[e].Name()
- tree.Entries[e].Mode = fmt.Sprintf("%06x", entries[e].Mode())
- tree.Entries[e].Type = string(entries[e].Type)
- tree.Entries[e].Size = entries[e].Size()
- tree.Entries[e].SHA = entries[e].ID.String()
+ tree.Entries = make([]gitea.GitEntry, rangeEnd-rangeStart)
+ for e := rangeStart; e < rangeEnd; e++ {
+ i := e - rangeStart
+ tree.Entries[i].Path = entries[e].Name()
+ tree.Entries[i].Mode = fmt.Sprintf("%06x", entries[e].Mode())
+ tree.Entries[i].Type = string(entries[e].Type)
+ tree.Entries[i].Size = entries[e].Size()
+ tree.Entries[i].SHA = entries[e].ID.String()
if entries[e].IsDir() {
copy(treeURL[copyPos:], entries[e].ID.String())
- tree.Entries[e].URL = string(treeURL[:])
+ tree.Entries[i].URL = string(treeURL[:])
} else {
copy(blobURL[copyPos:], entries[e].ID.String())
- tree.Entries[e].URL = string(blobURL[:])
+ tree.Entries[i].URL = string(blobURL[:])
}
}
return tree
diff --git a/routers/api/v1/repo/tree_test.go b/routers/api/v1/repo/tree_test.go
new file mode 100644
index 0000000000..708516e979
--- /dev/null
+++ b/routers/api/v1/repo/tree_test.go
@@ -0,0 +1,48 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package repo
+
+import (
+ "github.com/stretchr/testify/assert"
+ "testing"
+
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/context"
+ "code.gitea.io/gitea/modules/test"
+ "code.gitea.io/sdk/gitea"
+)
+
+func TestGetTreeBySHA(t *testing.T) {
+ models.PrepareTestEnv(t)
+ sha := "master"
+ ctx := test.MockContext(t, "user2/repo1")
+ ctx.SetParams(":id", "1")
+ ctx.SetParams(":sha", sha)
+ test.LoadRepo(t, ctx, 1)
+ test.LoadRepoCommit(t, ctx)
+ test.LoadUser(t, ctx, 2)
+ test.LoadGitRepo(t, ctx)
+
+ tree := GetTreeBySHA(&context.APIContext{Context: ctx, Org: nil}, ctx.Params("sha"))
+ expectedTree := &gitea.GitTreeResponse{
+ SHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d",
+ URL: "https://try.gitea.io/api/v1/repos/user2/repo1/git/trees/65f1bf27bc3bf70f64657658635e66094edbcb4d",
+ Entries: []gitea.GitEntry{
+ {
+ Path: "README.md",
+ Mode: "100644",
+ Type: "blob",
+ Size: 30,
+ SHA: "4b4851ad51df6a7d9f25c979345979eaeb5b349f",
+ URL: "https://try.gitea.io/api/v1/repos/user2/repo1/git/blobs/4b4851ad51df6a7d9f25c979345979eaeb5b349f",
+ },
+ },
+ Truncated: false,
+ Page: 1,
+ TotalCount: 1,
+ }
+
+ assert.EqualValues(t, tree, expectedTree)
+}