Skip to content

Commit 09c0045

Browse files
authored
feat: introduce "strict" mode (#61)
2 parents 2e0c674 + 6b4f68c commit 09c0045

File tree

7 files changed

+75
-1
lines changed

7 files changed

+75
-1
lines changed

conventional_pre_commit/format.py

+24
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
"style",
1515
"test",
1616
]
17+
AUTOSQUASH_PREFIXES = [
18+
"amend",
19+
"fixup",
20+
"squash",
21+
]
1722

1823

1924
def r_types(types):
@@ -39,6 +44,11 @@ def r_subject():
3944
return r" .+"
4045

4146

47+
def r_autosquash_prefixes():
48+
"""Regex str for autosquash prefixes."""
49+
return "|".join(AUTOSQUASH_PREFIXES)
50+
51+
4252
def conventional_types(types=[]):
4353
"""Return a list of Conventional Commits types merged with the given types."""
4454
if set(types) & set(CONVENTIONAL_TYPES) == set():
@@ -58,3 +68,17 @@ def is_conventional(input, types=DEFAULT_TYPES, optional_scope=True):
5868
regex = re.compile(pattern, re.DOTALL)
5969

6070
return bool(regex.match(input))
71+
72+
73+
def has_autosquash_prefix(input):
74+
"""
75+
Returns True if input starts with one of the autosquash prefixes used in git.
76+
See the documentation, please https://git-scm.com/docs/git-rebase.
77+
78+
It doesn't check whether the rest of the input matches Conventional Commits
79+
formatting.
80+
"""
81+
pattern = f"^(({r_autosquash_prefixes()})! ).*$"
82+
regex = re.compile(pattern, re.DOTALL)
83+
84+
return bool(regex.match(input))

conventional_pre_commit/hook.py

+7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ def main(argv=[]):
2323
parser.add_argument(
2424
"--force-scope", action="store_false", default=True, dest="optional_scope", help="Force commit to have scope defined."
2525
)
26+
parser.add_argument(
27+
"--strict", action="store_true", help="Force commit to strictly follow Conventional Commits formatting."
28+
)
2629

2730
if len(argv) < 1:
2831
argv = sys.argv[1:]
@@ -47,6 +50,10 @@ def main(argv=[]):
4750
)
4851
return RESULT_FAIL
4952

53+
if not args.strict:
54+
if format.has_autosquash_prefix(message):
55+
return RESULT_SUCCESS
56+
5057
if format.is_conventional(message, args.types, args.optional_scope):
5158
return RESULT_SUCCESS
5259
else:

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "conventional_pre_commit"
3-
version = "2.3.0"
3+
version = "2.4.0"
44
description = "A pre-commit hook that checks commit messages for Conventional Commits formatting."
55
readme = "README.md"
66
license = { file = "LICENSE" }

tests/conftest.py

+5
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,8 @@ def conventional_utf8_commit_path():
3737
@pytest.fixture
3838
def conventional_gbk_commit_path():
3939
return get_message_path("conventional_commit_gbk")
40+
41+
42+
@pytest.fixture
43+
def fixup_commit_path():
44+
return get_message_path("fixup_commit")

tests/messages/fixup_commit

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fixup! feature: implement something cool

tests/test_format.py

+25
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@ def test_r_subject__special_chars():
102102
assert regex.match(" some thing")
103103

104104

105+
def test_r_autosquash_prefixes():
106+
result = format.r_autosquash_prefixes()
107+
regex = re.compile(result)
108+
109+
for prefix in format.AUTOSQUASH_PREFIXES:
110+
assert regex.match(prefix)
111+
112+
105113
def test_conventional_types__default():
106114
result = format.conventional_types()
107115

@@ -210,3 +218,20 @@ def test_is_conventional__missing_delimiter():
210218
input = "feat message"
211219

212220
assert not format.is_conventional(input)
221+
222+
223+
@pytest.mark.parametrize(
224+
"input,has_prefix",
225+
[
226+
("amend! ", True),
227+
("fixup! ", True),
228+
("squash! ", True),
229+
("squash! whatever .. $12 #", True),
230+
("squash!", False),
231+
(" squash! ", False),
232+
("squash!:", False),
233+
("feat(foo):", False),
234+
],
235+
)
236+
def test_has_autosquash_prefix(input, has_prefix):
237+
assert format.has_autosquash_prefix(input) == has_prefix

tests/test_hook.py

+12
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,15 @@ def test_main_success__conventional_with_scope(cmd, conventional_commit_with_sco
104104
result = subprocess.call((cmd, "--force-scope", conventional_commit_with_scope_path))
105105

106106
assert result == RESULT_SUCCESS
107+
108+
109+
def test_main_success__fixup_commit(cmd, fixup_commit_path):
110+
result = subprocess.call((cmd, fixup_commit_path))
111+
112+
assert result == RESULT_SUCCESS
113+
114+
115+
def test_main_success__fail_commit(cmd, fixup_commit_path):
116+
result = subprocess.call((cmd, "--strict", fixup_commit_path))
117+
118+
assert result == RESULT_FAIL

0 commit comments

Comments
 (0)