releaser-pleaser/releasepr.go

139 lines
3.2 KiB
Go

package rp
import (
"fmt"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/text"
)
type ReleasePullRequest struct {
ID int
Title string
Description string
Labels []string
}
type ReleaseOverrides struct {
Prefix string
Suffix string
// TODO: Doing the changelog for normal releases after previews requires to know about this while fetching the changesets
NextVersionType NextVersionType
}
type NextVersionType int
const (
NextVersionTypeUndefined NextVersionType = iota
NextVersionTypeNormal
NextVersionTypeRC
NextVersionTypeBeta
NextVersionTypeAlpha
)
func (n NextVersionType) String() string {
switch n {
case NextVersionTypeUndefined:
return "undefined"
case NextVersionTypeNormal:
return "normal"
case NextVersionTypeRC:
return "rc"
case NextVersionTypeBeta:
return "beta"
case NextVersionTypeAlpha:
return "alpha"
default:
return ""
}
}
// PR Labels
const (
LabelNextVersionTypeNormal = "rp-next-version::normal"
LabelNextVersionTypeRC = "rp-next-version::rc"
LabelNextVersionTypeBeta = "rp-next-version::beta"
LabelNextVersionTypeAlpha = "rp-next-version::alpha"
)
const (
DescriptionLanguagePrefix = "rp-prefix"
DescriptionLanguageSuffix = "rp-suffix"
)
func (pr *ReleasePullRequest) GetOverrides() (ReleaseOverrides, error) {
overrides := ReleaseOverrides{}
overrides = pr.parseVersioningFlags(overrides)
overrides, err := pr.parseDescription(overrides)
if err != nil {
return ReleaseOverrides{}, err
}
return overrides, nil
}
func (pr *ReleasePullRequest) parseVersioningFlags(overrides ReleaseOverrides) ReleaseOverrides {
for _, label := range pr.Labels {
switch label {
// Versioning
case LabelNextVersionTypeNormal:
overrides.NextVersionType = NextVersionTypeNormal
case LabelNextVersionTypeRC:
overrides.NextVersionType = NextVersionTypeRC
case LabelNextVersionTypeBeta:
overrides.NextVersionType = NextVersionTypeBeta
case LabelNextVersionTypeAlpha:
overrides.NextVersionType = NextVersionTypeAlpha
}
}
return overrides
}
func (pr *ReleasePullRequest) parseDescription(overrides ReleaseOverrides) (ReleaseOverrides, error) {
source := []byte(pr.Description)
descriptionAST := parser.NewParser().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
})
if err != nil {
return ReleaseOverrides{}, err
}
return overrides, 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 string(content)
}