Skip to content
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

Calculate label URL on API #16186

Merged
merged 12 commits into from
Sep 10, 2021
59 changes: 54 additions & 5 deletions modules/convert/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
package convert

import (
"fmt"
"strings"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
)

Expand All @@ -26,6 +29,9 @@ func ToAPIIssue(issue *models.Issue) *api.Issue {
return &api.Issue{}
}

repoCache := make(map[int64]*models.Repository)
repoCache[issue.RepoID] = issue.Repo

apiIssue := &api.Issue{
ID: issue.ID,
URL: issue.APIURL(),
Expand All @@ -35,7 +41,7 @@ func ToAPIIssue(issue *models.Issue) *api.Issue {
Title: issue.Title,
Body: issue.Content,
Ref: issue.Ref,
Labels: ToLabelList(issue.Labels),
Labels: ToLabelList(issue.Labels, repoCache, nil),
State: issue.State(),
IsLocked: issue.IsLocked,
Comments: issue.NumComments,
Expand Down Expand Up @@ -168,20 +174,63 @@ func ToTrackedTimeList(tl models.TrackedTimeList) api.TrackedTimeList {
}

// ToLabel converts Label to API format
func ToLabel(label *models.Label) *api.Label {
return &api.Label{
func ToLabel(label *models.Label, repoCache map[int64]*models.Repository, orgCache map[int64]*models.User) *api.Label {
result := &api.Label{
ID: label.ID,
Name: label.Name,
Color: strings.TrimLeft(label.Color, "#"),
Description: label.Description,
}

// calculate URL
if label.BelongsToRepo() {
if repoCache == nil {
repoCache = make(map[int64]*models.Repository)
}
_, ok := repoCache[label.RepoID]
6543 marked this conversation as resolved.
Show resolved Hide resolved
if !ok {
var err error
repoCache[label.RepoID], err = models.GetRepositoryByID(label.RepoID)
if err != nil {
log.Error("cant load repo of label [%d]: %v", label.ID, err)
}
}

if repo := repoCache[label.RepoID]; repo != nil {
result.URL = fmt.Sprintf("%s/labels/%d", repo.APIURL(), label.ID)
}
} else { // BelongsToOrg
if orgCache == nil {
orgCache = make(map[int64]*models.User)
}
_, ok := orgCache[label.OrgID]
if !ok {
var err error
orgCache[label.OrgID], err = models.GetUserByID(label.OrgID)
if err != nil {
log.Error("cant load org of label [%d]: %v", label.ID, err)
}
}

if org := orgCache[label.OrgID]; org != nil {
result.URL = fmt.Sprintf("%sapi/v1/orgs/%s/labels/%d", setting.AppURL, org.Name, label.ID)
}
}

return result
}

// ToLabelList converts list of Label to API format
func ToLabelList(labels []*models.Label) []*api.Label {
func ToLabelList(labels []*models.Label, repoCache map[int64]*models.Repository, orgCache map[int64]*models.User) []*api.Label {
result := make([]*api.Label, len(labels))
if repoCache == nil {
repoCache = make(map[int64]*models.Repository)
}
if orgCache == nil {
orgCache = make(map[int64]*models.User)
}
for i := range labels {
result[i] = ToLabel(labels[i])
result[i] = ToLabel(labels[i], repoCache, orgCache)
}
return result
}
Expand Down
5 changes: 4 additions & 1 deletion modules/convert/issue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
package convert

import (
"fmt"
"testing"
"time"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"

Expand All @@ -22,7 +24,8 @@ func TestLabel_ToLabel(t *testing.T) {
ID: label.ID,
Name: label.Name,
Color: "abcdef",
}, ToLabel(label))
URL: fmt.Sprintf("%sapi/v1/repos/user2/repo1/labels/%d", setting.AppURL, label.ID),
}, ToLabel(label, nil, nil))
}

func TestMilestone_APIFormat(t *testing.T) {
Expand Down
18 changes: 13 additions & 5 deletions routers/api/v1/org/label.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ func ListLabels(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "GetLabelsByOrgID", err)
return
}

ctx.JSON(http.StatusOK, convert.ToLabelList(labels))
orgCache := make(map[int64]*models.User)
orgCache[ctx.Org.Organization.ID] = ctx.Org.Organization
ctx.JSON(http.StatusOK, convert.ToLabelList(labels, nil, orgCache))
}

// CreateLabel create a label for a repository
Expand Down Expand Up @@ -96,7 +97,9 @@ func CreateLabel(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "NewLabel", err)
return
}
ctx.JSON(http.StatusCreated, convert.ToLabel(label))
orgCache := make(map[int64]*models.User)
orgCache[ctx.Org.Organization.ID] = ctx.Org.Organization
ctx.JSON(http.StatusCreated, convert.ToLabel(label, nil, orgCache))
}

