GitRoot
craft your forge, build your project, grow your community freely
1// SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
2//
3// SPDX-License-Identifier: EUPL-1.2
4
5package main
6
7import (
8 "errors"
9 "fmt"
10 "io/fs"
11 "path/filepath"
12 "slices"
13 "strings"
14
15 "gitroot.dev/libs/golang/plugin/model"
16)
17
18type branchCommits struct {
19 branch string
20 commit *linkedCommits
21}
22
23func (p *Plugin) AddIfNotExist(commit model.Commit) error {
24 found := false
25 for _, bc := range p.branchCommits {
26 if bc.branch == commit.Branch {
27 found = true
28 bc.commit.Insert(commit)
29 }
30 }
31 if !found {
32 bc := &branchCommits{branch: commit.Branch, commit: &linkedCommits{}}
33
34 pathBranch := filepath.Join(p.config.branchesDir, fmt.Sprintf("%s.html", bc.branch))
35 contentBranch, err := fs.ReadFile(p.server.Webcontent(), pathBranch)
36 if err != nil {
37 contentBranch = []byte("")
38 }
39 p.parsePreviousCommits(bc, string(contentBranch))
40
41 bc.commit.Insert(commit)
42 p.branchCommits = append(p.branchCommits, bc)
43 }
44 return nil
45}
46
47func (p *Plugin) RenderBranches() error {
48 path := filepath.Join(p.config.branchesDir, "index.html")
49 content, err := fs.ReadFile(p.server.Webcontent(), path)
50 if errors.Is(err, fs.ErrNotExist) {
51 p.renderBranchesIndexInit(path)
52 } else {
53 p.renderBranchesIndexAppend(path, string(content))
54 }
55 for _, bc := range p.branchCommits {
56 p.renderBranchesCommits(bc)
57 }
58 return nil
59}
60
61func (p *Plugin) renderBranchesIndexInit(path string) {
62 branches := strings.Builder{}
63 branches.WriteString("<h1>Branches</h1><ul>")
64 for _, b := range p.branchCommits {
65 branches.WriteString(fmt.Sprintf("<li><a href=\"./%s.html\">%s</a></li>", b.branch, b.branch))
66 }
67 branches.WriteString("<!--NEXT--></ul>")
68 p.server.ModifyWebContent(path, p.renderHtml(path, branches.String()))
69}
70
71func (p *Plugin) renderBranchesIndexAppend(path string, content string) {
72 branches := strings.Builder{}
73 for _, b := range p.branchCommits {
74 if !strings.Contains(content, fmt.Sprintf("<li><a href=\"./%s.html\"", b.branch)) {
75 branches.WriteString(fmt.Sprintf("<li><a href=\"./%s.html\">%s</a></li>", b.branch, b.branch))
76 }
77 }
78 if branches.Len() > 0 {
79 branches.WriteString("<!--NEXT-->")
80 newContent := strings.Replace(content, "<!--NEXT-->", branches.String(), 1)
81 //TODO use replace of pollen
82 p.server.ModifyWebContent(path, newContent)
83 }
84}
85
86func (p *Plugin) parsePreviousCommits(bc *branchCommits, content string) {
87 splited := strings.Split(content, "\n")
88 slices.Reverse(splited)
89 for _, line := range splited {
90 if strings.Contains(line, "<li data-hash=") {
91 bc.commit.InsertLine(line)
92 }
93 }
94}
95
96func (p *Plugin) renderBranchesCommits(bc *branchCommits) {
97 pathBranch := filepath.Join(p.config.branchesDir, fmt.Sprintf("%s.html", bc.branch))
98
99 for _, mc := range bc.commit.hole() {
100 coms, err := p.server.Commits(mc[0], mc[1])
101 if err != nil {
102 p.server.LogError("can't get commits", err)
103 }
104 for _, com := range coms {
105 bc.commit.Insert(com)
106 }
107 }
108
109 newContent := p.renderHtml(pathBranch, fmt.Sprintf("<h1>Commits of branch %s</h1><ul>\n%s</ul>\n", bc.branch, bc.commit.Render()))
110 p.server.ModifyWebContent(pathBranch, newContent)
111}
112
113func (p *Plugin) renderHtml(fp string, htmlContent string) string {
114 menu := p.buildMenu(fp)
115 stylePath := relativePath(fp, p.config.style)
116 return fmt.Sprintf(simple, p.repoName, stylePath, p.config.header, menu, htmlContent, p.config.footer)
117}