166 lines
4.5 KiB
Go
166 lines
4.5 KiB
Go
// Copyright 2023 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package badges
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
|
|
actions_model "code.gitea.io/gitea/models/actions"
|
|
repo_model "code.gitea.io/gitea/models/repo"
|
|
"code.gitea.io/gitea/models/unit"
|
|
context_module "code.gitea.io/gitea/modules/context"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
)
|
|
|
|
func getBadgeURL(ctx *context_module.Context, label, text, color string) string {
|
|
sb := &strings.Builder{}
|
|
_ = setting.Badges.GeneratorURLTemplateTemplate.Execute(sb, map[string]string{
|
|
"label": url.PathEscape(label),
|
|
"text": url.PathEscape(text),
|
|
"color": url.PathEscape(color),
|
|
})
|
|
|
|
badgeURL := sb.String()
|
|
q := ctx.Req.URL.Query()
|
|
// Remove any `branch` or `event` query parameters. They're used by the
|
|
// workflow badge route, and do not need forwarding to the badge generator.
|
|
delete(q, "branch")
|
|
delete(q, "event")
|
|
if len(q) > 0 {
|
|
return fmt.Sprintf("%s?%s", badgeURL, q.Encode())
|
|
}
|
|
return badgeURL
|
|
}
|
|
|
|
func redirectToBadge(ctx *context_module.Context, label, text, color string) {
|
|
ctx.Redirect(getBadgeURL(ctx, label, text, color))
|
|
}
|
|
|
|
func errorBadge(ctx *context_module.Context, label, text string) {
|
|
ctx.Redirect(getBadgeURL(ctx, label, text, "crimson"))
|
|
}
|
|
|
|
func GetWorkflowBadge(ctx *context_module.Context) {
|
|
branch := ctx.Req.URL.Query().Get("branch")
|
|
if branch == "" {
|
|
branch = ctx.Repo.Repository.DefaultBranch
|
|
}
|
|
branch = fmt.Sprintf("refs/heads/%s", branch)
|
|
event := ctx.Req.URL.Query().Get("event")
|
|
|
|
workflowFile := ctx.Params("workflow_name")
|
|
run, err := actions_model.GetLatestRunForBranchAndWorkflow(ctx, ctx.Repo.Repository.ID, branch, workflowFile, event)
|
|
if err != nil {
|
|
errorBadge(ctx, workflowFile, "Not found")
|
|
return
|
|
}
|
|
|
|
var color string
|
|
switch run.Status {
|
|
case actions_model.StatusUnknown:
|
|
color = "lightgrey"
|
|
case actions_model.StatusWaiting:
|
|
color = "lightgrey"
|
|
case actions_model.StatusRunning:
|
|
color = "gold"
|
|
case actions_model.StatusSuccess:
|
|
color = "brightgreen"
|
|
case actions_model.StatusFailure:
|
|
color = "crimson"
|
|
case actions_model.StatusCancelled:
|
|
color = "orange"
|
|
case actions_model.StatusSkipped:
|
|
color = "blue"
|
|
case actions_model.StatusBlocked:
|
|
color = "yellow"
|
|
default:
|
|
color = "lightgrey"
|
|
}
|
|
|
|
redirectToBadge(ctx, workflowFile, run.Status.String(), color)
|
|
}
|
|
|
|
func getIssueOrPullBadge(ctx *context_module.Context, label, variant string, num int) {
|
|
var text string
|
|
if len(variant) > 0 {
|
|
text = fmt.Sprintf("%d %s", num, variant)
|
|
} else {
|
|
text = fmt.Sprintf("%d", num)
|
|
}
|
|
redirectToBadge(ctx, label, text, "blue")
|
|
}
|
|
|
|
func getIssueBadge(ctx *context_module.Context, variant string, num int) {
|
|
if !ctx.Repo.CanRead(unit.TypeIssues) &&
|
|
!ctx.Repo.CanRead(unit.TypeExternalTracker) {
|
|
errorBadge(ctx, "issues", "Not found")
|
|
return
|
|
}
|
|
|
|
_, err := ctx.Repo.Repository.GetUnit(ctx, unit.TypeExternalTracker)
|
|
if err == nil {
|
|
errorBadge(ctx, "issues", "Not found")
|
|
return
|
|
}
|
|
|
|
getIssueOrPullBadge(ctx, "issues", variant, num)
|
|
}
|
|
|
|
func getPullBadge(ctx *context_module.Context, variant string, num int) {
|
|
if !ctx.Repo.Repository.CanEnablePulls() || !ctx.Repo.CanRead(unit.TypePullRequests) {
|
|
errorBadge(ctx, "pulls", "Not found")
|
|
return
|
|
}
|
|
|
|
getIssueOrPullBadge(ctx, "pulls", variant, num)
|
|
}
|
|
|
|
func GetOpenIssuesBadge(ctx *context_module.Context) {
|
|
getIssueBadge(ctx, "open", ctx.Repo.Repository.NumOpenIssues)
|
|
}
|
|
|
|
func GetClosedIssuesBadge(ctx *context_module.Context) {
|
|
getIssueBadge(ctx, "closed", ctx.Repo.Repository.NumClosedIssues)
|
|
}
|
|
|
|
func GetTotalIssuesBadge(ctx *context_module.Context) {
|
|
getIssueBadge(ctx, "", ctx.Repo.Repository.NumIssues)
|
|
}
|
|
|
|
func GetOpenPullsBadge(ctx *context_module.Context) {
|
|
getPullBadge(ctx, "open", ctx.Repo.Repository.NumOpenPulls)
|
|
}
|
|
|
|
func GetClosedPullsBadge(ctx *context_module.Context) {
|
|
getPullBadge(ctx, "closed", ctx.Repo.Repository.NumClosedPulls)
|
|
}
|
|
|
|
func GetTotalPullsBadge(ctx *context_module.Context) {
|
|
getPullBadge(ctx, "", ctx.Repo.Repository.NumPulls)
|
|
}
|
|
|
|
func GetStarsBadge(ctx *context_module.Context) {
|
|
redirectToBadge(ctx, "stars", fmt.Sprintf("%d", ctx.Repo.Repository.NumStars), "blue")
|
|
}
|
|
|
|
func GetLatestReleaseBadge(ctx *context_module.Context) {
|
|
release, err := repo_model.GetLatestReleaseByRepoID(ctx, ctx.Repo.Repository.ID)
|
|
if err != nil {
|
|
if repo_model.IsErrReleaseNotExist(err) {
|
|
errorBadge(ctx, "release", "Not found")
|
|
return
|
|
}
|
|
ctx.ServerError("GetLatestReleaseByRepoID", err)
|
|
}
|
|
|
|
if err := release.LoadAttributes(ctx); err != nil {
|
|
ctx.ServerError("LoadAttributes", err)
|
|
return
|
|
}
|
|
|
|
redirectToBadge(ctx, "release", release.TagName, "blue")
|
|
}
|