// GetLabel get label by organization and label id
Expand Down Expand Up @@ -141,7 +144,9 @@ func GetLabel(ctx *context.APIContext) {
return
}

ctx.JSON(http.StatusOK, convert.ToLabel(label))
orgCache := make(map[int64]*models.User)
orgCache[ctx.Org.Organization.ID] = ctx.Org.Organization
ctx.JSON(http.StatusOK, convert.ToLabel(label, nil, orgCache))
}

// EditLabel modify a label for an Organization
Expand Down Expand Up @@ -205,7 +210,10 @@ func EditLabel(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "UpdateLabel", err)
return
}
ctx.JSON(http.StatusOK, convert.ToLabel(label))

orgCache := make(map[int64]*models.User)
orgCache[ctx.Org.Organization.ID] = ctx.Org.Organization
ctx.JSON(http.StatusOK, convert.ToLabel(label, nil, orgCache))
}

// DeleteLabel delete a label for an organization
Expand Down
12 changes: 9 additions & 3 deletions routers/api/v1/repo/issue_label.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ func ListIssueLabels(ctx *context.APIContext) {
return
}

ctx.JSON(http.StatusOK, convert.ToLabelList(issue.Labels))
repoCache := make(map[int64]*models.Repository)
repoCache[ctx.Repo.Repository.ID] = ctx.Repo.Repository
ctx.JSON(http.StatusOK, convert.ToLabelList(issue.Labels, repoCache, nil))
}

// AddIssueLabels add labels for an issue
Expand Down Expand Up @@ -117,7 +119,9 @@ func AddIssueLabels(ctx *context.APIContext) {
return
}

ctx.JSON(http.StatusOK, convert.ToLabelList(labels))
repoCache := make(map[int64]*models.Repository)
repoCache[ctx.Repo.Repository.ID] = ctx.Repo.Repository
ctx.JSON(http.StatusOK, convert.ToLabelList(labels, repoCache, nil))
}

// DeleteIssueLabel delete a label for an issue
Expand Down Expand Up @@ -243,7 +247,9 @@ func ReplaceIssueLabels(ctx *context.APIContext) {
return
}

ctx.JSON(http.StatusOK, convert.ToLabelList(labels))
repoCache := make(map[int64]*models.Repository)
repoCache[ctx.Repo.Repository.ID] = ctx.Repo.Repository
ctx.JSON(http.StatusOK, convert.ToLabelList(labels, repoCache, nil))
}

// ClearIssueLabels delete all the labels for an issue
Expand Down
18 changes: 14 additions & 4 deletions routers/api/v1/repo/label.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ func ListLabels(ctx *context.APIContext) {
return
}

ctx.JSON(http.StatusOK, convert.ToLabelList(labels))
repoCache := make(map[int64]*models.Repository)
repoCache[ctx.Repo.Repository.ID] = ctx.Repo.Repository
ctx.JSON(http.StatusOK, convert.ToLabelList(labels, repoCache, nil))
}

// GetLabel get label by repository and label id
Expand Down Expand Up @@ -105,7 +107,9 @@ func GetLabel(ctx *context.APIContext) {
return
}

ctx.JSON(http.StatusOK, convert.ToLabel(label))
repoCache := make(map[int64]*models.Repository)
repoCache[ctx.Repo.Repository.ID] = ctx.Repo.Repository
ctx.JSON(http.StatusOK, convert.ToLabel(label, repoCache, nil))
}

// CreateLabel create a label for a repository
Expand Down Expand Up @@ -158,7 +162,10 @@ func CreateLabel(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "NewLabel", err)
return
}
ctx.JSON(http.StatusCreated, convert.ToLabel(label))

repoCache := make(map[int64]*models.Repository)
repoCache[ctx.Repo.Repository.ID] = ctx.Repo.Repository
ctx.JSON(http.StatusCreated, convert.ToLabel(label, repoCache, nil))
}

// EditLabel modify a label for a repository
Expand Down Expand Up @@ -228,7 +235,10 @@ func EditLabel(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "UpdateLabel", err)
return
}
ctx.JSON(http.StatusOK, convert.ToLabel(label))

repoCache := make(map[int64]*models.Repository)
repoCache[ctx.Repo.Repository.ID] = ctx.Repo.Repository
ctx.JSON(http.StatusOK, convert.ToLabel(label, repoCache, nil))
}

// DeleteLabel delete a label for a repository
Expand Down