Ed Tanous | fb9948a | 2022-06-21 09:10:24 -0700 | [diff] [blame] | 1 | import re |
| 2 | from gitlint.rules import CommitRule, RuleViolation |
| 3 | from gitlint.options import IntOption |
| 4 | |
| 5 | |
| 6 | class 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 |