Skip to content

Commit

Permalink
feat: split-up logic in multiple files
Browse files Browse the repository at this point in the history
  • Loading branch information
christophwitzko committed Feb 17, 2024
1 parent 2967329 commit 3843c1a
Show file tree
Hide file tree
Showing 8 changed files with 340 additions and 99 deletions.
25 changes: 25 additions & 0 deletions pkg/analyzer/commit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package analyzer

import "strings"

type parsedCommit struct {
Type string
Scope string
Modifier string
Message string
}

func parseCommit(msg string) *parsedCommit {
found := commitPattern.FindAllStringSubmatch(msg, -1)
if len(found) < 1 {
// commit message does not match pattern
return nil
}

return &parsedCommit{
Type: strings.ToLower(found[0][1]),
Scope: found[0][2],
Modifier: found[0][3],
Message: found[0][4],
}
}
46 changes: 14 additions & 32 deletions pkg/analyzer/commit_analyzer.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
package analyzer

import (
"regexp"
"strings"

"github.com/go-semantic-release/semantic-release/v2/pkg/semrel"
)

var (
CAVERSION = "dev"
commitPattern = regexp.MustCompile(`^([^\s\(\!]+)(?:\(([^\)]*)\))?(\!)?\: (.*)$`)
breakingPattern = regexp.MustCompile("BREAKING CHANGES?")
mentionedIssuesPattern = regexp.MustCompile(`#(\d+)`)
mentionedUsersPattern = regexp.MustCompile(`(?i)@([a-z\d]([a-z\d]|-[a-z\d])+)`)
)
var CAVERSION = "dev"

