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