1package web
 2
 3import (
 4	"bytes"
 5	"context"
 6	"html/template"
 7
 8	"github.com/charmbracelet/soft-serve/git"
 9	"github.com/charmbracelet/soft-serve/pkg/backend"
10	"github.com/charmbracelet/soft-serve/pkg/proto"
11	"github.com/microcosm-cc/bluemonday"
12	"github.com/yuin/goldmark"
13	extension "github.com/yuin/goldmark/extension"
14	"github.com/yuin/goldmark/parser"
15	goldmarkhtml "github.com/yuin/goldmark/renderer/html"
16)
17
18// renderMarkdown converts markdown content to sanitized HTML.
19func renderMarkdown(content []byte) (template.HTML, error) {
20	var buf bytes.Buffer
21	md := goldmark.New(
22		goldmark.WithExtensions(extension.GFM),
23		goldmark.WithParserOptions(
24			parser.WithAutoHeadingID(),
25		),
26		goldmark.WithRendererOptions(
27			goldmarkhtml.WithUnsafe(),
28		),
29	)
30
31	if err := md.Convert(content, &buf); err != nil {
32		return "", err
33	}
34
35	policy := bluemonday.UGCPolicy()
36	policy.AllowStyling()
37	policy.RequireNoFollowOnLinks(false)
38	policy.AllowElements("center")
39	sanitized := policy.SanitizeBytes(buf.Bytes())
40
41	return template.HTML(sanitized), nil
42}
43
44// getServerReadme loads and renders the README from the .soft-serve repository.
45func getServerReadme(ctx context.Context, be *backend.Backend) (template.HTML, error) {
46	repos, err := be.Repositories(ctx)
47	if err != nil {
48		return "", err
49	}
50
51	for _, r := range repos {
52		if r.Name() == ".soft-serve" {
53			readme, _, err := backend.Readme(r, nil)
54			if err != nil {
55				return "", err
56			}
57			if readme != "" {
58				return renderMarkdown([]byte(readme))
59			}
60		}
61	}
62
63	return "", nil
64}
65
66// openRepository opens a git repository.
67func openRepository(repo proto.Repository) (*git.Repository, error) {
68	return repo.Open()
69}
70
71// getDefaultBranch returns the default branch name, or empty string if none exists.
72func getDefaultBranch(gr *git.Repository) string {
73	head, err := gr.HEAD()
74	if err != nil || head == nil {
75		return ""
76	}
77	return head.Name().Short()
78}