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}