func extractMentions(re *regexp.Regexp, s string) string {
ret := make([]string, 0)
for _, m := range re.FindAllStringSubmatch(s, -1) {
ret = append(ret, m[1])
}
return strings.Join(ret, ",")
type DefaultCommitAnalyzer struct{}

func (da *DefaultCommitAnalyzer) Init(m map[string]string) error {
// TODO: implement config parsing
return nil
}

func (da *DefaultCommitAnalyzer) Name() string {
return "default"
}

func matchesBreakingPattern(c *semrel.Commit) bool {
return breakingPattern.MatchString(strings.Join(c.Raw, "\n"))
func (da *DefaultCommitAnalyzer) Version() string {
return CAVERSION
}

func setTypeAndChange(c *semrel.Commit) {
func (da *DefaultCommitAnalyzer) setTypeAndChange(c *semrel.Commit) {
found := commitPattern.FindAllStringSubmatch(c.Raw[0], -1)
if len(found) < 1 {
// commit message does not match pattern
Expand All @@ -46,20 +42,6 @@ func setTypeAndChange(c *semrel.Commit) {
}
}

type DefaultCommitAnalyzer struct{}

func (da *DefaultCommitAnalyzer) Init(_ map[string]string) error {
return nil
}

func (da *DefaultCommitAnalyzer) Name() string {
return "default"
}

func (da *DefaultCommitAnalyzer) Version() string {
return CAVERSION
}

func (da *DefaultCommitAnalyzer) analyzeSingleCommit(rawCommit *semrel.RawCommit) *semrel.Commit {
c := &semrel.Commit{
SHA: rawCommit.SHA,
Expand All @@ -70,7 +52,7 @@ func (da *DefaultCommitAnalyzer) analyzeSingleCommit(rawCommit *semrel.RawCommit
c.Annotations["mentioned_issues"] = extractMentions(mentionedIssuesPattern, rawCommit.RawMessage)
c.Annotations["mentioned_users"] = extractMentions(mentionedUsersPattern, rawCommit.RawMessage)

setTypeAndChange(c)
da.setTypeAndChange(c)
return c
}

Expand Down
68 changes: 1 addition & 67 deletions pkg/analyzer/commit_analyzer_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package analyzer

import (
"fmt"
"strings"
"testing"

Expand Down Expand Up @@ -101,7 +100,7 @@ func TestDefaultAnalyzer(t *testing.T) {

defaultAnalyzer := &DefaultCommitAnalyzer{}
for _, tc := range testCases {
t.Run(fmt.Sprintf("AnalyzeCommitMessage: %s", tc.RawCommit.RawMessage), func(t *testing.T) {
t.Run(tc.RawCommit.RawMessage, func(t *testing.T) {
analyzedCommit := defaultAnalyzer.analyzeSingleCommit(tc.RawCommit)
require.Equal(t, tc.Type, analyzedCommit.Type, "Type")
require.Equal(t, tc.Scope, analyzedCommit.Scope, "Scope")
Expand All @@ -111,68 +110,3 @@ func TestDefaultAnalyzer(t *testing.T) {
})
}
}

func TestCommitPattern(t *testing.T) {
testCases := []struct {
message string
wanted []string
}{
{
message: "feat: new feature",
wanted: []string{"feat", "", "", "new feature"},
},
{
message: "feat!: new feature",
wanted: []string{"feat", "", "!", "new feature"},
},
{
message: "feat(api): new feature",
wanted: []string{"feat", "api", "", "new feature"},
},
{
message: "feat(api): a(b): c:",
wanted: []string{"feat", "api", "", "a(b): c:"},
},
{
message: "feat(new cool-api): feature",
wanted: []string{"feat", "new cool-api", "", "feature"},
},
{
message: "feat(😅): cool",
wanted: []string{"feat", "😅", "", "cool"},
},
{
message: "this-is-also(valid): cool",
wanted: []string{"this-is-also", "valid", "", "cool"},
},
{
message: "🚀(🦄): emojis!",
wanted: []string{"🚀", "🦄", "", "emojis!"},
},
// invalid messages
{
message: "feat (new api): feature",
wanted: nil,
},
{
message: "feat((x)): test",
wanted: nil,
},
{
message: "feat:test",
wanted: nil,
},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("CommitPattern: %s", tc.message), func(t *testing.T) {
found := commitPattern.FindAllStringSubmatch(tc.message, -1)
if len(tc.wanted) == 0 {
require.Len(t, found, 0)
return
}
require.Len(t, found, 1)
require.Len(t, found[0], 5)
require.Equal(t, tc.wanted, found[0][1:])
})
}
}
82 changes: 82 additions & 0 deletions pkg/analyzer/commit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package analyzer

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestParseCommit(t *testing.T) {
testCases := []struct {
message string
wanted *parsedCommit
}{
{
message: "feat: new feature",
wanted: &parsedCommit{"feat", "", "", "new feature"},
},
{
message: "feat!: new feature",
wanted: &parsedCommit{"feat", "", "!", "new feature"},
},
{
message: "feat(api): new feature",
wanted: &parsedCommit{"feat", "api", "", "new feature"},
},
{
message: "feat(api): a(b): c:",
wanted: &parsedCommit{"feat", "api", "", "a(b): c:"},
},
{
message: "feat(new cool-api): feature",
wanted: &parsedCommit{"feat", "new cool-api", "", "feature"},
},
{
message: "feat(😅): cool",
wanted: &parsedCommit{"feat", "😅", "", "cool"},
},
{
message: "this-is-also(valid): cool",
wanted: &parsedCommit{"this-is-also", "valid", "", "cool"},
},
{
message: "feat((x)): test",
wanted: &parsedCommit{"feat", "(x", ")", "test"},
},
{
message: "feat(x)?!: test",
wanted: &parsedCommit{"feat", "x", "?!", "test"},
},
{
message: "feat(x): test",
wanted: &parsedCommit{"feat", "x", "", "test"},
},
{
message: "feat(x): : test",
wanted: &parsedCommit{"feat", "x", "", ": test"},
},
{
message: "feat!: test",
wanted: &parsedCommit{"feat", "", "!", "test"},
},
// invalid messages
{
message: "feat (new api): feature",
wanted: nil,
},
{
message: "feat:test",
wanted: nil,
},
{
message: "🚀(🦄): emojis!",
wanted: nil,
},
}
for _, tc := range testCases {
t.Run(tc.message, func(t *testing.T) {
c := parseCommit(tc.message)
require.Equal(t, tc.wanted, c)
})
}
}
28 changes: 28 additions & 0 deletions pkg/analyzer/patterns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package analyzer

import (
"regexp"
"strings"

"github.com/go-semantic-release/semantic-release/v2/pkg/semrel"
)

var (
releaseRulePattern = regexp.MustCompile(`^([\w-\*]+)(?:\(([^\)]*)\))?(\S*)$`)
commitPattern = regexp.MustCompile(`^([\w-]+)(?:\(([^\)]*)\))?(\S*)\: (.*)$`)
breakingPattern = regexp.MustCompile("BREAKING CHANGES?")
mentionedIssuesPattern = regexp.MustCompile(`#(\d+)`)
mentionedUsersPattern = regexp.MustCompile(`(?i)@([a-z\d]([a-z\d]|-[a-z\d])+)`)
)

func extractMentions(re *regexp.Regexp, s string) string {
ret := make([]string, 0)
for _, m := range re.FindAllStringSubmatch(s, -1) {
ret = append(ret, m[1])
}
return strings.Join(ret, ",")
}

func matchesBreakingPattern(c *semrel.Commit) bool {
return breakingPattern.MatchString(strings.Join(c.Raw, "\n"))
}
51 changes: 51 additions & 0 deletions pkg/analyzer/patterns_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package analyzer

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestExtractIssues(t *testing.T) {
testCases := []struct {
message string
wanted string
}{
{
message: "feat: new feature #123",
wanted: "123",
},
{
message: "feat!: new feature closes #123 and #456",
wanted: "123,456",
},
}
for _, testCase := range testCases {
t.Run(testCase.message, func(t *testing.T) {
issues := extractMentions(mentionedIssuesPattern, testCase.message)
require.Equal(t, testCase.wanted, issues)
})
}
}

func TestExtractMentions(t *testing.T) {
testCases := []struct {
message string
wanted string
}{
{
message: "feat: new feature by @user",
wanted: "user",
},
{
message: "feat!: new feature by @user and @user-2",
wanted: "user,user-2",
},
}
for _, testCase := range testCases {
t.Run(testCase.message, func(t *testing.T) {
issues := extractMentions(mentionedUsersPattern, testCase.message)
require.Equal(t, testCase.wanted, issues)
})
}
}
Loading

0 comments on commit 3843c1a

Please sign in to comment.