From 3b0c098b16fb7e93b79c5cb259fbcc3725e9bb7b Mon Sep 17 00:00:00 2001 From: Christoph Witzko <github@christophwitzko.com> Date: Tue, 4 Aug 2020 11:32:34 +0200 Subject: [PATCH] refactor: extract commit analyzer --- cmd/semantic-release/main.go | 6 +++- pkg/analyzer/commit/commit.go | 44 ++++++++++++++++++++++++++ pkg/analyzer/commit/commit_test.go | 51 ++++++++++++++++++++++++++++++ pkg/provider/github/github.go | 9 ++++-- pkg/provider/github/github_test.go | 21 ++---------- pkg/provider/gitlab/gitlab.go | 9 ++++-- pkg/provider/gitlab/gitlab_test.go | 21 ++---------- pkg/provider/repository.go | 2 +- pkg/semrel/commit.go | 30 +++--------------- 9 files changed, 123 insertions(+), 70 deletions(-) create mode 100644 pkg/analyzer/commit/commit.go create mode 100644 pkg/analyzer/commit/commit_test.go diff --git a/cmd/semantic-release/main.go b/cmd/semantic-release/main.go index 85d63e2..daa5a9f 100644 --- a/cmd/semantic-release/main.go +++ b/cmd/semantic-release/main.go @@ -9,6 +9,7 @@ import ( "regexp" "strings" + "github.com/go-semantic-release/semantic-release/pkg/analyzer/commit" "github.com/go-semantic-release/semantic-release/pkg/condition" "github.com/go-semantic-release/semantic-release/pkg/config" "github.com/go-semantic-release/semantic-release/pkg/generator/changelog" @@ -128,9 +129,12 @@ func cliHandler(c *cli.Context) error { } logger.Println("getting commits...") - commits, err := repo.GetCommits(currentSha) + rawCommits, err := repo.GetCommits(currentSha) exitIfError(err) + commitAnalyzer := &commit.DefaultAnalyzer{} + commits := commitAnalyzer.Analyze(rawCommits) + logger.Println("calculating new version...") newVer := semrel.GetNewVersion(conf, commits, release) if newVer == nil { diff --git a/pkg/analyzer/commit/commit.go b/pkg/analyzer/commit/commit.go new file mode 100644 index 0000000..9f58f96 --- /dev/null +++ b/pkg/analyzer/commit/commit.go @@ -0,0 +1,44 @@ +package commit + +import ( + "regexp" + "strings" + + "github.com/go-semantic-release/semantic-release/pkg/semrel" +) + +type Analyzer interface { + Analyze([]*semrel.RawCommit) []*semrel.Commit +} + +var commitPattern = regexp.MustCompile(`^(\w*)(?:\((.*)\))?\: (.*)$`) +var breakingPattern = regexp.MustCompile("BREAKING CHANGES?") + +type DefaultAnalyzer struct{} + +func (da *DefaultAnalyzer) analyzeSingleCommit(rawCommit *semrel.RawCommit) *semrel.Commit { + c := new(semrel.Commit) + c.SHA = rawCommit.SHA + c.Raw = strings.Split(rawCommit.RawMessage, "\n") + found := commitPattern.FindAllStringSubmatch(c.Raw[0], -1) + if len(found) < 1 { + return c + } + c.Type = strings.ToLower(found[0][1]) + c.Scope = found[0][2] + c.Message = found[0][3] + c.Change = semrel.Change{ + Major: breakingPattern.MatchString(rawCommit.RawMessage), + Minor: c.Type == "feat", + Patch: c.Type == "fix", + } + return c +} + +func (da *DefaultAnalyzer) Analyze(rawCommits []*semrel.RawCommit) []*semrel.Commit { + ret := make([]*semrel.Commit, len(rawCommits)) + for i, c := range rawCommits { + ret[i] = da.analyzeSingleCommit(c) + } + return ret +} diff --git a/pkg/analyzer/commit/commit_test.go b/pkg/analyzer/commit/commit_test.go new file mode 100644 index 0000000..c776ee0 --- /dev/null +++ b/pkg/analyzer/commit/commit_test.go @@ -0,0 +1,51 @@ +package commit + +import ( + "fmt" + "testing" + + "github.com/go-semantic-release/semantic-release/pkg/semrel" + "github.com/stretchr/testify/require" +) + +func compareCommit(c *semrel.Commit, t, s string, change semrel.Change) bool { + if c.Type != t || c.Scope != s { + return false + } + if c.Change.Major != change.Major || + c.Change.Minor != change.Minor || + c.Change.Patch != change.Patch { + return false + } + return true +} + +func createRawCommit(sha, message string) *semrel.RawCommit { + return &semrel.RawCommit{ + SHA: sha, + RawMessage: message, + } +} + +func TestDefaultAnalyzer(t *testing.T) { + testCases := []struct { + RawCommit *semrel.RawCommit + Type string + Scope string + Change semrel.Change + }{ + { + createRawCommit("a", "feat: new feature"), + "feat", + "", + semrel.Change{Major: false, Minor: true, Patch: false}, + }, + } + + defaultAnalyzer := &DefaultAnalyzer{} + for _, tc := range testCases { + t.Run(fmt.Sprintf("AnalyzeCommitMessage: %s", tc.RawCommit.RawMessage), func(t *testing.T) { + require.True(t, compareCommit(defaultAnalyzer.analyzeSingleCommit(tc.RawCommit), tc.Type, tc.Scope, tc.Change)) + }) + } +} diff --git a/pkg/provider/github/github.go b/pkg/provider/github/github.go index 8755488..c53120c 100644 --- a/pkg/provider/github/github.go +++ b/pkg/provider/github/github.go @@ -57,7 +57,7 @@ func (repo *GitHubRepository) GetInfo() (*provider.RepositoryInfo, error) { }, nil } -func (repo *GitHubRepository) GetCommits(sha string) ([]*semrel.Commit, error) { +func (repo *GitHubRepository) GetCommits(sha string) ([]*semrel.RawCommit, error) { opts := &github.CommitsListOptions{ SHA: sha, ListOptions: github.ListOptions{PerPage: 100}, @@ -66,9 +66,12 @@ func (repo *GitHubRepository) GetCommits(sha string) ([]*semrel.Commit, error) { if err != nil { return nil, err } - ret := make([]*semrel.Commit, len(commits)) + ret := make([]*semrel.RawCommit, len(commits)) for i, commit := range commits { - ret[i] = semrel.NewCommit(commit.GetSHA(), commit.Commit.GetMessage()) + ret[i] = &semrel.RawCommit{ + SHA: commit.GetSHA(), + RawMessage: commit.Commit.GetMessage(), + } } return ret, nil } diff --git a/pkg/provider/github/github_test.go b/pkg/provider/github/github_test.go index cc53286..99a33a2 100644 --- a/pkg/provider/github/github_test.go +++ b/pkg/provider/github/github_test.go @@ -12,7 +12,6 @@ import ( "github.com/Masterminds/semver" "github.com/go-semantic-release/semantic-release/pkg/provider" - "github.com/go-semantic-release/semantic-release/pkg/semrel" "github.com/google/go-github/v30/github" "github.com/stretchr/testify/require" ) @@ -136,18 +135,6 @@ func TestGithubGetInfo(t *testing.T) { require.True(t, repoInfo.Private) } -func compareCommit(c *semrel.Commit, t, s string, change semrel.Change) bool { - if c.Type != t || c.Scope != s { - return false - } - if c.Change.Major != change.Major || - c.Change.Minor != change.Minor || - c.Change.Patch != change.Patch { - return false - } - return true -} - func TestGithubGetCommits(t *testing.T) { repo, ts := getNewGithubTestRepo(t) defer ts.Close() @@ -155,11 +142,9 @@ func TestGithubGetCommits(t *testing.T) { require.NoError(t, err) require.Len(t, commits, 4) - if !compareCommit(commits[0], "feat", "app", semrel.Change{Major: false, Minor: true, Patch: false}) || - !compareCommit(commits[1], "fix", "", semrel.Change{Major: false, Minor: false, Patch: true}) || - !compareCommit(commits[2], "", "", semrel.Change{Major: false, Minor: false, Patch: false}) || - !compareCommit(commits[3], "chore", "", semrel.Change{Major: true, Minor: false, Patch: false}) { - t.Fatal("invalid commits") + for i, c := range commits { + require.Equal(t, c.SHA, GITHUB_COMMITS[i].GetSHA()) + require.Equal(t, c.RawMessage, GITHUB_COMMITS[i].Commit.GetMessage()) } } diff --git a/pkg/provider/gitlab/gitlab.go b/pkg/provider/gitlab/gitlab.go index 89df154..9f3c7a4 100644 --- a/pkg/provider/gitlab/gitlab.go +++ b/pkg/provider/gitlab/gitlab.go @@ -62,7 +62,7 @@ func (repo *GitLabRepository) GetInfo() (*provider.RepositoryInfo, error) { }, nil } -func (repo *GitLabRepository) GetCommits(sha string) ([]*semrel.Commit, error) { +func (repo *GitLabRepository) GetCommits(sha string) ([]*semrel.RawCommit, error) { opts := &gitlab.ListCommitsOptions{ ListOptions: gitlab.ListOptions{ Page: 1, @@ -72,7 +72,7 @@ func (repo *GitLabRepository) GetCommits(sha string) ([]*semrel.Commit, error) { All: gitlab.Bool(true), } - allCommits := make([]*semrel.Commit, 0) + allCommits := make([]*semrel.RawCommit, 0) for { commits, resp, err := repo.client.Commits.ListCommits(repo.projectID, opts) @@ -82,7 +82,10 @@ func (repo *GitLabRepository) GetCommits(sha string) ([]*semrel.Commit, error) { } for _, commit := range commits { - allCommits = append(allCommits, semrel.NewCommit(commit.ID, commit.Message)) + allCommits = append(allCommits, &semrel.RawCommit{ + SHA: commit.ID, + RawMessage: commit.Message, + }) } if resp.CurrentPage >= resp.TotalPages { diff --git a/pkg/provider/gitlab/gitlab_test.go b/pkg/provider/gitlab/gitlab_test.go index 7ad9a5f..b953565 100644 --- a/pkg/provider/gitlab/gitlab_test.go +++ b/pkg/provider/gitlab/gitlab_test.go @@ -12,7 +12,6 @@ import ( "github.com/Masterminds/semver" "github.com/go-semantic-release/semantic-release/pkg/provider" - "github.com/go-semantic-release/semantic-release/pkg/semrel" "github.com/stretchr/testify/require" "github.com/xanzy/go-gitlab" ) @@ -125,18 +124,6 @@ func TestGitlabGetInfo(t *testing.T) { require.True(t, repoInfo.Private) } -func compareCommit(c *semrel.Commit, t, s string, change semrel.Change) bool { - if c.Type != t || c.Scope != s { - return false - } - if c.Change.Major != change.Major || - c.Change.Minor != change.Minor || - c.Change.Patch != change.Patch { - return false - } - return true -} - func TestGitlabGetCommits(t *testing.T) { repo, ts := getNewGitlabTestRepo(t) defer ts.Close() @@ -144,11 +131,9 @@ func TestGitlabGetCommits(t *testing.T) { require.NoError(t, err) require.Len(t, commits, 4) - if !compareCommit(commits[0], "feat", "app", semrel.Change{Major: false, Minor: true, Patch: false}) || - !compareCommit(commits[1], "fix", "", semrel.Change{Major: false, Minor: false, Patch: true}) || - !compareCommit(commits[2], "", "", semrel.Change{Major: false, Minor: false, Patch: false}) || - !compareCommit(commits[3], "chore", "", semrel.Change{Major: true, Minor: false, Patch: false}) { - t.Fatal("invalid commits") + for i, c := range commits { + require.Equal(t, c.SHA, GITLAB_COMMITS[i].ID) + require.Equal(t, c.RawMessage, GITLAB_COMMITS[i].Message) } } diff --git a/pkg/provider/repository.go b/pkg/provider/repository.go index 5f7ef91..ce8f837 100644 --- a/pkg/provider/repository.go +++ b/pkg/provider/repository.go @@ -24,7 +24,7 @@ type RepositoryRelease struct { type Repository interface { GetInfo() (*RepositoryInfo, error) - GetCommits(sha string) ([]*semrel.Commit, error) + GetCommits(sha string) ([]*semrel.RawCommit, error) GetReleases(re *regexp.Regexp) (semrel.Releases, error) CreateRelease(*RepositoryRelease) error Provider() string diff --git a/pkg/semrel/commit.go b/pkg/semrel/commit.go index 771eb79..9beb584 100644 --- a/pkg/semrel/commit.go +++ b/pkg/semrel/commit.go @@ -1,12 +1,9 @@ package semrel -import ( - "regexp" - "strings" -) - -var commitPattern = regexp.MustCompile(`^(\w*)(?:\((.*)\))?\: (.*)$`) -var breakingPattern = regexp.MustCompile("BREAKING CHANGES?") +type RawCommit struct { + SHA string + RawMessage string +} type Change struct { Major, Minor, Patch bool @@ -20,22 +17,3 @@ type Commit struct { Message string Change Change } - -func NewCommit(sha, msg string) *Commit { - c := new(Commit) - c.SHA = sha - c.Raw = strings.Split(msg, "\n") - found := commitPattern.FindAllStringSubmatch(c.Raw[0], -1) - if len(found) < 1 { - return c - } - c.Type = strings.ToLower(found[0][1]) - c.Scope = found[0][2] - c.Message = found[0][3] - c.Change = Change{ - Major: breakingPattern.MatchString(msg), - Minor: c.Type == "feat", - Patch: c.Type == "fix", - } - return c -} -- GitLab