Skip to content

Commit

Permalink
feat(scope): Added support for non optional scope
Browse files Browse the repository at this point in the history
By using the argument --force-scope the presense of scope
in the commit message is enforced, meaning that the commit
should always have a scope.
  • Loading branch information
Georgios Patsiaouras committed May 16, 2023
1 parent 0319903 commit 846698f
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 8 deletions.
11 changes: 7 additions & 4 deletions conventional_pre_commit/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ def r_types(types):
return "|".join(types)


def r_scope():
def r_scope(optional=True):
"""Regex str for an optional (scope)."""
return r"(\([\w \/:-]+\))?"
if optional:
return r"(\([\w \/:-]+\))?"
else:
return r"(\([\w \/:-]+\))"


def r_delim():
Expand All @@ -43,15 +46,15 @@ def conventional_types(types=[]):
return types


def is_conventional(input, types=DEFAULT_TYPES):
def is_conventional(input, types=DEFAULT_TYPES, optional_scope=True):
"""
Returns True if input matches Conventional Commits formatting
https://www.conventionalcommits.org
Optionally provide a list of additional custom types.
"""
types = conventional_types(types)
pattern = f"^({r_types(types)}){r_scope()}{r_delim()}{r_subject()}$"
pattern = f"^({r_types(types)}){r_scope(optional_scope)}{r_delim()}{r_subject()}$"
regex = re.compile(pattern, re.DOTALL)

return bool(regex.match(input))
7 changes: 5 additions & 2 deletions conventional_pre_commit/hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ def main(argv=[]):
)
parser.add_argument("types", type=str, nargs="*", default=format.DEFAULT_TYPES, help="Optional list of types to support")
parser.add_argument("input", type=str, help="A file containing a git commit message")
parser.add_argument(
"--force-scope", action="store_false", default=True, dest="optional_scope", help="Force commit to have scope defined."
)

if len(argv) < 1:
argv = sys.argv[1:]
Expand All @@ -44,7 +47,7 @@ def main(argv=[]):
)
return RESULT_FAIL

if format.is_conventional(message, args.types):
if format.is_conventional(message, args.types, args.optional_scope):
return RESULT_SUCCESS
else:
print(
Expand All @@ -66,7 +69,7 @@ def main(argv=[]):
fix: remove infinite loop
{Colors.YELLOW}Optionally, include a scope in parentheses after the type for more context:{Colors.RESTORE}
{Colors.YELLOW}Example commit with scope in parentheses after the type for more context:{Colors.RESTORE}
fix(account): remove infinite loop"""
)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "conventional_pre_commit"
version = "2.2.0"
version = "2.3.0"
description = "A pre-commit hook that checks commit messages for Conventional Commits formatting."
readme = "README.md"
license = { file = "LICENSE" }
Expand Down
5 changes: 5 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ def conventional_commit_path():
return get_message_path("conventional_commit")


@pytest.fixture
def conventional_commit_with_scope_path():
return get_message_path("conventional_commit_with_scope")


@pytest.fixture
def custom_commit_path():
return get_message_path("custom_commit")
Expand Down
1 change: 1 addition & 0 deletions tests/messages/conventional_commit_with_scope
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
feat(scope): message
21 changes: 20 additions & 1 deletion tests/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from conventional_pre_commit import format


CUSTOM_TYPES = ["one", "two"]


Expand All @@ -23,6 +22,14 @@ def test_r_scope__optional():
assert regex.match("")


def test_r_scope__not_optional():
result = format.r_scope(optional=False)
regex = re.compile(result)

# Assert not optional anymore
assert not regex.match("")


def test_r_scope__parenthesis_required():
result = format.r_scope()
regex = re.compile(result)
Expand Down Expand Up @@ -187,6 +194,18 @@ def test_is_conventional__scope_space():
assert not format.is_conventional(input)


def test_is_conventional__scope_not_optional():
input = "feat: message"

assert not format.is_conventional(input, optional_scope=False)


def test_is_conventional__scope_not_optional_empty_parenthesis():
input = "feat(): message"

assert not format.is_conventional(input, optional_scope=False)


def test_is_conventional__missing_delimiter():
input = "feat message"

Expand Down
12 changes: 12 additions & 0 deletions tests/test_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,15 @@ def test_main_fail__conventional_gbk(conventional_gbk_commit_path):
result = main([conventional_gbk_commit_path])

assert result == RESULT_FAIL


def test_main_fail__conventional_with_scope(cmd, conventional_commit_path):
result = subprocess.call((cmd, "--force-scope", conventional_commit_path))

assert result == RESULT_FAIL


def test_main_success__conventional_with_scope(cmd, conventional_commit_with_scope_path):
result = subprocess.call((cmd, "--force-scope", conventional_commit_with_scope_path))

assert result == RESULT_SUCCESS

0 comments on commit 846698f

Please sign in to comment.