@@ -32,6 +32,7 @@ const (
3232 endNestedCommit = "END_NESTED_COMMIT"
3333 breakingChangeKey = "BREAKING CHANGE"
3434 sourceLinkKey = "Source-Link"
35+ empty = ""
3536)
3637
3738var (
@@ -90,7 +91,7 @@ type parsedHeader struct {
9091func (header * parsedHeader ) extractLibraryID () string {
9192 matches := libraryIDRegex .FindStringSubmatch (header .Description )
9293 if len (matches ) == 0 {
93- return ""
94+ return empty
9495 }
9596 return matches [1 ]
9697}
@@ -127,7 +128,7 @@ func (c *ConventionalCommit) MarshalJSON() ([]byte, error) {
127128// conventional commit is logged and skipped.
128129func ParseCommits (commit * gitrepo.Commit , libraryID string ) ([]* ConventionalCommit , error ) {
129130 message := commit .Message
130- if strings .TrimSpace (message ) == "" {
131+ if strings .TrimSpace (message ) == empty {
131132 return nil , fmt .Errorf ("empty commit message" )
132133 }
133134 message = extractCommitMessageOverride (message )
@@ -167,7 +168,7 @@ func extractCommitParts(message string) []commitPart {
167168 var commitParts []commitPart
168169
169170 // The first part is the primary commit.
170- if len (parts ) > 0 && strings .TrimSpace (parts [0 ]) != "" {
171+ if len (parts ) > 0 && strings .TrimSpace (parts [0 ]) != empty {
171172 commitParts = append (commitParts , commitPart {
172173 message : strings .TrimSpace (parts [0 ]),
173174 isNested : false ,
@@ -198,7 +199,7 @@ func extractCommitParts(message string) []commitPart {
198199// A simple commit message is commit that does not include override or nested commits.
199200func parseSimpleCommit (commitPart commitPart , commit * gitrepo.Commit , libraryID string ) ([]* ConventionalCommit , error ) {
200201 trimmedMessage := strings .TrimSpace (commitPart .message )
201- if trimmedMessage == "" {
202+ if trimmedMessage == empty {
202203 return nil , fmt .Errorf ("empty commit message" )
203204 }
204205
@@ -210,6 +211,10 @@ func parseSimpleCommit(commitPart commitPart, commit *gitrepo.Commit, libraryID
210211 var commits []* ConventionalCommit
211212 // Hold the subjects of each commit.
212213 var subjects [][]string
214+ // Hold the body of each commit.
215+ var body [][]string
216+ // Whether it has seen an empty line.
217+ seenSeparator := false
213218 // If the body lines have multiple headers, separate them into different conventional commit, all associated with
214219 // the same commit sha.
215220 for _ , bodyLine := range bodyLines {
@@ -221,12 +226,26 @@ func parseSimpleCommit(commitPart commitPart, commit *gitrepo.Commit, libraryID
221226 continue
222227 }
223228
224- // This might be a multi-line header, append the line to the subject of the last commit.
225- subjects [len (subjects )- 1 ] = append (subjects [len (subjects )- 1 ], strings .TrimSpace (bodyLine ))
229+ bodyLine = strings .TrimSpace (bodyLine )
230+ if bodyLine == empty {
231+ seenSeparator = true
232+ continue
233+ }
234+
235+ if seenSeparator {
236+ // Since we have seen a separator, the rest of the lines are body lines of the commit.
237+ body [len (body )- 1 ] = append (body [len (body )- 1 ], bodyLine )
238+ } else {
239+ // We haven't seen a separator, this line is the continuation of the title.
240+ subjects [len (subjects )- 1 ] = append (subjects [len (subjects )- 1 ], bodyLine )
241+ }
242+
226243 continue
227244 }
228245
229246 subjects = append (subjects , []string {})
247+ body = append (body , []string {})
248+ seenSeparator = false
230249 // If there is an association for the commit (i.e. the commit has '[LIBRARY_ID]' in the
231250 // description), then use that libraryID. Otherwise, use the libraryID passed as the default.
232251 headerLibraryID := header .extractLibraryID ()
@@ -248,17 +267,10 @@ func parseSimpleCommit(commitPart commitPart, commit *gitrepo.Commit, libraryID
248267 })
249268 }
250269
251- if len (commits ) == 1 {
252- // If only one conventional commit is found, i.e., only one header line is
253- // in the commit message, assign the body field.
254- commits [0 ].Body = strings .TrimSpace (strings .Join (bodyLines [1 :], "\n " ))
255- } else {
256- // Otherwise, concatenate all lines as the subject of the corresponding commit.
257- // This is a workaround when GitHub inserts line breaks in the middle of a long line after squash and merge.
258- for i , commit := range commits {
259- sub := fmt .Sprintf ("%s %s" , commit .Subject , strings .Join (subjects [i ], " " ))
260- commit .Subject = strings .TrimSpace (sub )
261- }
270+ for i , commit := range commits {
271+ sub := fmt .Sprintf ("%s %s" , commit .Subject , strings .Join (subjects [i ], " " ))
272+ commit .Subject = strings .TrimSpace (sub )
273+ commit .Body = strings .Join (body [i ], "\n " )
262274 }
263275
264276 return commits , nil
@@ -294,11 +306,11 @@ func separateBodyAndFooters(lines []string) (bodyLines, footerLines []string) {
294306 footerLines = append (footerLines , line )
295307 continue
296308 }
297- if strings .TrimSpace (line ) == "" {
309+ if strings .TrimSpace (line ) == empty {
298310 isSeparator := false
299311 // Look ahead at the next non-blank line.
300312 for j := i + 1 ; j < len (lines ); j ++ {
301- if strings .TrimSpace (lines [j ]) != "" {
313+ if strings .TrimSpace (lines [j ]) != empty {
302314 if footerRegex .MatchString (lines [j ]) {
303315 isSeparator = true
304316 }
@@ -326,7 +338,7 @@ func parseFooters(footerLines []string) (footers map[string]string, isBreaking b
326338 if len (footerMatches ) == 0 {
327339 // Not a new footer. If we have a previous key and the line is not
328340 // empty, append it to the last value.
329- if lastKey != "" && strings .TrimSpace (line ) != "" {
341+ if lastKey != empty && strings .TrimSpace (line ) != empty {
330342 footers [lastKey ] += "\n " + line
331343 }
332344 continue
0 commit comments