0
0
mirror of https://github.com/thegeeklab/git-sv.git synced 2024-11-10 02:10:38 +00:00

Merge pull request #14 from bvieira/#13

Bugfix: Disable issue footer when key is empty
This commit is contained in:
Beatriz Vieira 2021-03-12 21:46:56 -03:00 committed by GitHub
commit b30e43f52c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 32 deletions

View File

@ -15,7 +15,7 @@
### Installing ### Installing
- Download the latest release and add the binary on your path - Download the latest release and add the binary to your path
- Optional: Set `SV4GIT_HOME` to define user configs, check [config](#config) for more information. - Optional: Set `SV4GIT_HOME` to define user configs, check [config](#config) for more information.
### Config ### Config
@ -117,7 +117,7 @@ commit-message:
# don't forget to add "" on your list if you need to define scopes and keep it optional # don't forget to add "" on your list if you need to define scopes and keep it optional
values: [] values: []
footer: footer:
issue: issue: # use "issue: {}" if you wish to disable issue footer
key: jira # name used to define an issue on footer metadata key: jira # name used to define an issue on footer metadata
key-synonyms: # supported variations for footer metadata key-synonyms: # supported variations for footer metadata
- Jira - Jira

View File

@ -298,9 +298,13 @@ func commitHandler(cfg Config, git sv.Git, messageProcessor sv.MessageProcessor)
if err != nil { if err != nil {
return err return err
} }
issue, err := promptIssueID(cfg.CommitMessage.IssueFooterConfig().Key, cfg.CommitMessage.Issue.Regex, branchIssue)
if err != nil { var issue string
return err if cfg.CommitMessage.IssueFooterConfig().Key != "" && cfg.CommitMessage.Issue.Regex != "" {
issue, err = promptIssueID("issue id", cfg.CommitMessage.Issue.Regex, branchIssue)
if err != nil {
return err
}
} }
hasBreakingChanges, err := promptConfirm("has breaking changes?") hasBreakingChanges, err := promptConfirm("has breaking changes?")

View File

@ -119,6 +119,10 @@ func (p MessageProcessorImpl) Enhance(branch string, message string) (string, er
// IssueID try to extract issue id from branch, return empty if not found. // IssueID try to extract issue id from branch, return empty if not found.
func (p MessageProcessorImpl) IssueID(branch string) (string, error) { func (p MessageProcessorImpl) IssueID(branch string) (string, error) {
if p.branchesCfg.DisableIssue || p.messageCfg.Issue.Regex == "" {
return "", nil
}
rstr := fmt.Sprintf("^%s(%s)%s$", p.branchesCfg.PrefixRegex, p.messageCfg.Issue.Regex, p.branchesCfg.SuffixRegex) rstr := fmt.Sprintf("^%s(%s)%s$", p.branchesCfg.PrefixRegex, p.messageCfg.Issue.Regex, p.branchesCfg.SuffixRegex)
r, err := regexp.Compile(rstr) r, err := regexp.Compile(rstr)
if err != nil { if err != nil {
@ -146,7 +150,7 @@ func (p MessageProcessorImpl) Format(msg CommitMessage) (string, string, string)
if msg.BreakingMessage() != "" { if msg.BreakingMessage() != "" {
footer.WriteString(fmt.Sprintf("%s: %s", breakingChangeFooterKey, msg.BreakingMessage())) footer.WriteString(fmt.Sprintf("%s: %s", breakingChangeFooterKey, msg.BreakingMessage()))
} }
if issue, exists := msg.Metadata[issueMetadataKey]; exists { if issue, exists := msg.Metadata[issueMetadataKey]; exists && p.messageCfg.IssueFooterConfig().Key != "" {
if footer.Len() > 0 { if footer.Len() > 0 {
footer.WriteString("\n") footer.WriteString("\n")
} }
@ -166,11 +170,13 @@ func (p MessageProcessorImpl) Parse(subject, body string) CommitMessage {
metadata := make(map[string]string) metadata := make(map[string]string)
for key, mdCfg := range p.messageCfg.Footer { for key, mdCfg := range p.messageCfg.Footer {
prefixes := append([]string{mdCfg.Key}, mdCfg.KeySynonyms...) if mdCfg.Key != "" {
for _, prefix := range prefixes { prefixes := append([]string{mdCfg.Key}, mdCfg.KeySynonyms...)
if tagValue := extractFooterMetadata(prefix, body, mdCfg.UseHash); tagValue != "" { for _, prefix := range prefixes {
metadata[key] = tagValue if tagValue := extractFooterMetadata(prefix, body, mdCfg.UseHash); tagValue != "" {
break metadata[key] = tagValue
break
}
} }
} }
} }

View File

@ -15,6 +15,15 @@ var ccfg = CommitMessageConfig{
Issue: CommitMessageIssueConfig{Regex: "[A-Z]+-[0-9]+"}, Issue: CommitMessageIssueConfig{Regex: "[A-Z]+-[0-9]+"},
} }
var ccfgEmptyIssue = CommitMessageConfig{
Types: []string{"feat", "fix"},
Scope: CommitMessageScopeConfig{},
Footer: map[string]CommitMessageFooterConfig{
"issue": {},
},
Issue: CommitMessageIssueConfig{Regex: "[A-Z]+-[0-9]+"},
}
var ccfgWithScope = CommitMessageConfig{ var ccfgWithScope = CommitMessageConfig{
Types: []string{"feat", "fix"}, Types: []string{"feat", "fix"},
Scope: CommitMessageScopeConfig{Values: []string{"", "scope"}}, Scope: CommitMessageScopeConfig{Values: []string{"", "scope"}},
@ -203,6 +212,7 @@ jira: JIRA-123`
func Test_hasIssueID(t *testing.T) { func Test_hasIssueID(t *testing.T) {
cfgColon := CommitMessageFooterConfig{Key: "jira"} cfgColon := CommitMessageFooterConfig{Key: "jira"}
cfgHash := CommitMessageFooterConfig{Key: "jira", UseHash: true} cfgHash := CommitMessageFooterConfig{Key: "jira", UseHash: true}
cfgEmpty := CommitMessageFooterConfig{}
tests := []struct { tests := []struct {
name string name string
@ -223,6 +233,9 @@ jira: JIRA-123`, cfgColon, true},
{"multi line with issue and hash", `feat: something {"multi line with issue and hash", `feat: something
jira #JIRA-123`, cfgHash, true}, jira #JIRA-123`, cfgHash, true},
{"empty config", `feat: something
jira #JIRA-123`, cfgEmpty, false},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
@ -275,26 +288,26 @@ Jira: JIRA-999
Refs #123` Refs #123`
func TestMessageProcessorImpl_Parse(t *testing.T) { func TestMessageProcessorImpl_Parse(t *testing.T) {
p := NewMessageProcessor(ccfg, newBranchCfg(false))
tests := []struct { tests := []struct {
name string name string
cfg CommitMessageConfig
subject string subject string
body string body string
want CommitMessage want CommitMessage
}{ }{
{"simple message", "feat: something awesome", "", CommitMessage{Type: "feat", Scope: "", Description: "something awesome", Body: "", IsBreakingChange: false, Metadata: map[string]string{}}}, {"simple message", ccfg, "feat: something awesome", "", CommitMessage{Type: "feat", Scope: "", Description: "something awesome", Body: "", IsBreakingChange: false, Metadata: map[string]string{}}},
{"message with scope", "feat(scope): something awesome", "", CommitMessage{Type: "feat", Scope: "scope", Description: "something awesome", Body: "", IsBreakingChange: false, Metadata: map[string]string{}}}, {"message with scope", ccfg, "feat(scope): something awesome", "", CommitMessage{Type: "feat", Scope: "scope", Description: "something awesome", Body: "", IsBreakingChange: false, Metadata: map[string]string{}}},
{"unmapped type", "unkn: something unknown", "", CommitMessage{Type: "unkn", Scope: "", Description: "something unknown", Body: "", IsBreakingChange: false, Metadata: map[string]string{}}}, {"unmapped type", ccfg, "unkn: something unknown", "", CommitMessage{Type: "unkn", Scope: "", Description: "something unknown", Body: "", IsBreakingChange: false, Metadata: map[string]string{}}},
{"jira and breaking change metadata", "feat: something new", completeBody, CommitMessage{Type: "feat", Scope: "", Description: "something new", Body: completeBody, IsBreakingChange: true, Metadata: map[string]string{issueMetadataKey: "JIRA-123", breakingChangeMetadataKey: "this change breaks everything"}}}, {"jira and breaking change metadata", ccfg, "feat: something new", completeBody, CommitMessage{Type: "feat", Scope: "", Description: "something new", Body: completeBody, IsBreakingChange: true, Metadata: map[string]string{issueMetadataKey: "JIRA-123", breakingChangeMetadataKey: "this change breaks everything"}}},
{"jira only metadata", "feat: something new", issueOnlyBody, CommitMessage{Type: "feat", Scope: "", Description: "something new", Body: issueOnlyBody, IsBreakingChange: false, Metadata: map[string]string{issueMetadataKey: "JIRA-456"}}}, {"jira only metadata", ccfg, "feat: something new", issueOnlyBody, CommitMessage{Type: "feat", Scope: "", Description: "something new", Body: issueOnlyBody, IsBreakingChange: false, Metadata: map[string]string{issueMetadataKey: "JIRA-456"}}},
{"jira synonyms metadata", "feat: something new", issueSynonymsBody, CommitMessage{Type: "feat", Scope: "", Description: "something new", Body: issueSynonymsBody, IsBreakingChange: false, Metadata: map[string]string{issueMetadataKey: "JIRA-789"}}}, {"jira synonyms metadata", ccfg, "feat: something new", issueSynonymsBody, CommitMessage{Type: "feat", Scope: "", Description: "something new", Body: issueSynonymsBody, IsBreakingChange: false, Metadata: map[string]string{issueMetadataKey: "JIRA-789"}}},
{"breaking change with exclamation mark", "feat!: something new", "", CommitMessage{Type: "feat", Scope: "", Description: "something new", Body: "", IsBreakingChange: true, Metadata: map[string]string{}}}, {"breaking change with exclamation mark", ccfg, "feat!: something new", "", CommitMessage{Type: "feat", Scope: "", Description: "something new", Body: "", IsBreakingChange: true, Metadata: map[string]string{}}},
{"hash metadata", "feat: something new", hashMetadataBody, CommitMessage{Type: "feat", Scope: "", Description: "something new", Body: hashMetadataBody, IsBreakingChange: false, Metadata: map[string]string{issueMetadataKey: "JIRA-999", "refs": "#123"}}}, {"hash metadata", ccfg, "feat: something new", hashMetadataBody, CommitMessage{Type: "feat", Scope: "", Description: "something new", Body: hashMetadataBody, IsBreakingChange: false, Metadata: map[string]string{issueMetadataKey: "JIRA-999", "refs": "#123"}}},
{"empty issue cfg", ccfgEmptyIssue, "feat: something new", hashMetadataBody, CommitMessage{Type: "feat", Scope: "", Description: "something new", Body: hashMetadataBody, IsBreakingChange: false, Metadata: map[string]string{}}},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if got := p.Parse(tt.subject, tt.body); !reflect.DeepEqual(got, tt.want) { if got := NewMessageProcessor(tt.cfg, newBranchCfg(false)).Parse(tt.subject, tt.body); !reflect.DeepEqual(got, tt.want) {
t.Errorf("MessageProcessorImpl.Parse() = %v, want %v", got, tt.want) t.Errorf("MessageProcessorImpl.Parse() = %v, want %v", got, tt.want)
} }
}) })
@ -302,26 +315,26 @@ func TestMessageProcessorImpl_Parse(t *testing.T) {
} }
func TestMessageProcessorImpl_Format(t *testing.T) { func TestMessageProcessorImpl_Format(t *testing.T) {
p := NewMessageProcessor(ccfg, newBranchCfg(false))
tests := []struct { tests := []struct {
name string name string
cfg CommitMessageConfig
msg CommitMessage msg CommitMessage
wantHeader string wantHeader string
wantBody string wantBody string
wantFooter string wantFooter string
}{ }{
{"simple message", NewCommitMessage("feat", "", "something", "", "", ""), "feat: something", "", ""}, {"simple message", ccfg, NewCommitMessage("feat", "", "something", "", "", ""), "feat: something", "", ""},
{"with issue", NewCommitMessage("feat", "", "something", "", "JIRA-123", ""), "feat: something", "", "jira: JIRA-123"}, {"with issue", ccfg, NewCommitMessage("feat", "", "something", "", "JIRA-123", ""), "feat: something", "", "jira: JIRA-123"},
{"with breaking change", NewCommitMessage("feat", "", "something", "", "", "breaks"), "feat: something", "", "BREAKING CHANGE: breaks"}, {"with breaking change", ccfg, NewCommitMessage("feat", "", "something", "", "", "breaks"), "feat: something", "", "BREAKING CHANGE: breaks"},
{"with scope", NewCommitMessage("feat", "scope", "something", "", "", ""), "feat(scope): something", "", ""}, {"with scope", ccfg, NewCommitMessage("feat", "scope", "something", "", "", ""), "feat(scope): something", "", ""},
{"with body", NewCommitMessage("feat", "", "something", "body", "", ""), "feat: something", "body", ""}, {"with body", ccfg, NewCommitMessage("feat", "", "something", "body", "", ""), "feat: something", "body", ""},
{"with multiline body", NewCommitMessage("feat", "", "something", multilineBody, "", ""), "feat: something", multilineBody, ""}, {"with multiline body", ccfg, NewCommitMessage("feat", "", "something", multilineBody, "", ""), "feat: something", multilineBody, ""},
{"full message", NewCommitMessage("feat", "scope", "something", multilineBody, "JIRA-123", "breaks"), "feat(scope): something", multilineBody, fullFooter}, {"full message", ccfg, NewCommitMessage("feat", "scope", "something", multilineBody, "JIRA-123", "breaks"), "feat(scope): something", multilineBody, fullFooter},
{"config without issue key", ccfgEmptyIssue, NewCommitMessage("feat", "", "something", "", "JIRA-123", ""), "feat: something", "", ""},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got, got1, got2 := p.Format(tt.msg) got, got1, got2 := NewMessageProcessor(tt.cfg, newBranchCfg(false)).Format(tt.msg)
if got != tt.wantHeader { if got != tt.wantHeader {
t.Errorf("MessageProcessorImpl.Format() header got = %v, want %v", got, tt.wantHeader) t.Errorf("MessageProcessorImpl.Format() header got = %v, want %v", got, tt.wantHeader)
} }