| import re | 
 |  | 
 | from gitlint.options import IntOption | 
 | from gitlint.rules import CommitRule, RuleViolation | 
 |  | 
 |  | 
 | class BodyMaxLineLengthWithExceptions(CommitRule): | 
 |     name = "body-max-line-length-with-exceptions" | 
 |     id = "UC1" | 
 |  | 
 |     options_spec = [IntOption("line-length", 80, "Max line length")] | 
 |     line_length_violation_message = """Line exceeds max length ({0}>{1}). | 
 |     It's possible you intended to use one of the following exceptions: | 
 |     1. Put logs or shell script in a quoted section with triple quotes (''') | 
 |         before and after the section | 
 |     2. Put a long link at the bottom in a footnote. | 
 |         example: [1] https://my_long_link.com | 
 |     Line that was too long: | 
 | """ | 
 |     tabs_violation_message = "Line contains hard tab characters (\\t)" | 
 |  | 
 |     def validate(self, commit): | 
 |         in_block_comment = False | 
 |         for line in commit.message.body: | 
 |             # allow a quoted string to be over the line limit | 
 |             if ( | 
 |                 line.startswith("'''") | 
 |                 or line.startswith('"""') | 
 |                 or line.startswith("```") | 
 |             ): | 
 |                 in_block_comment = not in_block_comment | 
 |  | 
 |             if in_block_comment: | 
 |                 continue | 
 |  | 
 |             if "\t" in line: | 
 |                 return [ | 
 |                     RuleViolation(self.id, self.tabs_violation_message, line) | 
 |                 ] | 
 |  | 
 |             # allow footnote url links to be as long as needed example | 
 |             # [1] http://www.myspace.com | 
 |             ret = re.match(r"^\[\d+\]:? ", line) | 
 |             if ret is not None: | 
 |                 continue | 
 |  | 
 |             # allow signed-off-by | 
 |             if line.startswith("Signed-off-by:"): | 
 |                 continue | 
 |  | 
 |             max_length = self.options["line-length"].value | 
 |             if len(line) > max_length: | 
 |                 return [ | 
 |                     RuleViolation( | 
 |                         self.id, | 
 |                         self.line_length_violation_message.format( | 
 |                             len(line), max_length | 
 |                         ), | 
 |                         line, | 
 |                     ) | 
 |                 ] | 
 |         return None |