Skip to content

Add API for Label templates #24602

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions modules/structs/issue_label.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,13 @@ type IssueLabelsOption struct {
// list of label IDs
Labels []int64 `json:"labels"`
}

// LabelTemplate info of a Label template
type LabelTemplate struct {
Name string `json:"name"`
// example: false
Exclusive bool `json:"exclusive"`
// example: 00aabb
Color string `json:"color"`
Description string `json:"description"`
}
2 changes: 2 additions & 0 deletions routers/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,8 @@ func Routes(ctx gocontext.Context) *web.Route {
m.Get("/gitignore/templates/{name}", misc.GetGitignoreTemplateInfo)
m.Get("/licenses", misc.ListLicenseTemplates)
m.Get("/licenses/{name}", misc.GetLicenseTemplateInfo)
m.Get("/label/templates", misc.ListLabelTemplates)
m.Get("/label/templates/{name}", misc.GetLabelTemplate)
m.Group("/settings", func() {
m.Get("/ui", settings.GetGeneralUISettings)
m.Get("/api", settings.GetGeneralAPISettings)
Expand Down
60 changes: 60 additions & 0 deletions routers/api/v1/misc/label_templates.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package misc

import (
"net/http"

"code.gitea.io/gitea/modules/context"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/convert"
)

// Shows a list of all Label templates
func ListLabelTemplates(ctx *context.APIContext) {
// swagger:operation GET /label/templates miscellaneous listLabelTemplates
// ---
// summary: Returns a list of all label templates
// produces:
// - application/json
// responses:
// "200":
// "$ref": "#/responses/LabelTemplateList"
result := make([]string, len(repo_module.LabelTemplateFiles))
for i := range repo_module.LabelTemplateFiles {
result[i] = repo_module.LabelTemplateFiles[i].DisplayName
}

ctx.JSON(http.StatusOK, result)
}

// Shows all labels in a template
func GetLabelTemplate(ctx *context.APIContext) {
// swagger:operation GET /label/templates/{name} miscellaneous getLabelTemplateInfo
// ---
// summary: Returns all labels in a template
// produces:
// - application/json
// parameters:
// - name: name
// in: path
// description: name of the template
// type: string
// required: true
// responses:
// "200":
// "$ref": "#/responses/LabelTemplateInfo"
// "404":
// "$ref": "#/responses/notFound"
name := util.PathJoinRelX(ctx.Params("name"))

labels, err := repo_module.LoadTemplateLabelsByDisplayName(name)
if err != nil {
ctx.NotFound()
return
}

ctx.JSON(http.StatusOK, convert.ToLabelTemplateList(labels))
}
14 changes: 14 additions & 0 deletions routers/api/v1/swagger/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,17 @@ type swaggerResponseStringSlice struct {
// in:body
Body []string `json:"body"`
}

// LabelTemplateList
// swagger:response LabelTemplateList
type swaggerResponseLabelTemplateList struct {
// in:body
Body []string `json:"body"`
}

// LabelTemplateInfo
// swagger:response LabelTemplateInfo
type swaggerResponseLabelTemplateInfo struct {
// in:body
Body []api.LabelTemplate `json:"body"`
}
22 changes: 22 additions & 0 deletions services/convert/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/label"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
Expand Down Expand Up @@ -238,3 +239,24 @@ func ToAPIMilestone(m *issues_model.Milestone) *api.Milestone {
}
return apiMilestone
}

// ToLabelTemplate converts Label to API format
func ToLabelTemplate(label *label.Label) *api.LabelTemplate {
result := &api.LabelTemplate{
Name: label.Name,
Exclusive: label.Exclusive,
Color: strings.TrimLeft(label.Color, "#"),
Description: label.Description,
}

return result
}

// ToLabelTemplateList converts list of Label to API format
func ToLabelTemplateList(labels []*label.Label) []*api.LabelTemplate {
result := make([]*api.LabelTemplate, len(labels))
for i := range labels {
result[i] = ToLabelTemplate(labels[i])
}
return result
}
89 changes: 89 additions & 0 deletions templates/swagger/v1_json.tmpl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions tests/integration/api_label_templates_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package integration

import (
"fmt"
"net/http"
"net/url"
"strings"
"testing"

repo_module "code.gitea.io/gitea/modules/repository"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/tests"

"github.com/stretchr/testify/assert"
)

func TestAPIListLabelTemplates(t *testing.T) {
defer tests.PrepareTestEnv(t)()

req := NewRequest(t, "GET", "/api/v1/label/templates")
resp := MakeRequest(t, req, http.StatusOK)

var templateList []string
DecodeJSON(t, resp, &templateList)

for i := range repo_module.LabelTemplateFiles {
assert.Equal(t, repo_module.LabelTemplateFiles[i].DisplayName, templateList[i])
}
}

func TestAPIGetLabelTemplateInfo(t *testing.T) {
defer tests.PrepareTestEnv(t)()

// If Gitea has for some reason no Label templates, we need to skip this test
if len(repo_module.LabelTemplateFiles) == 0 {
return
}

// Use the first template for the test
templateName := repo_module.LabelTemplateFiles[0].DisplayName

urlStr := fmt.Sprintf("/api/v1/label/templates/%s", url.PathEscape(templateName))
req := NewRequest(t, "GET", urlStr)
resp := MakeRequest(t, req, http.StatusOK)

var templateInfo []api.LabelTemplate
DecodeJSON(t, resp, &templateInfo)

labels, err := repo_module.LoadTemplateLabelsByDisplayName(templateName)
assert.NoError(t, err)

for i := range labels {
assert.Equal(t, strings.TrimLeft(labels[i].Color, "#"), templateInfo[i].Color)
assert.Equal(t, labels[i].Description, templateInfo[i].Description)
assert.Equal(t, labels[i].Exclusive, templateInfo[i].Exclusive)
assert.Equal(t, labels[i].Name, templateInfo[i].Name)
}
}