diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c0e74d..0a8f68d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Run golangci lint - uses: golangci/golangci-lint-action@v2 + uses: golangci/golangci-lint-action@v3 with: version: latest @@ -26,9 +26,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: go-version: ^1.19 - name: Build @@ -40,7 +40,7 @@ jobs: needs: [lint, build] steps: - name: Check out code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -70,7 +70,7 @@ jobs: needs: [tag] steps: - name: Check out code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -81,7 +81,7 @@ jobs: - name: Set up Go id: go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: go-version: ^1.19 diff --git a/sv/message.go b/sv/message.go index fc7e5f7..3344df8 100644 --- a/sv/message.go +++ b/sv/message.go @@ -83,7 +83,7 @@ func (p MessageProcessorImpl) Validate(message string) error { subject, body := splitCommitMessageContent(message) msg, parseErr := p.Parse(subject, body) - if (parseErr != nil) { + if parseErr != nil { return parseErr } @@ -205,14 +205,19 @@ func (p MessageProcessorImpl) Format(msg CommitMessage) (string, string, string) return header.String(), msg.Body, footer.String() } +func removeCarriage(commit string) string { + return regexp.MustCompile(`\r`).ReplaceAllString(commit, "") +} + // Parse a commit message. func (p MessageProcessorImpl) Parse(subject, body string) (CommitMessage, error) { preparedSubject, err := p.prepareHeader(subject) + commitBody := removeCarriage(body) if err != nil { return CommitMessage{}, err } - + commitType, scope, description, hasBreakingChange := parseSubjectMessage(preparedSubject) metadata := make(map[string]string) @@ -220,14 +225,14 @@ func (p MessageProcessorImpl) Parse(subject, body string) (CommitMessage, error) if mdCfg.Key != "" { prefixes := append([]string{mdCfg.Key}, mdCfg.KeySynonyms...) for _, prefix := range prefixes { - if tagValue := extractFooterMetadata(prefix, body, mdCfg.UseHash); tagValue != "" { + if tagValue := extractFooterMetadata(prefix, commitBody, mdCfg.UseHash); tagValue != "" { metadata[key] = tagValue break } } } } - if tagValue := extractFooterMetadata(breakingChangeFooterKey, body, false); tagValue != "" { + if tagValue := extractFooterMetadata(breakingChangeFooterKey, commitBody, false); tagValue != "" { metadata[breakingChangeMetadataKey] = tagValue hasBreakingChange = true } @@ -236,7 +241,7 @@ func (p MessageProcessorImpl) Parse(subject, body string) (CommitMessage, error) Type: commitType, Scope: scope, Description: description, - Body: body, + Body: commitBody, IsBreakingChange: hasBreakingChange, Metadata: metadata, }, nil diff --git a/sv/message_test.go b/sv/message_test.go index c1e790c..5fcd29f 100644 --- a/sv/message_test.go +++ b/sv/message_test.go @@ -70,7 +70,7 @@ func newCommitMessageCfg(headerSelector string) CommitMessageConfig { "issue": {Key: "jira", KeySynonyms: []string{"Jira"}}, "refs": {Key: "Refs", UseHash: true}, }, - Issue: CommitMessageIssueConfig{Regex: "[A-Z]+-[0-9]+"}, + Issue: CommitMessageIssueConfig{Regex: "[A-Z]+-[0-9]+"}, HeaderSelector: headerSelector, } } @@ -378,6 +378,9 @@ var completeBody = `some descriptions jira: JIRA-123 BREAKING CHANGE: this change breaks everything` +var bodyWithCarriage = "some description\r\nmore description\r\n\r\njira: JIRA-123\r" +var expectedBodyWithCarriage = "some description\nmore description\n\njira: JIRA-123" + var issueOnlyBody = `some descriptions jira: JIRA-456` @@ -408,11 +411,12 @@ func TestMessageProcessorImpl_Parse(t *testing.T) { {"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", 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{}}}, + {"carriage return on body", ccfg, "feat: something new", bodyWithCarriage, CommitMessage{Type: "feat", Scope: "", Description: "something new", Body: expectedBodyWithCarriage, IsBreakingChange: false, Metadata: map[string]string{issueMetadataKey: "JIRA-123"}}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got, err := NewMessageProcessor(tt.cfg, newBranchCfg(false)).Parse(tt.subject, tt.body); !reflect.DeepEqual(got, tt.want) && err == nil { - t.Errorf("MessageProcessorImpl.Parse() = %v, want %v", got, tt.want) + t.Errorf("MessageProcessorImpl.Parse() = [%+v], want [%+v]", got, tt.want) } }) } @@ -522,11 +526,11 @@ func Test_parseSubjectMessage(t *testing.T) { func Test_prepareHeader(t *testing.T) { tests := []struct { - name string - headerSelector string - commitHeader string - wantHeader string - wantError bool + name string + headerSelector string + commitHeader string + wantHeader string + wantError bool }{ {"conventional without selector", "", "feat: something", "feat: something", false}, {"conventional with scope without selector", "", "feat(scope): something", "feat(scope): something", false}, @@ -551,3 +555,22 @@ func Test_prepareHeader(t *testing.T) { }) } } + +func Test_removeCarriage(t *testing.T) { + tests := []struct { + name string + commit string + want string + }{ + {"normal string", "normal string", "normal string"}, + {"break line", "normal\nstring", "normal\nstring"}, + {"carriage return", "normal\r\nstring", "normal\nstring"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := removeCarriage(tt.commit); got != tt.want { + t.Errorf("removeCarriage() = %v, want %v", got, tt.want) + } + }) + } +}