1#!/usr/bin/env python 2# 3# Common lint functions applicable to multiple types of files. 4 5from __future__ import print_function 6import re 7 8def VerifyLineLength(filename, lines, max_length): 9 """Checks to make sure the file has no lines with lines exceeding the length 10 limit. 11 12 Args: 13 filename: the file under consideration as string 14 lines: contents of the file as string array 15 max_length: maximum acceptable line length as number 16 17 Returns: 18 A list of tuples with format [(filename, line number, msg), ...] with any 19 violations found. 20 """ 21 lint = [] 22 line_num = 1 23 for line in lines: 24 length = len(line.rstrip('\n')) 25 if length > max_length: 26 lint.append((filename, line_num, 27 'Line exceeds %d chars (%d)' % (max_length, length))) 28 line_num += 1 29 return lint 30 31def VerifyTabs(filename, lines): 32 """Checks to make sure the file has no tab characters. 33 34 Args: 35 filename: the file under consideration as string 36 lines: contents of the file as string array 37 38 Returns: 39 A list of tuples with format [(line_number, msg), ...] with any violations 40 found. 41 """ 42 lint = [] 43 tab_re = re.compile(r'\t') 44 line_num = 1 45 for line in lines: 46 if tab_re.match(line.rstrip('\n')): 47 lint.append((filename, line_num, 'Tab found instead of whitespace')) 48 line_num += 1 49 return lint 50 51 52def VerifyTrailingWhitespace(filename, lines): 53 """Checks to make sure the file has no lines with trailing whitespace. 54 55 Args: 56 filename: the file under consideration as string 57 lines: contents of the file as string array 58 59 Returns: 60 A list of tuples with format [(filename, line number, msg), ...] with any 61 violations found. 62 """ 63 lint = [] 64 trailing_whitespace_re = re.compile(r'\s+$') 65 line_num = 1 66 for line in lines: 67 if trailing_whitespace_re.match(line.rstrip('\n')): 68 lint.append((filename, line_num, 'Trailing whitespace')) 69 line_num += 1 70 return lint 71 72 73class BaseLint: 74 def RunOnFile(filename, lines): 75 raise Exception('RunOnFile() unimplemented') 76 77 78def RunLintOverAllFiles(linter, filenames): 79 """Runs linter over the contents of all files. 80 81 Args: 82 lint: subclass of BaseLint, implementing RunOnFile() 83 filenames: list of all files whose contents will be linted 84 85 Returns: 86 A list of tuples with format [(filename, line number, msg), ...] with any 87 violations found. 88 """ 89 lint = [] 90 for filename in filenames: 91 file = open(filename, 'r') 92 if not file: 93 print('Cound not open %s' % filename) 94 continue 95 lines = file.readlines() 96 lint.extend(linter.RunOnFile(filename, lines)) 97 98 return lint 99