feat(analyzer): update AnalyzedCommit to add flexibility in parsing a message

This provides flexibility of parsing and rendering structured messages
with more detail in the changelog and helps extract metadata from the 
message. The new structure can be used to split a message in multiple 
blocks (e.g. footer)
This commit is contained in:
maulik13
2021-02-16 15:25:34 +01:00
committed by Felix Wiedmann
parent 81bdb68ee4
commit dc4d1c581a
13 changed files with 284 additions and 41 deletions

View File

@@ -3,6 +3,8 @@ package analyzer
import (
"fmt"
"regexp"
"strings"
"github.com/Nightapes/go-semantic-release/internal/shared"
"github.com/Nightapes/go-semantic-release/pkg/config"
@@ -11,8 +13,9 @@ import (
// Analyzer struct
type Analyzer struct {
analyzeCommits analyzeCommits
Config config.ChangelogConfig
analyzeCommits analyzeCommits
ChangelogConfig config.ChangelogConfig
AnalyzerConfig config.AnalyzerConfig
}
// Rule for commits
@@ -24,14 +27,15 @@ type Rule struct {
}
type analyzeCommits interface {
analyze(commit shared.Commit, tag Rule) (*shared.AnalyzedCommit, bool)
analyze(commit shared.Commit, tag Rule) *shared.AnalyzedCommit
getRules() []Rule
}
// New Analyzer struct for given commit format
func New(format string, config config.ChangelogConfig) (*Analyzer, error) {
func New(format string, analyzerConfig config.AnalyzerConfig, chglogConfig config.ChangelogConfig) (*Analyzer, error) {
analyzer := &Analyzer{
Config: config,
AnalyzerConfig: analyzerConfig,
ChangelogConfig: chglogConfig,
}
switch format {
@@ -39,7 +43,7 @@ func New(format string, config config.ChangelogConfig) (*Analyzer, error) {
analyzer.analyzeCommits = newAngular()
log.Debugf("Commit format set to %s", ANGULAR)
case CONVENTIONAL:
analyzer.analyzeCommits = newConventional()
analyzer.analyzeCommits = newConventional(analyzerConfig)
log.Debugf("Commit format set to %s", CONVENTIONAL)
default:
return nil, fmt.Errorf("invalid commit format: %s", format)
@@ -62,14 +66,14 @@ func (a *Analyzer) Analyze(commits []shared.Commit) map[shared.Release][]shared.
for _, commit := range commits {
for _, rule := range a.analyzeCommits.getRules() {
analyzedCommit, hasBreakingChange := a.analyzeCommits.analyze(commit, rule)
analyzedCommit := a.analyzeCommits.analyze(commit, rule)
if analyzedCommit == nil {
continue
}
if a.Config.PrintAll || rule.Changelog {
if a.ChangelogConfig.PrintAll || rule.Changelog {
analyzedCommit.Print = true
}
if hasBreakingChange {
if analyzedCommit.IsBreaking {
analyzedCommits["major"] = append(analyzedCommits["major"], *analyzedCommit)
break
}
@@ -80,3 +84,52 @@ func (a *Analyzer) Analyze(commits []shared.Commit) map[shared.Release][]shared.
log.Debugf("Analyzed commits: major=%d minor=%d patch=%d none=%d", len(analyzedCommits["major"]), len(analyzedCommits["minor"]), len(analyzedCommits["patch"]), len(analyzedCommits["none"]))
return analyzedCommits
}
func getMessageParts(msg string) (header string, bodyBlocks []string){
firstSplit := strings.SplitN(msg, "\n", 2)
header = firstSplit[0]
bodyBlocks = make([]string, 0)
if len(firstSplit) < 2 {
return
}
// Trim and then split by a blank line
remaining := strings.Trim(firstSplit[1], "\n")
bodyBlocks = strings.Split(remaining, "\n\n")
return
}
func parseMessageBlock(msg string, prefixes []string) shared.MessageBlock {
for _, prefix := range prefixes {
if !strings.HasPrefix(msg, prefix + ":") {
continue
}
content := strings.Replace(msg, prefix+":", "", 1)
return shared.MessageBlock{
Label: prefix,
Content: strings.TrimSpace(content),
}
}
return shared.MessageBlock{
Label: "",
Content: msg,
}
}
//
// getRegexMatchedMap will match a regex with named groups and map the matching
// results to corresponding group names
//
func getRegexMatchedMap(regEx, url string) (paramsMap map[string]string) {
var compRegEx = regexp.MustCompile(regEx)
match := compRegEx.FindStringSubmatch(url)
paramsMap = make(map[string]string)
for i, name := range compRegEx.SubexpNames() {
if i > 0 && i <= len(match) {
paramsMap[name] = match[i]
}
}
return paramsMap
}