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