diff --git a/helper_test.go b/helper_test.go index 71f5db4..6102141 100644 --- a/helper_test.go +++ b/helper_test.go @@ -1,8 +1,6 @@ package main -import "go.uber.org/zap" - // NextVersion is a test fixture to expose the private nextVersion() function. -func NextVersion(log *zap.Logger, path string) (string, error) { +func NextVersion(path string) (string, error) { return nextVersion(path) } diff --git a/main.go b/main.go index 3041b0e..3ce9902 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,7 @@ package main import ( "fmt" - "strings" + "regexp" "github.com/Masterminds/semver/v3" "github.com/go-git/go-git/v5" @@ -40,18 +40,21 @@ func nextVersion(path string) (string, error) { var major, minor, patch bool var stopIter error = fmt.Errorf("stop commit iteration") var latestTag string + patchRegex := regexp.MustCompile(`^fix(\(.+\))?: `) + minorRegex := regexp.MustCompile(`^feat(\(.+\))?: `) + majorRegex := regexp.MustCompile(`^(fix|feat)(\(.+\))?!: |BREAKING CHANGE: `) err = commits.ForEach(func(c *object.Commit) error { if latestTag = tagRefs[c.Hash.String()]; latestTag != "" { return stopIter } // analyze commit message - if strings.HasPrefix(c.Message, "fix: ") { + if patchRegex.MatchString(c.Message) { patch = true } - if strings.HasPrefix(c.Message, "feat: ") { + if minorRegex.MatchString(c.Message) { minor = true } - if strings.Contains(c.Message, "BREAKING CHANGE: ") { + if majorRegex.MatchString(c.Message) { major = true } return nil diff --git a/main_test.go b/main_test.go index 5eb5cd3..0fa2bd2 100644 --- a/main_test.go +++ b/main_test.go @@ -6,7 +6,6 @@ import ( "testing" ccv "github.com/smlx/ccv" - "go.uber.org/zap" ) func TestNextVersion(t *testing.T) { @@ -15,29 +14,38 @@ func TestNextVersion(t *testing.T) { expect string }{ "none": {gitCmds: [][]string{ - {"commit", "--allow-empty", "-m", "feat: initial commit"}, - {"tag", "v0.1.0"}, {"commit", "--allow-empty", "-m", "chore: not much"}, }, expect: "v0.1.0"}, "patch": {gitCmds: [][]string{ - {"commit", "--allow-empty", "-m", "feat: initial commit"}, - {"tag", "v0.1.0"}, {"commit", "--allow-empty", "-m", "fix: minor bug"}, }, expect: "v0.1.1"}, "minor": {gitCmds: [][]string{ - {"commit", "--allow-empty", "-m", "feat: initial commit"}, - {"tag", "v0.1.0"}, {"commit", "--allow-empty", "-m", "feat: cool new feature"}, }, expect: "v0.2.0"}, "major": {gitCmds: [][]string{ - {"commit", "--allow-empty", "-m", "feat: initial commit"}, - {"tag", "v0.1.0"}, {"commit", "--allow-empty", "-m", "feat: major refactor\nBREAKING CHANGE: new stuff"}, }, expect: "v1.0.0"}, - } - log, err := zap.NewDevelopment() - if err != nil { - t.Fatalf("couldn't get logger: %v", err) + "major fix bang": {gitCmds: [][]string{ + {"commit", "--allow-empty", "-m", "fix!: major bug"}, + }, expect: "v1.0.0"}, + "major feat bang": {gitCmds: [][]string{ + {"commit", "--allow-empty", "-m", "feat!: major change"}, + }, expect: "v1.0.0"}, + "patch with scope": {gitCmds: [][]string{ + {"commit", "--allow-empty", "-m", "fix(lasers): minor bug"}, + }, expect: "v0.1.1"}, + "minor with scope": {gitCmds: [][]string{ + {"commit", "--allow-empty", "-m", "feat(phasers): cool new feature"}, + }, expect: "v0.2.0"}, + "major with scope": {gitCmds: [][]string{ + {"commit", "--allow-empty", "-m", "feat(blasters): major refactor\nBREAKING CHANGE: new stuff"}, + }, expect: "v1.0.0"}, + "major fix bang with scope": {gitCmds: [][]string{ + {"commit", "--allow-empty", "-m", "fix(lightsaber)!: major bug"}, + }, expect: "v1.0.0"}, + "major feat bang with scope": {gitCmds: [][]string{ + {"commit", "--allow-empty", "-m", "feat(bowcaster)!: major change"}, + }, expect: "v1.0.0"}, } for name, tc := range testCases { t.Run(name, func(tt *testing.T) { @@ -47,10 +55,17 @@ func TestNextVersion(t *testing.T) { tt.Fatalf("couldn't get a tempdir: %v", err) } // init git repo - initCmd := exec.Command("git", "init") - initCmd.Dir = dir - if err = initCmd.Run(); err != nil { - tt.Fatalf("couldn't git init: %v", err) + initCmds := [][]string{ + {"init"}, + {"commit", "--allow-empty", "-m", "feat: initial commit"}, + {"tag", "v0.1.0"}, + } + for _, c := range initCmds { + cmd := exec.Command("git", c...) + cmd.Dir = dir + if output, err := cmd.CombinedOutput(); err != nil { + tt.Fatalf("couldn't run init cmd git %v: %v (%s)", c, err, output) + } } for _, c := range tc.gitCmds { cmd := exec.Command("git", c...) @@ -59,8 +74,7 @@ func TestNextVersion(t *testing.T) { tt.Fatalf("couldn't run git %v: %v (%s)", c, err, output) } } - tt.Log(dir) - next, err := ccv.NextVersion(log, dir) + next, err := ccv.NextVersion(dir) if err != nil { tt.Fatalf("error from main.nextVersion(): %v", err) }