blob: 8f5b51f5f795552904069adfeffafae6f3369e2a [file] [log] [blame]
Ed Tanousfb9948a2022-06-21 09:10:24 -07001import re
2from gitlint.rules import CommitRule, RuleViolation
3from gitlint.options import IntOption
4
5
6class BodyMaxLineLengthWithExceptions(CommitRule):
7 name = "body-max-line-length-with-exceptions"
8 id = "UC1"
9
10 options_spec = [IntOption("line-length", 80, "Max line length")]
11 line_length_violation_message = """Line exceeds max length ({0}>{1}).
12 It's possible you intended to use one of the following exceptions:
13 1. Put logs or shell script in a quoted section with triple quotes (''') before and after the section
14 2. Put a long link at the bottom in a footnote. example: [1] https://my_long_link.com
15 Line that was too long:
16"""
17 tabs_violation_message = "Line contains hard tab characters (\\t)"
18
19 def validate(self, commit):
20 in_block_comment = False
21 for line in commit.message.body:
22 # allow a quoted string to be over the line limit
23 if (
24 line.startswith("'''")
25 or line.startswith('"""')
26 or line.startswith("```")
27 ):
28 in_block_comment = not in_block_comment
29
30 if in_block_comment:
31 continue
32
33 if "\t" in line:
34 return [RuleViolation(self.id, self.tabs_violation_message, line)]
35
36 # allow footnote url links to be as long as needed example
37 # [1] http://www.myspace.com
38 ret = re.match(r"^\[\d+\]:? ", line)
39 if ret is not None:
40 continue
41
42 # allow signed-off-by
43 if line.startswith("Signed-off-by:"):
44 continue
45
46 max_length = self.options["line-length"].value
47 if len(line) > max_length:
48 return [
49 RuleViolation(
50 self.id,
51 self.line_length_violation_message.format(
52 len(line), max_length
53 ),
54 line,
55 )
56 ]
57 return None