From 51578d64188a7077848cb60d3ead8e818637ab59 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Fri, 10 Sep 2021 18:03:16 +0200 Subject: [PATCH] Calculate label URL on API (#16186) close #8028 --- modules/convert/issue.go | 33 +++++++++++++++++++++++++----- modules/convert/issue_test.go | 6 +++++- routers/api/v1/org/label.go | 10 +++++---- routers/api/v1/repo/issue_label.go | 6 +++--- routers/api/v1/repo/label.go | 10 +++++---- 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/modules/convert/issue.go b/modules/convert/issue.go index da09aeaca41ef..3974d460e0e5d 100644 --- a/modules/convert/issue.go +++ b/modules/convert/issue.go @@ -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" ) @@ -25,6 +28,9 @@ func ToAPIIssue(issue *models.Issue) *api.Issue { if err := issue.LoadRepo(); err != nil { return &api.Issue{} } + if err := issue.Repo.GetOwner(); err != nil { + return &api.Issue{} + } apiIssue := &api.Issue{ ID: issue.ID, @@ -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, issue.Repo, issue.Repo.Owner), State: issue.State(), IsLocked: issue.IsLocked, Comments: issue.NumComments, @@ -168,20 +174,37 @@ 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, repo *models.Repository, org *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() && repo != nil { + if repo != nil { + result.URL = fmt.Sprintf("%s/labels/%d", repo.APIURL(), label.ID) + } else { + log.Error("ToLabel did not get repo to calculate url for label with id '%d'", label.ID) + } + } else { // BelongsToOrg + if org != nil { + result.URL = fmt.Sprintf("%sapi/v1/orgs/%s/labels/%d", setting.AppURL, org.Name, label.ID) + } else { + log.Error("ToLabel did not get org to calculate url for label with id '%d'", label.ID) + } + } + + return result } // ToLabelList converts list of Label to API format -func ToLabelList(labels []*models.Label) []*api.Label { +func ToLabelList(labels []*models.Label, repo *models.Repository, org *models.User) []*api.Label { result := make([]*api.Label, len(labels)) for i := range labels { - result[i] = ToLabel(labels[i]) + result[i] = ToLabel(labels[i], repo, org) } return result } diff --git a/modules/convert/issue_test.go b/modules/convert/issue_test.go index 2f8f56e99a643..f3c5b50c8cf3e 100644 --- a/modules/convert/issue_test.go +++ b/modules/convert/issue_test.go @@ -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" @@ -18,11 +20,13 @@ import ( func TestLabel_ToLabel(t *testing.T) { assert.NoError(t, models.PrepareTestDatabase()) label := models.AssertExistsAndLoadBean(t, &models.Label{ID: 1}).(*models.Label) + repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: label.RepoID}).(*models.Repository) assert.Equal(t, &api.Label{ 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, repo, nil)) } func TestMilestone_APIFormat(t *testing.T) { diff --git a/routers/api/v1/org/label.go b/routers/api/v1/org/label.go index 09acb0bf04426..b3752841898d9 100644 --- a/routers/api/v1/org/label.go +++ b/routers/api/v1/org/label.go @@ -56,7 +56,7 @@ func ListLabels(ctx *context.APIContext) { } ctx.SetTotalCountHeader(count) - ctx.JSON(http.StatusOK, convert.ToLabelList(labels)) + ctx.JSON(http.StatusOK, convert.ToLabelList(labels, nil, ctx.Org.Organization)) } // CreateLabel create a label for a repository @@ -103,7 +103,8 @@ func CreateLabel(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "NewLabel", err) return } - ctx.JSON(http.StatusCreated, convert.ToLabel(label)) + + ctx.JSON(http.StatusCreated, convert.ToLabel(label, nil, ctx.Org.Organization)) } // GetLabel get label by organization and label id @@ -148,7 +149,7 @@ func GetLabel(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, convert.ToLabel(label)) + ctx.JSON(http.StatusOK, convert.ToLabel(label, nil, ctx.Org.Organization)) } // EditLabel modify a label for an Organization @@ -212,7 +213,8 @@ func EditLabel(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "UpdateLabel", err) return } - ctx.JSON(http.StatusOK, convert.ToLabel(label)) + + ctx.JSON(http.StatusOK, convert.ToLabel(label, nil, ctx.Org.Organization)) } // DeleteLabel delete a label for an organization diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go index d7f64b2d995eb..0469ae247c3b4 100644 --- a/routers/api/v1/repo/issue_label.go +++ b/routers/api/v1/repo/issue_label.go @@ -61,7 +61,7 @@ func ListIssueLabels(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, convert.ToLabelList(issue.Labels)) + ctx.JSON(http.StatusOK, convert.ToLabelList(issue.Labels, ctx.Repo.Repository, ctx.Repo.Owner)) } // AddIssueLabels add labels for an issue @@ -117,7 +117,7 @@ func AddIssueLabels(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, convert.ToLabelList(labels)) + ctx.JSON(http.StatusOK, convert.ToLabelList(labels, ctx.Repo.Repository, ctx.Repo.Owner)) } // DeleteIssueLabel delete a label for an issue @@ -243,7 +243,7 @@ func ReplaceIssueLabels(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, convert.ToLabelList(labels)) + ctx.JSON(http.StatusOK, convert.ToLabelList(labels, ctx.Repo.Repository, ctx.Repo.Owner)) } // ClearIssueLabels delete all the labels for an issue diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go index 1de5705aa28e4..67682fc60da9f 100644 --- a/routers/api/v1/repo/label.go +++ b/routers/api/v1/repo/label.go @@ -62,7 +62,7 @@ func ListLabels(ctx *context.APIContext) { } ctx.SetTotalCountHeader(count) - ctx.JSON(http.StatusOK, convert.ToLabelList(labels)) + ctx.JSON(http.StatusOK, convert.ToLabelList(labels, ctx.Repo.Repository, nil)) } // GetLabel get label by repository and label id @@ -112,7 +112,7 @@ func GetLabel(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, convert.ToLabel(label)) + ctx.JSON(http.StatusOK, convert.ToLabel(label, ctx.Repo.Repository, nil)) } // CreateLabel create a label for a repository @@ -165,7 +165,8 @@ func CreateLabel(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "NewLabel", err) return } - ctx.JSON(http.StatusCreated, convert.ToLabel(label)) + + ctx.JSON(http.StatusCreated, convert.ToLabel(label, ctx.Repo.Repository, nil)) } // EditLabel modify a label for a repository @@ -235,7 +236,8 @@ func EditLabel(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "UpdateLabel", err) return } - ctx.JSON(http.StatusOK, convert.ToLabel(label)) + + ctx.JSON(http.StatusOK, convert.ToLabel(label, ctx.Repo.Repository, nil)) } // DeleteLabel delete a label for a repository