Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for non optional scope #54

Merged
merged 1 commit into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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