diff --git a/reader/converter.go b/reader/converter.go index a1c0b9a..fc5fe5b 100644 --- a/reader/converter.go +++ b/reader/converter.go @@ -4,7 +4,7 @@ import ( "strings" ) -func StringToModel(message string, signature Signature, filesCount int) GitCommit { +func StringToModel(message string, signature Signature, filesCount int, isMerge bool) GitCommit { var res = strings.SplitN(message, "\n", 2) if len(res) == 1 { return GitCommit{Title: message, Description: "", Signature: signature, RawMessage: message} diff --git a/reader/converter_test.go b/reader/converter_test.go index da14994..9e839ca 100644 --- a/reader/converter_test.go +++ b/reader/converter_test.go @@ -21,7 +21,7 @@ and continues and continues ` - commit := StringToModel(message, Signature{}, 3) + commit := StringToModel(message, Signature{}, 3, false) assert.Equal(t, len(strings.Split(commit.Title, "\n")), 1) assert.Equal(t, len(strings.Split(commit.Description, "\n")), 13) assert.Equal(t, commit.FilesCount, 3) @@ -36,7 +36,7 @@ body continues and continues and continues ` - commit := StringToModel(message, Signature{}, 0) + commit := StringToModel(message, Signature{}, 0, false) assert.Equal(t, len(strings.Split(commit.Title, "\n")), 1) assert.Equal(t, len(strings.Split(commit.Description, "\n")), 7) } diff --git a/reader/direct_input_reader.go b/reader/direct_input_reader.go index 356907d..98c25b1 100644 --- a/reader/direct_input_reader.go +++ b/reader/direct_input_reader.go @@ -23,5 +23,5 @@ func ReadDirectInput(directory string) []GitCommit { rawAuthor := string(out) commit, _ := ioutil.ReadFile(".git/COMMIT_EDITMSG") rawCommit := string(commit) - return []GitCommit{StringToModel(rawCommit, GitVarToSignature(rawAuthor), changedFiles)} + return []GitCommit{StringToModel(rawCommit, GitVarToSignature(rawAuthor), changedFiles, false)} } diff --git a/reader/directory_reader.go b/reader/directory_reader.go index 231389e..95db7cd 100644 --- a/reader/directory_reader.go +++ b/reader/directory_reader.go @@ -18,7 +18,7 @@ func ReadGitCommitsFromDirectory(directory string, scope string) []GitCommit { var models []GitCommit iterateOverCommon(r, getHashFromBranchName(r, a), getHashFromBranchName(r, b), func(c *object.Commit) error { - models = append(models, StringToModel(c.Message, Signature{Email: c.Author.Email, Name: c.Author.Name}, countFilesInCommit(c))) + models = append(models, StringToModel(c.Message, Signature{Email: c.Author.Email, Name: c.Author.Name}, countFilesInCommit(c), isMergeCommit(c))) return nil }) return models @@ -90,3 +90,7 @@ func countFilesInCommit(commit *object.Commit) int { return count } + +func isMergeCommit(commit *object.Commit) bool { + return len(commit.ParentHashes) > 1 +} diff --git a/reader/reader.go b/reader/reader.go index 83ad549..b0fbd99 100644 --- a/reader/reader.go +++ b/reader/reader.go @@ -16,6 +16,7 @@ type GitCommit struct { RawMessage string Signature Signature FilesCount int + IsMerge bool } type Signature struct { diff --git a/rules/config.go b/rules/config.go index 06be7af..dca8840 100644 --- a/rules/config.go +++ b/rules/config.go @@ -16,6 +16,7 @@ type ProjectConfig struct { noTrailingPunctuationInTitle bool maxFiles int startsWithVerb bool + forbidMerge bool } var k = koanf.New(".") @@ -44,6 +45,7 @@ func ReadConfig(directory string) ProjectConfig { noTrailingPunctuationInTitle: k.Bool("no_trailing_punctuation_in_title"), maxFiles: k.Int("max_files"), startsWithVerb: k.Bool("starts_with_verb"), + forbidMerge: k.Bool("forbid_merge"), } return config diff --git a/rules/forbid_merges.go b/rules/forbid_merges.go new file mode 100644 index 0000000..5322163 --- /dev/null +++ b/rules/forbid_merges.go @@ -0,0 +1,18 @@ +package rules + +import "gitlab.com/tbacompany/gitector/reader" + +type ContainsMergeCommit struct{} + +func ForbidMerges(isMerge bool, isEnabled bool) bool { + return isMerge && isEnabled +} + +func ContainsMergeCommitError(commit reader.GitCommit) GitError { + return GitError{ + ErrorType: ContainsMergeCommit{}, + Title: "Commit is a merge commit", + Description: "Merge commits are disabled please use rebase instead", + Commit: commit, + } +} diff --git a/rules/rules.go b/rules/rules.go index 818999a..558704d 100644 --- a/rules/rules.go +++ b/rules/rules.go @@ -62,5 +62,9 @@ func singleCommit(description reader.GitCommit, config ProjectConfig) []GitError errors = append(errors, StartsWithBaseVerbError(description.Title, description)) } + if ForbidMerges(description.IsMerge, config.forbidMerge) { + errors = append(errors, ContainsMergeCommitError(description)) + } + return errors } diff --git a/utils/init.go b/utils/init.go index 0d536c0..1458d6f 100644 --- a/utils/init.go +++ b/utils/init.go @@ -12,7 +12,8 @@ var defaultConfig = []byte(` "ticket_regexp": "", "no_trailing_punctuation_in_title": true, "max_files": 0, - "starts_with_verb": true + "starts_with_verb": true, + "forbid_merge": false } `)