Ed Tanous | fb9948a | 2022-06-21 09:10:24 -0700 | [diff] [blame] | 1 | import re |
Patrick Williams | e08ffba | 2022-12-05 10:33:46 -0600 | [diff] [blame] | 2 | |
Ed Tanous | fb9948a | 2022-06-21 09:10:24 -0700 | [diff] [blame] | 3 | from gitlint.options import IntOption |
Patrick Williams | e08ffba | 2022-12-05 10:33:46 -0600 | [diff] [blame] | 4 | from gitlint.rules import CommitRule, RuleViolation |
Ed Tanous | fb9948a | 2022-06-21 09:10:24 -0700 | [diff] [blame] | 5 | |
| 6 | |
| 7 | class 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: |
Patrick Williams | e08ffba | 2022-12-05 10:33:46 -0600 | [diff] [blame] | 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 |
Ed Tanous | fb9948a | 2022-06-21 09:10:24 -0700 | [diff] [blame] | 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: |
Patrick Williams | e08ffba | 2022-12-05 10:33:46 -0600 | [diff] [blame] | 37 | return [ |
| 38 | RuleViolation(self.id, self.tabs_violation_message, line) |
| 39 | ] |
Ed Tanous | fb9948a | 2022-06-21 09:10:24 -0700 | [diff] [blame] | 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 |