parent
dd2bf81ff8
commit
5a887cd08f
1
go.mod
1
go.mod
|
@ -9,6 +9,7 @@ require (
|
|||
github.com/google/go-cmp v0.5.5 // indirect
|
||||
github.com/haunt98/clock v0.1.0
|
||||
github.com/haunt98/color v0.1.0
|
||||
github.com/haunt98/markdown-go v0.1.0
|
||||
github.com/kevinburke/ssh_config v1.1.0 // indirect
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -39,6 +39,8 @@ github.com/haunt98/clock v0.1.0 h1:iRaGSoQ21Z+gD9J4mVoYqL4liAg5eGwPkkPGknmfV6A=
|
|||
github.com/haunt98/clock v0.1.0/go.mod h1:Sq2/R7IgMjxnqgCF3f69ROb8ZeF9PO0YaQW1p3wXGiE=
|
||||
github.com/haunt98/color v0.1.0 h1:qfP5oNI3aoUC8T+bH/JNVAg79ljyhTGpgfqSKWhkiQQ=
|
||||
github.com/haunt98/color v0.1.0/go.mod h1:V4BPVUSuiOItuVZHRHUTkpxO7OYQiP0DSgIWMpC/2qs=
|
||||
github.com/haunt98/markdown-go v0.1.0 h1:Yg98g9F8NtLfZwFOlBtJRu1VWhDbJbPC8LjLgD70WSc=
|
||||
github.com/haunt98/markdown-go v0.1.0/go.mod h1:E18hIq5n6hy+aQ+U6o+MuMJdZoq7/5n50FG+JsjuFIs=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/haunt98/changeloguru/internal/convention"
|
||||
"github.com/haunt98/changeloguru/internal/markdown"
|
||||
"github.com/haunt98/clock"
|
||||
"github.com/haunt98/markdown-go"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/haunt98/changeloguru/internal/convention"
|
||||
"github.com/haunt98/changeloguru/internal/markdown"
|
||||
"github.com/haunt98/markdown-go"
|
||||
"github.com/sebdah/goldie/v2"
|
||||
)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/haunt98/changeloguru/internal/changelog"
|
||||
"github.com/haunt98/changeloguru/internal/convention"
|
||||
"github.com/haunt98/changeloguru/internal/git"
|
||||
"github.com/haunt98/changeloguru/internal/markdown"
|
||||
"github.com/haunt98/markdown-go"
|
||||
"github.com/pkg/diff"
|
||||
"github.com/pkg/diff/write"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
package markdown
|
||||
|
||||
import "strings"
|
||||
|
||||
// GenerateText return single string which represents all markdown nodes
|
||||
func GenerateText(bases []Node) string {
|
||||
lines := make([]string, len(bases))
|
||||
for i, base := range bases {
|
||||
lines[i] = base.String()
|
||||
}
|
||||
|
||||
result := strings.Join(lines, string(NewlineToken)+string(NewlineToken))
|
||||
// Fix no newline at end of file
|
||||
result += string(NewlineToken)
|
||||
return result
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package markdown
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGenerate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
bases []Node
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "normal",
|
||||
bases: []Node{
|
||||
header{
|
||||
level: 1,
|
||||
text: "header",
|
||||
},
|
||||
listItem{
|
||||
text: "item 1",
|
||||
},
|
||||
listItem{
|
||||
text: "item 2",
|
||||
},
|
||||
},
|
||||
want: "# header\n\n- item 1\n\n- item 2\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := GenerateText(tc.bases)
|
||||
assert.Equal(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
package markdown
|
||||
|
||||
import "strings"
|
||||
|
||||
// https://guides.github.com/features/mastering-markdown/
|
||||
|
||||
const (
|
||||
headerToken = '#'
|
||||
defaultListToken = '-'
|
||||
alternativeListToken = '*'
|
||||
|
||||
spaceToken = ' '
|
||||
NewlineToken = '\n'
|
||||
)
|
||||
|
||||
// Node is single markdown syntax representation
|
||||
// Example: header, list, ...
|
||||
type Node interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
type header struct {
|
||||
level int
|
||||
text string
|
||||
}
|
||||
|
||||
func NewHeader(level int, text string) Node {
|
||||
return header{
|
||||
level: level,
|
||||
text: text,
|
||||
}
|
||||
}
|
||||
|
||||
func (h header) String() string {
|
||||
var builder strings.Builder
|
||||
|
||||
for i := 0; i < h.level; i++ {
|
||||
builder.WriteString(string(headerToken))
|
||||
}
|
||||
|
||||
builder.WriteString(string(spaceToken))
|
||||
|
||||
text := strings.TrimSpace(h.text)
|
||||
builder.WriteString(text)
|
||||
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
type listItem struct {
|
||||
text string
|
||||
}
|
||||
|
||||
func NewListItem(text string) Node {
|
||||
return listItem{
|
||||
text: text,
|
||||
}
|
||||
}
|
||||
|
||||
func (i listItem) String() string {
|
||||
text := strings.TrimSpace(i.text)
|
||||
|
||||
return string(defaultListToken) + string(spaceToken) + text
|
||||
}
|
||||
|
||||
func Equal(base1, base2 Node) bool {
|
||||
return base1.String() == base2.String()
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
package markdown
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestHeaderString(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
header header
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "level 1",
|
||||
header: header{
|
||||
level: 1,
|
||||
text: "abc",
|
||||
},
|
||||
want: "# abc",
|
||||
},
|
||||
{
|
||||
name: "level 3",
|
||||
header: header{
|
||||
level: 3,
|
||||
text: "xyz",
|
||||
},
|
||||
want: "### xyz",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := tc.header.String()
|
||||
assert.Equal(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListItemString(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
listItem listItem
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "normal",
|
||||
listItem: listItem{
|
||||
text: "abc",
|
||||
},
|
||||
want: "- abc",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := tc.listItem.String()
|
||||
assert.Equal(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
package markdown
|
||||
|
||||
import "strings"
|
||||
|
||||
const (
|
||||
defaultBaseLen = 10
|
||||
)
|
||||
|
||||
// Parse return all markdown nodes from lines
|
||||
func Parse(lines []string) []Node {
|
||||
if len(lines) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
bases := make([]Node, 0, defaultBaseLen)
|
||||
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(line, string(headerToken)) {
|
||||
bases = append(bases, parseHeader(line))
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(line, string(defaultListToken)) ||
|
||||
strings.HasPrefix(line, string(alternativeListToken)) {
|
||||
bases = append(bases, parseListItem(line))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return bases
|
||||
}
|
||||
|
||||
func parseHeader(line string) header {
|
||||
level := 0
|
||||
|
||||
for _, c := range line {
|
||||
if c != headerToken {
|
||||
break
|
||||
}
|
||||
|
||||
level++
|
||||
}
|
||||
|
||||
line = strings.TrimLeft(line, string(headerToken))
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
return header{
|
||||
level: level,
|
||||
text: line,
|
||||
}
|
||||
}
|
||||
|
||||
func parseListItem(line string) listItem {
|
||||
line = strings.TrimLeft(line, string(defaultListToken))
|
||||
line = strings.TrimLeft(line, string(alternativeListToken))
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
return listItem{
|
||||
text: line,
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
package markdown
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
lines []string
|
||||
want []Node
|
||||
}{
|
||||
{
|
||||
name: "level 1",
|
||||
lines: []string{
|
||||
"# abc",
|
||||
"- xyz",
|
||||
},
|
||||
want: []Node{
|
||||
header{
|
||||
level: 1,
|
||||
text: "abc",
|
||||
},
|
||||
listItem{
|
||||
text: "xyz",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "level 3 with alternative",
|
||||
lines: []string{
|
||||
"### xyz",
|
||||
"* abc",
|
||||
},
|
||||
want: []Node{
|
||||
header{
|
||||
level: 3,
|
||||
text: "xyz",
|
||||
},
|
||||
listItem{
|
||||
text: "abc",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := Parse(tc.lines)
|
||||
assert.Equal(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseHeader(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
line string
|
||||
want header
|
||||
}{
|
||||
{
|
||||
name: "level 1",
|
||||
line: "# abc",
|
||||
want: header{
|
||||
level: 1,
|
||||
text: "abc",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "level 3",
|
||||
line: "### xyz",
|
||||
want: header{
|
||||
level: 3,
|
||||
text: "xyz",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := parseHeader(tc.line)
|
||||
assert.Equal(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseListItem(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
line string
|
||||
want listItem
|
||||
}{
|
||||
{
|
||||
name: "normal",
|
||||
line: "- abc",
|
||||
want: listItem{
|
||||
text: "abc",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "alternative",
|
||||
line: "* xyz",
|
||||
want: listItem{
|
||||
text: "xyz",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := parseListItem(tc.line)
|
||||
assert.Equal(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue