Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6828582

Browse files
feat: implement message length limit for commit messages
1 parent a69d441 commit 6828582

File tree

7 files changed

+144
-6
lines changed

7 files changed

+144
-6
lines changed

‎commitizen/cli.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ def __call__(
160160
{
161161
"name": ["-l", "--message-length-limit"],
162162
"type": int,
163-
"default": 0,
164163
"help": "length limit of the commit message; 0 for no limit",
165164
},
166165
{
@@ -492,7 +491,6 @@ def __call__(
492491
{
493492
"name": ["-l", "--message-length-limit"],
494493
"type": int,
495-
"default": 0,
496494
"help": "length limit of the commit message; 0 for no limit",
497495
},
498496
],

‎commitizen/commands/check.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from commitizen import factory, git, out
88
from commitizen.config import BaseConfig
99
from commitizen.exceptions import (
10+
CommitMessageLengthExceededError,
1011
InvalidCommandArgumentError,
1112
InvalidCommitMessageError,
1213
NoCommitsFoundError,
@@ -40,7 +41,13 @@ def __init__(self, config: BaseConfig, arguments: CheckArgs, *args: object) -> N
4041
self.allow_abort = bool(
4142
arguments.get("allow_abort", config.settings["allow_abort"])
4243
)
43-
self.max_msg_length = arguments.get("message_length_limit", 0)
44+
45+
# Use command line argument if provided, otherwise use config setting
46+
cmd_length_limit = arguments.get("message_length_limit")
47+
if cmd_length_limit is None:
48+
self.max_msg_length = config.settings.get("message_length_limit", 0)
49+
else:
50+
self.max_msg_length = cmd_length_limit
4451

4552
# we need to distinguish between None and [], which is a valid value
4653
allowed_prefixes = arguments.get("allowed_prefixes")
@@ -154,6 +161,11 @@ def _validate_commit_message(
154161
if self.max_msg_length:
155162
msg_len = len(commit_msg.partition("\n")[0].strip())
156163
if msg_len > self.max_msg_length:
157-
return False
164+
raise CommitMessageLengthExceededError(
165+
f"commit validation: failed!\n"
166+
f"commit message length exceeds the limit.\n"
167+
f'commit "": "{commit_msg}"\n'
168+
f"message length limit: {self.max_msg_length} (actual: {msg_len})"
169+
)
158170

159171
return bool(pattern.match(commit_msg))

‎commitizen/commands/commit.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,12 @@ def _prompt_commit_questions(self) -> str:
8181

8282
message = cz.message(answers)
8383
message_len = len(message.partition("\n")[0].strip())
84-
message_length_limit = self.arguments.get("message_length_limit", 0)
84+
85+
86+
message_length_limit = self.arguments.get("message_length_limit")
87+
if message_length_limit is None:
88+
message_length_limit = self.config.settings.get("message_length_limit", 0)
89+
8590
if 0 < message_length_limit < message_len:
8691
raise CommitMessageLengthExceededError(
8792
f"Length of commit message exceeds limit ({message_len}/{message_length_limit})"

‎commitizen/defaults.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class Settings(TypedDict, total=False):
4646
ignored_tag_formats: Sequence[str]
4747
legacy_tag_formats: Sequence[str]
4848
major_version_zero: bool
49+
message_length_limit: int
4950
name: str
5051
post_bump_hooks: list[str] | None
5152
pre_bump_hooks: list[str] | None
@@ -108,6 +109,7 @@ class Settings(TypedDict, total=False):
108109
"always_signoff": False,
109110
"template": None, # default provided by plugin
110111
"extras": {},
112+
"message_length_limit": 0, # 0 for no limit
111113
}
112114

113115
MAJOR = "MAJOR"

‎tests/commands/test_check_command.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from commitizen import cli, commands, git
1010
from commitizen.exceptions import (
11+
CommitMessageLengthExceededError,
1112
InvalidCommandArgumentError,
1213
InvalidCommitMessageError,
1314
NoCommitsFoundError,
@@ -449,6 +450,65 @@ def test_check_command_with_message_length_limit_exceeded(config, mocker: MockFi
449450
arguments={"message": message, "message_length_limit": len(message) - 1},
450451
)
451452

452-
with pytest.raises(InvalidCommitMessageError):
453+
with pytest.raises(CommitMessageLengthExceededError):
453454
check_cmd()
454455
error_mock.assert_called_once()
456+
457+
458+
def test_check_command_with_config_message_length_limit(config, mocker: MockFixture):
459+
success_mock = mocker.patch("commitizen.out.success")
460+
message = "fix(scope): some commit message"
461+
462+
config.settings["message_length_limit"] = len(message) + 1
463+
464+
check_cmd = commands.Check(
465+
config=config,
466+
arguments={"message": message},
467+
)
468+
469+
check_cmd()
470+
success_mock.assert_called_once()
471+
472+
473+
def test_check_command_with_config_message_length_limit_exceeded(
474+
config, mocker: MockFixture
475+
):
476+
error_mock = mocker.patch("commitizen.out.error")
477+
message = "fix(scope): some commit message"
478+
479+
config.settings["message_length_limit"] = len(message) - 1
480+
481+
check_cmd = commands.Check(
482+
config=config,
483+
arguments={"message": message},
484+
)
485+
486+
with pytest.raises(CommitMessageLengthExceededError):
487+
check_cmd()
488+
error_mock.assert_called_once()
489+
490+
491+
def test_check_command_cli_overrides_config_message_length_limit(
492+
config, mocker: MockFixture
493+
):
494+
success_mock = mocker.patch("commitizen.out.success")
495+
message = "fix(scope): some commit message"
496+
497+
config.settings["message_length_limit"] = len(message) - 1
498+
499+
check_cmd = commands.Check(
500+
config=config,
501+
arguments={"message": message, "message_length_limit": len(message) + 1},
502+
)
503+
504+
check_cmd()
505+
success_mock.assert_called_once()
506+
507+
success_mock.reset_mock()
508+
check_cmd = commands.Check(
509+
config=config,
510+
arguments={"message": message, "message_length_limit": 0},
511+
)
512+
513+
check_cmd()
514+
success_mock.assert_called_once()

‎tests/commands/test_commit_command.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,3 +554,62 @@ def test_commit_when_nothing_added_to_commit(config, mocker: MockFixture, out):
554554

555555
commit_mock.assert_called_once()
556556
error_mock.assert_called_once_with(out)
557+
558+
559+
@pytest.mark.usefixtures("staging_is_clean")
560+
def test_commit_command_with_config_message_length_limit(config, mocker: MockFixture):
561+
prompt_mock = mocker.patch("questionary.prompt")
562+
prefix = "feat"
563+
subject = "random subject"
564+
message_length = len(prefix) + len(": ") + len(subject)
565+
prompt_mock.return_value = {
566+
"prefix": prefix,
567+
"subject": subject,
568+
"scope": "",
569+
"is_breaking_change": False,
570+
"body": "random body",
571+
"footer": "random footer",
572+
}
573+
574+
commit_mock = mocker.patch("commitizen.git.commit")
575+
commit_mock.return_value = cmd.Command("success", "", b"", b"", 0)
576+
success_mock = mocker.patch("commitizen.out.success")
577+
578+
config.settings["message_length_limit"] = message_length
579+
commands.Commit(config, {})()
580+
success_mock.assert_called_once()
581+
582+
config.settings["message_length_limit"] = message_length - 1
583+
with pytest.raises(CommitMessageLengthExceededError):
584+
commands.Commit(config, {})()
585+
586+
587+
@pytest.mark.usefixtures("staging_is_clean")
588+
def test_commit_command_cli_overrides_config_message_length_limit(
589+
config, mocker: MockFixture
590+
):
591+
prompt_mock = mocker.patch("questionary.prompt")
592+
prefix = "feat"
593+
subject = "random subject"
594+
message_length = len(prefix) + len(": ") + len(subject)
595+
prompt_mock.return_value = {
596+
"prefix": prefix,
597+
"subject": subject,
598+
"scope": "",
599+
"is_breaking_change": False,
600+
"body": "random body",
601+
"footer": "random footer",
602+
}
603+
604+
commit_mock = mocker.patch("commitizen.git.commit")
605+
commit_mock.return_value = cmd.Command("success", "", b"", b"", 0)
606+
success_mock = mocker.patch("commitizen.out.success")
607+
608+
config.settings["message_length_limit"] = message_length - 1
609+
610+
commands.Commit(config, {"message_length_limit": message_length})()
611+
success_mock.assert_called_once()
612+
613+
success_mock.reset_mock()
614+
commands.Commit(config, {"message_length_limit": 0})()
615+
success_mock.assert_called_once()

‎tests/test_conf.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
"always_signoff": False,
9696
"template": None,
9797
"extras": {},
98+
"message_length_limit": 0,
9899
}
99100

100101
_new_settings: dict[str, Any] = {
@@ -126,6 +127,7 @@
126127
"always_signoff": False,
127128
"template": None,
128129
"extras": {},
130+
"message_length_limit": 0,
129131
}
130132

131133

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /