From e0458f81b1e0f48eebc89a61b0be4f981d1810e5 Mon Sep 17 00:00:00 2001
From: Kimmo Saari <kimmo.saari@worddive.com>
Date: Mon, 26 Oct 2020 11:21:23 +0200
Subject: [PATCH] feat: Added support for `Commit message with ! to draw
 attention to breaking change`

---
 README.md                            | 36 ++++++++++++++++++++++++++++
 go.sum                               |  2 ++
 pkg/analyzer/commit_analyzer.go      | 24 ++++++++++++++-----
 pkg/analyzer/commit_analyzer_test.go | 30 +++++++++++++++++++++++
 4 files changed, 86 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md
index c1ddfc3..70468bf 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,42 @@
 
 A [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) analyzer for [go-semantic-release](https://github.com/go-semantic-release/semantic-release).
 
+## How the commit messages are analyzed
+
+### Bump major version (0.1.2 -> 1.0.0)
+- By adding `BREAKING CHANGE` or `BREAKING CHANGES` in the commit message footer, e.g.:
+  ```
+  feat: allow provided config object to extend other configs
+
+  BREAKING CHANGE: `extends` key in config file is now used for extending other config files
+  ```
+- By adding `!` at the end of the commit type, e.g.:
+  ```
+  refactor!: drop support for Node 6
+  ```
+
+### Bump minor version (0.1.2 -> 0.2.0)
+- By using type `feat`, e.g.:
+  ```
+  feat(lang): add polish language
+  ```
+
+### Bump patch version (0.1.2 -> 0.1.3)
+- By using type `fix`, e.g.:
+  ```
+  fix: correct minor typos in code
+
+  see the issue for details
+
+  on typos fixed.
+
+  Reviewed-by: Z
+  Refs #133
+  ```
+
+## References
+- [Conventional Commit v1.0.0 - Examples](https://www.conventionalcommits.org/en/v1.0.0/#examples)
+
 ## Licence
 
 The [MIT License (MIT)](http://opensource.org/licenses/MIT)
diff --git a/go.sum b/go.sum
index 2189c59..241a5b6 100644
--- a/go.sum
+++ b/go.sum
@@ -58,8 +58,10 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-semantic-release/semantic-release v1.22.1 h1:tVeMBvHLNfNV5cS7vK6ZFcozV/u4BtZ+pAvROKibQmw=
 github.com/go-semantic-release/semantic-release/v2 v2.5.0 h1:QDE5x/D/Rt7c1fcgZ3EGAgKOaBuK30R+SX4oPL8b6QI=
 github.com/go-semantic-release/semantic-release/v2 v2.5.0/go.mod h1:2YcQ8CPUnSXnw5Krcakz8gDMrkd+eF69DySp8jAIbQI=
+github.com/go-semantic-release/semantic-release/v2 v2.6.0 h1:hau9IVTeBjxEE7pQoKyhlATWRDjlKY8R/4RXdpa5FRE=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
diff --git a/pkg/analyzer/commit_analyzer.go b/pkg/analyzer/commit_analyzer.go
index 3d915e1..ec18659 100644
--- a/pkg/analyzer/commit_analyzer.go
+++ b/pkg/analyzer/commit_analyzer.go
@@ -8,7 +8,7 @@ import (
 )
 
 var CAVERSION = "dev"
-var commitPattern = regexp.MustCompile(`^(\w*)(?:\((.*)\))?\: (.*)$`)
+var commitPattern = regexp.MustCompile(`^(\w*)(!)?(?:\((.*)\))?\: (.*)$`)
 var breakingPattern = regexp.MustCompile("BREAKING CHANGES?")
 
 type DefaultCommitAnalyzer struct{}
@@ -34,12 +34,24 @@ func (da *DefaultCommitAnalyzer) analyzeSingleCommit(rawCommit *semrel.RawCommit
 		return c
 	}
 	c.Type = strings.ToLower(found[0][1])
-	c.Scope = found[0][2]
-	c.Message = found[0][3]
+	breakingChange := found[0][2]
+	c.Scope = found[0][3]
+	c.Message = found[0][4]
+
+	isMajorChange := breakingPattern.MatchString(rawCommit.RawMessage)
+	isMinorChange := c.Type == "feat"
+	isPatchChange := c.Type == "fix"
+
+	if len(breakingChange) > 0 {
+		isMajorChange = true
+		isMinorChange = false
+		isPatchChange = false
+	}
+
 	c.Change = &semrel.Change{
-		Major: breakingPattern.MatchString(rawCommit.RawMessage),
-		Minor: c.Type == "feat",
-		Patch: c.Type == "fix",
+		Major: isMajorChange,
+		Minor: isMinorChange,
+		Patch: isPatchChange,
 	}
 	return c
 }
diff --git a/pkg/analyzer/commit_analyzer_test.go b/pkg/analyzer/commit_analyzer_test.go
index 53db49d..74911d0 100644
--- a/pkg/analyzer/commit_analyzer_test.go
+++ b/pkg/analyzer/commit_analyzer_test.go
@@ -58,6 +58,36 @@ func TestDefaultAnalyzer(t *testing.T) {
 			"",
 			&semrel.Change{Major: true, Minor: false, Patch: false},
 		},
+		{
+			createRawCommit("e", "feat!: modified login endpoint"),
+			"feat",
+			"",
+			&semrel.Change{Major: true, Minor: false, Patch: false},
+		},
+		{
+			createRawCommit("f", "fix!: fixed a typo"),
+			"fix",
+			"",
+			&semrel.Change{Major: true, Minor: false, Patch: false},
+		},
+		{
+			createRawCommit("g", "refactor!: drop support for Node 6\n\nBREAKING CHANGE: refactor to use JavaScript features not available in Node 6."),
+			"refactor",
+			"",
+			&semrel.Change{Major: true, Minor: false, Patch: false},
+		},
+		{
+			createRawCommit("h", "docs: added more documentation"),
+			"docs",
+			"",
+			&semrel.Change{Major: false, Minor: false, Patch: false},
+		},
+		{
+			createRawCommit("i", "chore: moved README.md to root"),
+			"chore",
+			"",
+			&semrel.Change{Major: false, Minor: false, Patch: false},
+		},
 	}
 
 	defaultAnalyzer := &DefaultCommitAnalyzer{}
-- 
GitLab