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