diff options
author | Richard Mahn <richmahn@users.noreply.github.com> | 2019-02-06 11:19:26 -0700 |
---|---|---|
committer | zeripath <art27@cantab.net> | 2019-02-06 18:19:26 +0000 |
commit | da1edbfb79566e9d31f43ee85eb2e9fc9b52695b (patch) | |
tree | 6e81098a8ddb5695b52a6a136bb24286fb8a8c9b /routers/api | |
parent | 0c840a924a9a78556dafdc3e558bdcfe3c704201 (diff) | |
download | gitea-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.go | 66 | ||||
-rw-r--r-- | routers/api/v1/repo/tree_test.go | 48 |
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) +} |