On 9/29/26 1:00 PM, Ales Musil wrote:
> Long commit message lines are difficult to read after git and email add
> indentation or quotation prefixes. Enforce the documented 75-character
> limit while allowing Git-style trailers to remain unwrapped.
>
> Add coverage for boundary values, trailer exemptions, and raw email
> input.
>
> Assisted-by: GPT-5.6-Sol, OpenCode
> Signed-off-by: Ales Musil <[email protected]>
> ---
Hi Ales,
> tests/checkpatch.at | 103 ++++++++++++++++++++++++++++++++++++++++
> utilities/checkpatch.py | 16 ++++++-
> 2 files changed, 117 insertions(+), 2 deletions(-)
>
> diff --git a/tests/checkpatch.at b/tests/checkpatch.at
> index 352a5f4d2..af95579bf 100755
> --- a/tests/checkpatch.at
> +++ b/tests/checkpatch.at
> @@ -39,6 +39,23 @@ try_checkpatch__() {
> AT_CHECK([$1 $top_srcdir/utilities/checkpatch.py -q test.patch])
> fi
> }
> +
> +try_checkpatch_stdin() {
> + echo "$1" | sed 's/^ //' > test.patch
> + if test -n "$2"; then
> + echo "$2" | sed 's/^ //' > expout
> + else
> + : > expout
> + fi
> +
> + if test -s expout; then
> + AT_CHECK([$PYTHON3 $top_srcdir/utilities/checkpatch.py -q <
> test.patch],
> + [1], [stdout])
> + AT_CHECK([sed '/^Lines checked:/,$d' stdout], [0], [expout])
> + else
> + AT_CHECK([$PYTHON3 $top_srcdir/utilities/checkpatch.py -q <
> test.patch])
> + fi
> +}
> OVS_END_SHELL_HELPERS
>
> AT_SETUP([checkpatch - sign-offs])
> @@ -433,6 +450,92 @@ try_checkpatch \
>
> AT_CLEANUP
>
> +AT_SETUP([checkpatch - commit message body length])
> +
> +body_75=$(printf '%75s' '' | tr ' ' x)
> +body_76=${body_75}x
> +long_tag_value=$(printf '%80s' '' | tr ' ' x)
> +
> +try_checkpatch \
> + "Author: A
> + Commit: A
> +
> + $body_75
> + Signed-off-by: A"
> +
> +try_checkpatch \
> + "Author: A
> + Commit: A
> +
> + $body_76
> + Signed-off-by: A" \
> + "WARNING: Commit message body line is 76 characters long (recommended
> limit is 75)
> + 1: $body_76
> +"
> +
> +try_checkpatch_stdin \
> + "Author: A
> + Commit: A
> + Subject: checkpatch: Test body length.
> + $long_tag_value
> +
> + $body_76
> + Signed-off-by: A
> + ---" \
> + "WARNING: Commit message body line is 76 characters long (recommended
> limit is 75)
> + 6: $body_76
> +"
> +
> +try_checkpatch \
> + "Author: A
> + Commit: A
> +
> + Acked-by: B
> + Tested-at: https://example.com/test/1
> + Link: https://example.com/reviews/$long_tag_value
> + Arbitrary-Tag: $long_tag_value
> + Reported-at: https://example.com/bugs/$long_tag_value
> + Assisted-by: $long_tag_value
> + Fixes: 123456789abc (\"$long_tag_value\")
> + Signed-off-by: A"
> +
> +try_checkpatch \
> + "Author: A
> + Commit: A
> +
> + This is ordinary prose with a colon: $long_tag_value
> + Signed-off-by: A" \
> + "WARNING: Commit message body line is 117 characters long (recommended
> limit is 75)
> + 1: This is ordinary prose with a colon: $long_tag_value
> +"
> +
> +try_checkpatch \
> + "Author: A
> + Commit: A
> +
> + Not/A/Trailer: $long_tag_value
> + Signed-off-by: A" \
> + "WARNING: Commit message body line is 95 characters long (recommended
> limit is 75)
> + 1: Not/A/Trailer: $long_tag_value
> +"
> +
> +raw_patch="From 123456789abc Mon Sep 17 00:00:00 2001
> +From: A
> +Date: Tue, 29 Sep 2026 08:00:00 +0000
> +X-Long-Header: $long_tag_value
> + $long_tag_value
> +Subject: [PATCH] checkpatch: Test body length.
> +
> +$body_75
> +Link: https://example.com/reviews/$long_tag_value
> +Signed-off-by: A
> +---"
> +
> +try_checkpatch "$raw_patch"
> +try_checkpatch_stdin "$raw_patch"
> +
> +AT_CLEANUP
> +
> AT_SETUP([checkpatch - malformed tags])
> try_checkpatch \
> " Author: A
> diff --git a/utilities/checkpatch.py b/utilities/checkpatch.py
> index d644db9e1..49de50b19 100755
> --- a/utilities/checkpatch.py
> +++ b/utilities/checkpatch.py
> @@ -886,7 +886,8 @@ def run_subject_checks(subject, spellcheck=False):
> return warnings
>
>
> -def ovs_checkpatch_parse(text, filename, author=None, committer=None):
> +def ovs_checkpatch_parse(text, filename, author=None, committer=None,
> + body_only=False):
> global print_file_name, total_line, checking_file, \
> empty_return_check_state
>
> @@ -915,6 +916,7 @@ def ovs_checkpatch_parse(text, filename, author=None,
> committer=None):
> re.I | re.M | re.S)
> is_fixes = re.compile(r'(\s*(Fixes:)(.*))$', re.I | re.M | re.S)
> is_fixes_exact = re.compile(r'^Fixes: [0-9a-f]{12} \(".*"\)$')
> + is_trailer = re.compile(r'^[A-Za-z0-9][A-Za-z0-9-]*:[ \t]+\S')
>
> tags_typos = {
> r'^Acked by:': 'Acked-by:',
> @@ -929,6 +931,8 @@ def ovs_checkpatch_parse(text, filename, author=None,
> committer=None):
> reset_counters()
>
> current_line = ""
> + subject_seen = False
> + in_commit_body = body_only
> for line in text.split("\n"):
> if current_file != previous_file:
> previous_file = current_file
> @@ -953,6 +957,8 @@ def ovs_checkpatch_parse(text, filename, author=None,
> committer=None):
> # Form feed
> continue
> if len(line) <= 0:
> + if subject_seen:
> + in_commit_body = True
> continue
>
> if checking_file:
> @@ -1022,6 +1028,7 @@ def ovs_checkpatch_parse(text, filename, author=None,
> committer=None):
> elif is_author.match(line):
> author = is_author.match(line).group(2)
> elif is_subject.match(line):
> + subject_seen = True
> run_subject_checks(line, spellcheck)
> elif is_signature.match(line):
> m = is_signature.match(line)
> @@ -1041,6 +1048,11 @@ def ovs_checkpatch_parse(text, filename, author=None,
> committer=None):
> '--pretty=format:"Fixes: %h (\\\"%s\\\")" '
> '--abbrev=12 COMMIT_REF\n')
> print("%d: %s\n" % (lineno, line))
> + elif (in_commit_body and len(line) > 75
> + and not is_trailer.match(line)):
> + print_warning("Commit message body line is %d characters "
> + "long (recommended limit is 75)" % len(line))
> + print("%d: %s\n" % (lineno, line))
> elif spellcheck:
> check_spelling(line, False)
We'd skip spell checking for long lines. That's not that bad but we
could probably fix it if we do:
else:
if (in_commit_body and len(line) > 75
and not is_trailer.match(line)):
print_warning("Commit message body line is %d characters "
"long (recommended limit is 75)" % len(line))
print("%d: %s\n" % (lineno, line))
if spellcheck:
check_spelling(line, False)
I can fold that in, what do you think?
> for typo, correct in tags_typos.items():
> @@ -1138,7 +1150,7 @@ def ovs_checkpatch_file(filename):
> continue
> result = ovs_checkpatch_parse(part.get_payload(decode=False), filename,
> mail.get('Author', mail['From']),
> - mail['Commit'])
> + mail['Commit'], body_only=True)
>
> if not mail['Subject'] or not mail['Subject'].strip():
> if mail['Subject']:
Regards,
Dumitru
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev