* enable paggination for repoTags * precalculate first, cut slice second * Apply suggestions from code review Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>tags/v1.21.12.1
| @@ -187,7 +187,7 @@ func (repo *Repository) GetTag(name string) (*Tag, error) { | |||||
| } | } | ||||
| // GetTagInfos returns all tag infos of the repository. | // GetTagInfos returns all tag infos of the repository. | ||||
| func (repo *Repository) GetTagInfos() ([]*Tag, error) { | |||||
| func (repo *Repository) GetTagInfos(page, pageSize int) ([]*Tag, error) { | |||||
| // TODO this a slow implementation, makes one git command per tag | // TODO this a slow implementation, makes one git command per tag | ||||
| stdout, err := NewCommand("tag").RunInDir(repo.Path) | stdout, err := NewCommand("tag").RunInDir(repo.Path) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -195,6 +195,18 @@ func (repo *Repository) GetTagInfos() ([]*Tag, error) { | |||||
| } | } | ||||
| tagNames := strings.Split(strings.TrimRight(stdout, "\n"), "\n") | tagNames := strings.Split(strings.TrimRight(stdout, "\n"), "\n") | ||||
| if page != 0 { | |||||
| skip := (page - 1) * pageSize | |||||
| if skip >= len(tagNames) { | |||||
| return nil, nil | |||||
| } | |||||
| if (len(tagNames) - skip) < pageSize { | |||||
| pageSize = len(tagNames) - skip | |||||
| } | |||||
| tagNames = tagNames[skip : skip+pageSize] | |||||
| } | |||||
| var tags = make([]*Tag, 0, len(tagNames)) | var tags = make([]*Tag, 0, len(tagNames)) | ||||
| for _, tagName := range tagNames { | for _, tagName := range tagNames { | ||||
| tagName = strings.TrimSpace(tagName) | tagName = strings.TrimSpace(tagName) | ||||
| @@ -18,7 +18,7 @@ func TestRepository_GetTags(t *testing.T) { | |||||
| assert.NoError(t, err) | assert.NoError(t, err) | ||||
| defer bareRepo1.Close() | defer bareRepo1.Close() | ||||
| tags, err := bareRepo1.GetTagInfos() | |||||
| tags, err := bareRepo1.GetTagInfos(0, 0) | |||||
| assert.NoError(t, err) | assert.NoError(t, err) | ||||
| assert.Len(t, tags, 1) | assert.Len(t, tags, 1) | ||||
| assert.EqualValues(t, "test", tags[0].Name) | assert.EqualValues(t, "test", tags[0].Name) | ||||
| @@ -10,6 +10,7 @@ import ( | |||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/convert" | "code.gitea.io/gitea/modules/convert" | ||||
| api "code.gitea.io/gitea/modules/structs" | api "code.gitea.io/gitea/modules/structs" | ||||
| "code.gitea.io/gitea/routers/api/v1/utils" | |||||
| ) | ) | ||||
| // ListTags list all the tags of a repository | // ListTags list all the tags of a repository | ||||
| @@ -30,11 +31,21 @@ func ListTags(ctx *context.APIContext) { | |||||
| // description: name of the repo | // description: name of the repo | ||||
| // type: string | // type: string | ||||
| // required: true | // required: true | ||||
| // - name: page | |||||
| // in: query | |||||
| // description: page number of results to return (1-based) | |||||
| // type: integer | |||||
| // - name: limit | |||||
| // in: query | |||||
| // description: page size of results, default maximum page size is 50 | |||||
| // type: integer | |||||
| // responses: | // responses: | ||||
| // "200": | // "200": | ||||
| // "$ref": "#/responses/TagList" | // "$ref": "#/responses/TagList" | ||||
| tags, err := ctx.Repo.GitRepo.GetTagInfos() | |||||
| listOpts := utils.GetListOptions(ctx) | |||||
| tags, err := ctx.Repo.GitRepo.GetTagInfos(listOpts.Page, listOpts.PageSize) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Error(http.StatusInternalServerError, "GetTags", err) | ctx.Error(http.StatusInternalServerError, "GetTags", err) | ||||
| return | return | ||||
| @@ -7251,6 +7251,18 @@ | |||||
| "name": "repo", | "name": "repo", | ||||
| "in": "path", | "in": "path", | ||||
| "required": true | "required": true | ||||
| }, | |||||
| { | |||||
| "type": "integer", | |||||
| "description": "page number of results to return (1-based)", | |||||
| "name": "page", | |||||
| "in": "query" | |||||
| }, | |||||
| { | |||||
| "type": "integer", | |||||
| "description": "page size of results, default maximum page size is 50", | |||||
| "name": "limit", | |||||
| "in": "query" | |||||
| } | } | ||||
| ], | ], | ||||
| "responses": { | "responses": { | ||||