mirror of
https://github.com/apricote/releaser-pleaser.git
synced 2026-01-13 13:21:00 +00:00
refactor: releasepr markdown handling (#42)
This commit is contained in:
parent
0750bd6b46
commit
36a0b90bcd
6 changed files with 466 additions and 83 deletions
|
|
@ -6,15 +6,10 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"regexp"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/yuin/goldmark/ast"
|
||||
"github.com/yuin/goldmark/text"
|
||||
|
||||
"github.com/apricote/releaser-pleaser/internal/git"
|
||||
"github.com/apricote/releaser-pleaser/internal/markdown"
|
||||
ast2 "github.com/apricote/releaser-pleaser/internal/markdown/extensions/ast"
|
||||
"github.com/apricote/releaser-pleaser/internal/versioning"
|
||||
)
|
||||
|
||||
|
|
@ -140,31 +135,11 @@ func (pr *ReleasePullRequest) parseVersioningFlags(overrides ReleaseOverrides) R
|
|||
|
||||
func (pr *ReleasePullRequest) parseDescription(overrides ReleaseOverrides) (ReleaseOverrides, error) {
|
||||
source := []byte(pr.Description)
|
||||
descriptionAST := markdown.New().Parser().Parse(text.NewReader(source))
|
||||
|
||||
err := ast.Walk(descriptionAST, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||
if !entering {
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
if n.Type() != ast.TypeBlock || n.Kind() != ast.KindFencedCodeBlock {
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
codeBlock, ok := n.(*ast.FencedCodeBlock)
|
||||
if !ok {
|
||||
return ast.WalkStop, fmt.Errorf("node has unexpected type: %T", n)
|
||||
}
|
||||
|
||||
switch string(codeBlock.Language(source)) {
|
||||
case DescriptionLanguagePrefix:
|
||||
overrides.Prefix = textFromLines(source, codeBlock)
|
||||
case DescriptionLanguageSuffix:
|
||||
overrides.Suffix = textFromLines(source, codeBlock)
|
||||
}
|
||||
|
||||
return ast.WalkContinue, nil
|
||||
})
|
||||
err := markdown.WalkAST(source,
|
||||
markdown.GetCodeBlockText(source, DescriptionLanguagePrefix, &overrides.Prefix),
|
||||
markdown.GetCodeBlockText(source, DescriptionLanguageSuffix, &overrides.Suffix),
|
||||
)
|
||||
if err != nil {
|
||||
return ReleaseOverrides{}, err
|
||||
}
|
||||
|
|
@ -174,59 +149,15 @@ func (pr *ReleasePullRequest) parseDescription(overrides ReleaseOverrides) (Rele
|
|||
|
||||
func (pr *ReleasePullRequest) ChangelogText() (string, error) {
|
||||
source := []byte(pr.Description)
|
||||
gm := markdown.New()
|
||||
descriptionAST := gm.Parser().Parse(text.NewReader(source))
|
||||
|
||||
var section *ast2.Section
|
||||
|
||||
err := ast.Walk(descriptionAST, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||
if !entering {
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
if n.Type() != ast.TypeBlock || n.Kind() != ast2.KindSection {
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
anySection, ok := n.(*ast2.Section)
|
||||
if !ok {
|
||||
return ast.WalkStop, fmt.Errorf("node has unexpected type: %T", n)
|
||||
}
|
||||
|
||||
if anySection.Name != MarkdownSectionChangelog {
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
section = anySection
|
||||
return ast.WalkStop, nil
|
||||
})
|
||||
var sectionText string
|
||||
err := markdown.WalkAST(source, markdown.GetSectionText(source, MarkdownSectionChangelog, §ionText))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if section == nil {
|
||||
return "", nil
|
||||
}
|
||||
return sectionText, nil
|
||||
|
||||
outputBuffer := new(bytes.Buffer)
|
||||
err = gm.Renderer().Render(outputBuffer, source, section)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return outputBuffer.String(), nil
|
||||
}
|
||||
|
||||
func textFromLines(source []byte, n ast.Node) string {
|
||||
content := make([]byte, 0)
|
||||
|
||||
l := n.Lines().Len()
|
||||
for i := 0; i < l; i++ {
|
||||
line := n.Lines().At(i)
|
||||
content = append(content, line.Value(source)...)
|
||||
}
|
||||
|
||||
return strings.TrimSpace(string(content))
|
||||
}
|
||||
|
||||
func (pr *ReleasePullRequest) SetTitle(branch, version string) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,121 @@
|
|||
package releasepr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/apricote/releaser-pleaser/internal/versioning"
|
||||
)
|
||||
|
||||
func TestReleasePullRequest_GetOverrides(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pr ReleasePullRequest
|
||||
want ReleaseOverrides
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
pr: ReleasePullRequest{},
|
||||
want: ReleaseOverrides{},
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
// TODO: Test for multiple version flags
|
||||
name: "single version flag",
|
||||
pr: ReleasePullRequest{
|
||||
Labels: []Label{LabelNextVersionTypeAlpha},
|
||||
},
|
||||
want: ReleaseOverrides{
|
||||
NextVersionType: versioning.NextVersionTypeAlpha,
|
||||
},
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "prefix in description",
|
||||
pr: ReleasePullRequest{
|
||||
Description: "```rp-prefix\n## Foo\n\n- Cool thing\n```",
|
||||
},
|
||||
want: ReleaseOverrides{Prefix: "## Foo\n\n- Cool thing"},
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "suffix in description",
|
||||
pr: ReleasePullRequest{
|
||||
Description: "```rp-suffix\n## Compatibility\n\nNo compatibility guarantees.\n```",
|
||||
},
|
||||
want: ReleaseOverrides{Suffix: "## Compatibility\n\nNo compatibility guarantees."},
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := tt.pr.GetOverrides()
|
||||
if !tt.wantErr(t, err, fmt.Sprintf("GetOverrides()")) {
|
||||
return
|
||||
}
|
||||
assert.Equalf(t, tt.want, got, "GetOverrides()")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReleasePullRequest_ChangelogText(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
description string
|
||||
want string
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "no section",
|
||||
description: "# Foo\n",
|
||||
want: "",
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "with section",
|
||||
description: `# Foobar
|
||||
|
||||
<!-- section-start changelog -->
|
||||
This is the changelog
|
||||
|
||||
## Awesome
|
||||
|
||||
### New
|
||||
|
||||
#### Changes
|
||||
<!-- section-end changelog -->
|
||||
|
||||
Suffix Things
|
||||
`,
|
||||
want: `This is the changelog
|
||||
|
||||
## Awesome
|
||||
|
||||
### New
|
||||
|
||||
#### Changes
|
||||
`,
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
pr := &ReleasePullRequest{
|
||||
Description: tt.description,
|
||||
}
|
||||
got, err := pr.ChangelogText()
|
||||
if !tt.wantErr(t, err, fmt.Sprintf("ChangelogText()")) {
|
||||
return
|
||||
}
|
||||
assert.Equalf(t, tt.want, got, "ChangelogText()")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReleasePullRequest_SetTitle(t *testing.T) {
|
||||
type args struct {
|
||||
branch string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue