File tree Expand file tree Collapse file tree 12 files changed +80
-20
lines changed Expand file tree Collapse file tree 12 files changed +80
-20
lines changed Original file line number Diff line number Diff line change @@ -154,6 +154,12 @@ def __call__(
154
154
"action" : "store_true" ,
155
155
"help" : "Tell the command to automatically stage files that have been modified and deleted, but new files you have not told Git about are not affected." ,
156
156
},
157
+ {
158
+ "name" : ["-l" , "--message-length-limit" ],
159
+ "type" : int ,
160
+ "default" : 0 ,
161
+ "help" : "length limit of the commit message; 0 for no limit" ,
162
+ },
157
163
],
158
164
},
159
165
{
Original file line number Diff line number Diff line change @@ -61,7 +61,9 @@ def prompt_commit_questions(self) -> str:
61
61
62
62
if not answers :
63
63
raise NoAnswersError ()
64
- return cz .message (answers )
64
+
65
+ message_length_limit : int = self .arguments .get ("message_length_limit" , 0 )
66
+ return cz .message (answers , message_length_limit = message_length_limit )
65
67
66
68
def __call__ (self ):
67
69
dry_run : bool = self .arguments .get ("dry_run" )
Original file line number Diff line number Diff line change 9
9
from commitizen import git
10
10
from commitizen .config .base_config import BaseConfig
11
11
from commitizen .defaults import Questions
12
+ from commitizen .exceptions import CommitMessageLengthExceededError
12
13
13
14
14
15
class MessageBuilderHook (Protocol ):
@@ -71,7 +72,7 @@ def questions(self) -> Questions:
71
72
"""Questions regarding the commit message."""
72
73
73
74
@abstractmethod
74
- def message (self , answers : dict ) -> str :
75
+ def message (self , answers : dict , message_length_limit : int ) -> str :
75
76
"""Format your git message."""
76
77
77
78
@property
@@ -105,3 +106,12 @@ def process_commit(self, commit: str) -> str:
105
106
If not overwritten, it returns the first line of commit.
106
107
"""
107
108
return commit .split ("\n " )[0 ]
109
+
110
+ def _check_message_length_limit (
111
+ self , message : str , message_length_limit : int
112
+ ) -> None :
113
+ message_len = len (message )
114
+ if message_length_limit > 0 and message_len > message_length_limit :
115
+ raise CommitMessageLengthExceededError (
116
+ f"Length of commit message exceeds limit ({ message_len } /{ message_length_limit } )"
117
+ )
Original file line number Diff line number Diff line change @@ -150,7 +150,7 @@ def questions(self) -> Questions:
150
150
]
151
151
return questions
152
152
153
- def message (self , answers : dict ) -> str :
153
+ def message (self , answers : dict , message_length_limit : int = 0 ) -> str :
154
154
prefix = answers ["prefix" ]
155
155
scope = answers ["scope" ]
156
156
subject = answers ["subject" ]
@@ -167,9 +167,9 @@ def message(self, answers: dict) -> str:
167
167
if footer :
168
168
footer = f"\n \n { footer } "
169
169
170
- message = f"{ prefix } { scope } : { subject } { body } { footer } "
171
-
172
- return message
170
+ message = f"{ prefix } { scope } : { subject } "
171
+ self . _check_message_length_limit ( message , message_length_limit )
172
+ return f" { message } { body } { footer } "
173
173
174
174
def example (self ) -> str :
175
175
return (
Original file line number Diff line number Diff line change @@ -61,12 +61,15 @@ def __init__(self, config: BaseConfig):
61
61
def questions (self ) -> Questions :
62
62
return self .custom_settings .get ("questions" , [{}])
63
63
64
- def message (self , answers : dict ) -> str :
64
+ def message (self , answers : dict , message_length_limit : int = 0 ) -> str :
65
65
message_template = Template (self .custom_settings .get ("message_template" , "" ))
66
- if getattr (Template , "substitute" , None ):
67
- return message_template .substitute (** answers ) # type: ignore
68
- else :
69
- return message_template .render (** answers )
66
+ message : str = (
67
+ message_template .substitute (** answers ) # type: ignore
68
+ if getattr (Template , "substitute" , None )
69
+ else message_template .render (** answers )
70
+ )
71
+ self ._check_message_length_limit (message , message_length_limit )
72
+ return message
70
73
71
74
def example (self ) -> str | None :
72
75
return self .custom_settings .get ("example" )
Original file line number Diff line number Diff line change @@ -44,8 +44,8 @@ def questions(self) -> Questions:
44
44
]
45
45
return questions
46
46
47
- def message (self , answers ) -> str :
48
- return " " .join (
47
+ def message (self , answers : dict , message_length_limit : int = 0 ) -> str :
48
+ message = " " .join (
49
49
filter (
50
50
bool ,
51
51
[
@@ -57,6 +57,8 @@ def message(self, answers) -> str:
57
57
],
58
58
)
59
59
)
60
+ self ._check_message_length_limit (message , message_length_limit )
61
+ return message
60
62
61
63
def example (self ) -> str :
62
64
return (
Original file line number Diff line number Diff line change @@ -57,6 +57,7 @@ class Settings(TypedDict, total=False):
57
57
always_signoff : bool
58
58
template : str | None
59
59
extras : dict [str , Any ]
60
+ message_length_limit : int
60
61
61
62
62
63
name : str = "cz_conventional_commits"
@@ -102,6 +103,7 @@ class Settings(TypedDict, total=False):
102
103
"always_signoff" : False ,
103
104
"template" : None , # default provided by plugin
104
105
"extras" : {},
106
+ "message_length_limit" : 0 ,
105
107
}
106
108
107
109
MAJOR = "MAJOR"
Original file line number Diff line number Diff line change @@ -36,6 +36,7 @@ class ExitCode(enum.IntEnum):
36
36
CHANGELOG_FORMAT_UNKNOWN = 29
37
37
CONFIG_FILE_NOT_FOUND = 30
38
38
CONFIG_FILE_IS_EMPTY = 31
39
+ COMMIT_MESSAGE_LENGTH_LIMIT_EXCEEDED = 32
39
40
40
41
41
42
class CommitizenException (Exception ):
@@ -201,3 +202,7 @@ class ConfigFileNotFound(CommitizenException):
201
202
class ConfigFileIsEmpty (CommitizenException ):
202
203
exit_code = ExitCode .CONFIG_FILE_IS_EMPTY
203
204
message = "Config file is empty, please check your file path again."
205
+
206
+
207
+ class CommitMessageLengthExceededError (CommitizenException ):
208
+ exit_code = ExitCode .COMMIT_MESSAGE_LENGTH_LIMIT_EXCEEDED
Original file line number Diff line number Diff line change @@ -36,3 +36,13 @@ You can use `cz commit --retry` to reuse the last commit message when the previo
36
36
To automatically retry when running ` cz commit ` , you can set the ` retry_after_failure `
37
37
configuration option to ` true ` . Running ` cz commit --no-retry ` makes commitizen ignore ` retry_after_failure ` , forcing
38
38
a new commit message to be prompted.
39
+
40
+ ### Commit message length limit
41
+
42
+ The argument ` -l ` (or ` --message-length-limit ` ) followed by a positive number can limit the length of commit messages.
43
+ An exception would be raised when the message length exceeds the limit.
44
+ For example, ` cz commit -l 72 ` will limit the length of commit messages to 72 characters.
45
+ By default the limit is set to 0, which means no limit on the length.
46
+
47
+ Note that for ` ConventionalCommitsCz ` , the limit applies only from the prefix to the subject.
48
+ In other words, everything after the first line (the body and the footer) are not counted in the length.
Original file line number Diff line number Diff line change @@ -227,9 +227,11 @@ class JiraCz(BaseCommitizen):
227
227
]
228
228
return questions
229
229
230
- def message(self, answers: dict) -> str:
230
+ def message(self, answers: dict, message_length_limit: int = 0 ) -> str:
231
231
"""Generate the message with the given answers."""
232
- return "{0} (#{1})".format(answers["title"], answers["issue"])
232
+ message = "{0} (#{1})".format(answers["title"], answers["issue"])
233
+ self._check_message_length_limit(message, message_length_limit)
234
+ return message
233
235
234
236
def example(self) -> str:
235
237
"""Provide an example to help understand the style (OPTIONAL)
Original file line number Diff line number Diff line change @@ -204,10 +204,12 @@ def questions(self) -> list:
204
204
},
205
205
]
206
206
207
- def message (self , answers : dict ) -> str :
207
+ def message (self , answers : dict , message_length_limit : int = 0 ) -> str :
208
208
prefix = answers ["prefix" ]
209
209
subject = answers .get ("subject" , "default message" ).trim ()
210
- return f"{ prefix } : { subject } "
210
+ message = f"{ prefix } : { subject } "
211
+ self ._check_message_length_limit (message , message_length_limit )
212
+ return message
211
213
212
214
213
215
@pytest .fixture ()
@@ -220,7 +222,7 @@ class MockPlugin(BaseCommitizen):
220
222
def questions (self ) -> defaults .Questions :
221
223
return []
222
224
223
- def message (self , answers : dict ) -> str :
225
+ def message (self , answers : dict , message_length_limit : int = 0 ) -> str :
224
226
return ""
225
227
226
228
Original file line number Diff line number Diff line change 1
1
import pytest
2
2
3
3
from commitizen .cz .base import BaseCommitizen
4
+ from commitizen .exceptions import CommitMessageLengthExceededError
4
5
5
6
6
7
class DummyCz (BaseCommitizen ):
7
8
def questions (self ):
8
9
return [{"type" : "input" , "name" : "commit" , "message" : "Initial commit:\n " }]
9
10
10
- def message (self , answers ):
11
- return answers ["commit" ]
11
+ def message (self , answers : dict , message_length_limit : int = 0 ):
12
+ message = answers ["commit" ]
13
+ self ._check_message_length_limit (message , message_length_limit )
14
+ return message
12
15
13
16
14
17
def test_base_raises_error (config ):
@@ -48,3 +51,16 @@ def test_process_commit(config):
48
51
cz = DummyCz (config )
49
52
message = cz .process_commit ("test(test_scope): this is test msg" )
50
53
assert message == "test(test_scope): this is test msg"
54
+
55
+
56
+ def test_message_length_limit (config ):
57
+ cz = DummyCz (config )
58
+ commit_message = "123456789"
59
+ message_length = len (commit_message )
60
+ assert cz .message ({"commit" : commit_message }) == commit_message
61
+ assert (
62
+ cz .message ({"commit" : commit_message }, message_length_limit = message_length )
63
+ == commit_message
64
+ )
65
+ with pytest .raises (CommitMessageLengthExceededError ):
66
+ cz .message ({"commit" : commit_message }, message_length_limit = message_length - 1 )
You can’t perform that action at this time.
0 commit comments