|  |  | @ -33,6 +33,10 @@ class Linter(object): | 
			
		
	
		
		
			
				
					
					|  |  |  |         if len(failures): |  |  |  |         if len(failures): | 
			
		
	
		
		
			
				
					
					|  |  |  |             raise LinterError('%s: %s' % (self.msg, self.display_lines(failures, len(lines)))) |  |  |  |             raise LinterError('%s: %s' % (self.msg, self.display_lines(failures, len(lines)))) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     def fix(self, lines): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         for i in range(len(lines)): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             lines[i] = self.fix_line(lines[i]) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     def display_lines(self, lines, total): |  |  |  |     def display_lines(self, lines, total): | 
			
		
	
		
		
			
				
					
					|  |  |  |         if len(lines) == total - 1: |  |  |  |         if len(lines) == total - 1: | 
			
		
	
		
		
			
				
					
					|  |  |  |             return 'entire file' |  |  |  |             return 'entire file' | 
			
		
	
	
		
		
			
				
					|  |  | @ -62,22 +66,29 @@ class NewlineLinter(Linter): | 
			
		
	
		
		
			
				
					
					|  |  |  |     msg = 'Contains DOS-style newlines' |  |  |  |     msg = 'Contains DOS-style newlines' | 
			
		
	
		
		
			
				
					
					|  |  |  |     def check_line(self, line): |  |  |  |     def check_line(self, line): | 
			
		
	
		
		
			
				
					
					|  |  |  |         return '\r' not in line |  |  |  |         return '\r' not in line | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     def fix_line(self, line): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         return line.replace('\r', '') | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | class TrailingWhitespaceLinter(Linter): |  |  |  | class TrailingWhitespaceLinter(Linter): | 
			
		
	
		
		
			
				
					
					|  |  |  |     msg = 'Contains trailing whitespace' |  |  |  |     msg = 'Contains trailing whitespace' | 
			
		
	
		
		
			
				
					
					|  |  |  |     def check_line(self, line): |  |  |  |     def check_line(self, line): | 
			
		
	
		
		
			
				
					
					|  |  |  |         line = line.replace('\r', '') |  |  |  |         line = line.replace('\r', '') | 
			
		
	
		
		
			
				
					
					|  |  |  |         return not line.endswith(' ') and not line.endswith('\t') |  |  |  |         return not line.endswith(' ') and not line.endswith('\t') | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     def fix_line(self, line): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         return line.rstrip('\t ') | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | class TabLinter(Linter): |  |  |  | class TabLinter(Linter): | 
			
		
	
		
		
			
				
					
					|  |  |  |     msg = 'Contains tabs' |  |  |  |     msg = 'Contains tabs' | 
			
		
	
		
		
			
				
					
					|  |  |  |     def check_line(self, line): |  |  |  |     def check_line(self, line): | 
			
		
	
		
		
			
				
					
					|  |  |  |         return '\t' not in line |  |  |  |         return '\t' not in line | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     def fix_line(self, line): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         return line.replace('\t', '    ') | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | linters = [NewlineLinter(), TrailingWhitespaceLinter(), TabLinter()] |  |  |  | linters = [NewlineLinter(), TrailingWhitespaceLinter(), TabLinter()] | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | def main(): |  |  |  | def main(): | 
			
		
	
		
		
			
				
					
					|  |  |  |     root_path = os.path.abspath(sys.argv[1] if len(sys.argv) > 1 else '.') |  |  |  |     root_path = os.path.abspath(sys.argv[1] if len(sys.argv) > 1 else '.') | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     fix = (len(sys.argv) > 2 and sys.argv[2] == '--fix') | 
			
		
	
		
		
			
				
					
					|  |  |  |     global path_blacklist |  |  |  |     global path_blacklist | 
			
		
	
		
		
			
				
					
					|  |  |  |     path_blacklist = map(lambda s: os.path.join(root_path, s), path_blacklist) |  |  |  |     path_blacklist = map(lambda s: os.path.join(root_path, s), path_blacklist) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -87,6 +98,7 @@ def main(): | 
			
		
	
		
		
			
				
					
					|  |  |  |             rel_path = full_path.replace(root_path, '.') |  |  |  |             rel_path = full_path.replace(root_path, '.') | 
			
		
	
		
		
			
				
					
					|  |  |  |             if not valid_file(full_path): |  |  |  |             if not valid_file(full_path): | 
			
		
	
		
		
			
				
					
					|  |  |  |                 continue |  |  |  |                 continue | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             lines = [] | 
			
		
	
		
		
			
				
					
					|  |  |  |             with open(full_path, 'rb') as f: |  |  |  |             with open(full_path, 'rb') as f: | 
			
		
	
		
		
			
				
					
					|  |  |  |                 lines = f.read().split('\n') |  |  |  |                 lines = f.read().split('\n') | 
			
		
	
		
		
			
				
					
					|  |  |  |             for linter in linters: |  |  |  |             for linter in linters: | 
			
		
	
	
		
		
			
				
					|  |  | @ -94,6 +106,11 @@ def main(): | 
			
		
	
		
		
			
				
					
					|  |  |  |                     linter.check(lines) |  |  |  |                     linter.check(lines) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 except LinterError as e: |  |  |  |                 except LinterError as e: | 
			
		
	
		
		
			
				
					
					|  |  |  |                     error('%s: %s' % (rel_path, e)) |  |  |  |                     error('%s: %s' % (rel_path, e)) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     if fix: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         linter.fix(lines) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         contents = '\n'.join(lines) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         with open(full_path, 'wb') as f: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             f.write(contents) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if success: |  |  |  |     if success: | 
			
		
	
		
		
			
				
					
					|  |  |  |         print('All linters completed successfully') |  |  |  |         print('All linters completed successfully') | 
			
		
	
	
		
		
			
				
					|  |  | 
 |