diff --git a/conventional_pre_commit/format.py b/conventional_pre_commit/format.py index 6b664a8..4a856a4 100644 --- a/conventional_pre_commit/format.py +++ b/conventional_pre_commit/format.py @@ -156,7 +156,7 @@ def r_subject(self): @property def r_body(self): """Regex str for the body, with multiline support.""" - return r"(?P\r?\n(?P^$\r?\n)?.+)?" + return r"(?P\r?\n(?P^$\r?\n)?(?P(?i:BREAKING[ -]CHANGE: ))?.+)?" @property def regex(self): @@ -201,6 +201,19 @@ def errors(self, commit_msg: str = "") -> List[str]: return [g for g, v in groups.items() if not v] + def _is_valid_body(self, match: re.Match) -> bool: + """ + Returns True if the body follows Conventional Commits formatting. + """ + if not match.group("body"): # no extra body + return True + if match.group("multi") and match.group("sep"): # a multiline body with proper separator + if match.group("break"): + return match.group("break").isupper() + else: + return True + return False + def is_valid(self, commit_msg: str = "") -> bool: """ Returns True if commit_msg matches Conventional Commits formatting. @@ -220,14 +233,7 @@ def is_valid(self, commit_msg: str = "") -> bool: self.scope_optional or match.group("scope"), match.group("delim"), match.group("subject"), - any( - [ - # no extra body; OR - not match.group("body"), - # a multiline body with proper separator - match.group("multi") and match.group("sep"), - ] - ), + self._is_valid_body(match), ] ) diff --git a/tests/test_format.py b/tests/test_format.py index 30dbd2d..6817180 100644 --- a/tests/test_format.py +++ b/tests/test_format.py @@ -768,6 +768,18 @@ def test_is_valid__missing_delimiter(conventional_commit): """, False, ), + ( + "feat(scope): subject\n\nBreaking change: description\n", + False, + ), + ( + "feat(scope): subject\n\nBREAKING CHANGE: description\n", + True, + ), + ( + "feat(scope): subject\n\nBREAKING-CHANGE: description\n", + True, + ), ], ) def test_is_conventional(input, expected_result):