Skip to content

Commit 26392d2

Browse files
committed
refactor(format): extract regex construction and usage
1 parent 174d446 commit 26392d2

File tree

2 files changed

+67
-9
lines changed

2 files changed

+67
-9
lines changed

conventional_pre_commit/format.py

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,22 +96,52 @@ def conventional_types(types=[]):
9696
return types
9797

9898

99-
def is_conventional(input, types=DEFAULT_TYPES, optional_scope=True, scopes: Optional[List[str]] = None):
99+
def conventional_regex(types=DEFAULT_TYPES, optional_scope=True, scopes: Optional[List[str]] = None):
100+
types = conventional_types(types)
101+
102+
types_pattern = f"^(?P<type>{r_types(types)})?"
103+
scope_pattern = f"(?P<scope>{r_scope(optional_scope, scopes=scopes)})?"
104+
delim_pattern = f"(?P<delim>{r_delim()})?"
105+
subject_pattern = f"(?P<subject>{r_subject()})?"
106+
body_pattern = f"(?P<body>{r_body()})?"
107+
pattern = types_pattern + scope_pattern + delim_pattern + subject_pattern + body_pattern
108+
109+
return re.compile(pattern, re.MULTILINE)
110+
111+
112+
def clean_input(input: str):
113+
"""
114+
Prepares an input message for conventional commits format check.
115+
"""
116+
input = strip_verbose_commit_ignored(input)
117+
input = strip_comments(input)
118+
return input
119+
120+
121+
def conventional_match(input: str, types=DEFAULT_TYPES, optional_scope=True, scopes: Optional[List[str]] = None):
122+
"""
123+
Returns an `re.Match` object for the input against the Conventional Commits format.
124+
"""
125+
input = clean_input(input)
126+
regex = conventional_regex(types, optional_scope, scopes)
127+
return regex.match(input)
128+
129+
130+
def is_conventional(input: str, types=DEFAULT_TYPES, optional_scope=True, scopes: Optional[List[str]] = None) -> bool:
100131
"""
101132
Returns True if input matches Conventional Commits formatting
102133
https://www.conventionalcommits.org
103134
104135
Optionally provide a list of additional custom types.
105136
"""
106-
input = strip_verbose_commit_ignored(input)
107-
input = strip_comments(input)
108-
types = conventional_types(types)
109-
pattern = f"^({r_types(types)}){r_scope(optional_scope, scopes=scopes)}{r_delim()}{r_subject()}{r_body()}"
110-
regex = re.compile(pattern, re.MULTILINE)
111-
112-
result = regex.match(input)
137+
result = conventional_match(input, types, optional_scope, scopes)
113138
is_valid = bool(result)
114-
if is_valid and result.group("multi") and not result.group("sep"):
139+
140+
if result and result.group("multi") and not result.group("sep"):
141+
is_valid = False
142+
if result and not all(
143+
[result.group("type"), optional_scope or result.group("scope"), result.group("delim"), result.group("subject")]
144+
):
115145
is_valid = False
116146

117147
return is_valid

tests/test_format.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,34 @@ def test_strip_verbose_commit_ignored__strips_double_verbose_ignored():
436436
assert result == expected
437437

438438

439+
def test_conventional_regex():
440+
regex = format.conventional_regex()
441+
442+
assert isinstance(regex, re.Pattern)
443+
assert "type" in regex.groupindex
444+
assert "scope" in regex.groupindex
445+
assert "delim" in regex.groupindex
446+
assert "subject" in regex.groupindex
447+
assert "body" in regex.groupindex
448+
assert "multi" in regex.groupindex
449+
assert "sep" in regex.groupindex
450+
451+
452+
def test_conventional_match():
453+
match = format.conventional_match(
454+
"""test(scope): subject line
455+
456+
body copy
457+
"""
458+
)
459+
assert match
460+
assert match.group("type") == "test"
461+
assert match.group("scope") == "(scope)"
462+
assert match.group("delim") == ":"
463+
assert match.group("subject").strip() == "subject line"
464+
assert match.group("body").strip() == "body copy"
465+
466+
439467
@pytest.mark.parametrize("type", format.DEFAULT_TYPES)
440468
def test_is_conventional__default_type(type):
441469
input = f"{type}: message"

0 commit comments

Comments
 (0)