changeloguru/pkg/changelog/markdown.go

127 lines
3.0 KiB
Go

package changelog
import (
"fmt"
"strings"
"time"
"github.com/haunt98/changeloguru/pkg/convention"
"github.com/haunt98/changeloguru/pkg/markdown"
)
const (
title = "CHANGELOG"
defaultNodesLen = 10
firstLevel = 1
secondLevel = 2
thirdLevel = 3
)
type MarkdownGenerator struct {
oldData string
version string
t time.Time
}
func NewMarkdownGenerator(oldData, version string, t time.Time) *MarkdownGenerator {
return &MarkdownGenerator{
oldData: oldData,
version: version,
t: t,
}
}
func (g *MarkdownGenerator) Generate(commits []convention.Commit) string {
newBases := g.getNewNodes(commits)
if len(newBases) == 0 {
return ""
}
nodes := make([]markdown.Node, 0, defaultNodesLen)
// title
nodes = append(nodes, markdown.NewHeader(firstLevel, title))
// version
nodes = append(nodes, markdown.NewHeader(secondLevel, g.getVersionHeader()))
// new
nodes = append(nodes, newBases...)
// old
oldNodes := g.getOldNodes()
nodes = append(nodes, oldNodes...)
return markdown.Generate(nodes)
}
func (g *MarkdownGenerator) getNewNodes(commits []convention.Commit) []markdown.Node {
if len(commits) == 0 {
return nil
}
result := make([]markdown.Node, 0, defaultNodesLen)
commitBases := make(map[string][]markdown.Node)
commitBases[addedType] = make([]markdown.Node, 0, defaultNodesLen)
commitBases[fixedType] = make([]markdown.Node, 0, defaultNodesLen)
commitBases[othersType] = make([]markdown.Node, 0, defaultNodesLen)
for _, commit := range commits {
t := getType(commit.GetType())
switch t {
case addedType:
commitBases[addedType] = append(commitBases[addedType], markdown.NewListItem(commit.String()))
case fixedType:
commitBases[fixedType] = append(commitBases[fixedType], markdown.NewListItem(commit.String()))
case othersType:
commitBases[othersType] = append(commitBases[othersType], markdown.NewListItem(commit.String()))
default:
continue
}
}
if len(commitBases[addedType]) != 0 {
result = append(result, markdown.NewHeader(thirdLevel, addedType))
result = append(result, commitBases[addedType]...)
}
if len(commitBases[fixedType]) != 0 {
result = append(result, markdown.NewHeader(thirdLevel, fixedType))
result = append(result, commitBases[fixedType]...)
}
if len(commitBases[othersType]) != 0 {
result = append(result, markdown.NewHeader(thirdLevel, othersType))
result = append(result, commitBases[othersType]...)
}
return result
}
func (g *MarkdownGenerator) getOldNodes() []markdown.Node {
if g.oldData == "" {
return nil
}
result := make([]markdown.Node, 0, defaultNodesLen)
lines := strings.Split(g.oldData, string(markdown.NewlineToken))
result = append(result, markdown.Parse(lines)...)
// remove title as we will add later
if len(result) > 0 && markdown.Equal(result[0], markdown.NewHeader(firstLevel, title)) {
result = result[1:]
}
return result
}
func (g *MarkdownGenerator) getVersionHeader() string {
year, month, day := g.t.Date()
return fmt.Sprintf("%s (%d-%d-%d)", g.version, year, month, day)
}