#!/usr/bin/env python
from __future__ import absolute_import, division, print_function
import argparse
from collections import OrderedDict
import os
import sys
def eprint(*args, **kwargs):
kwargs['file'] = sys.stderr
print(*args, **kwargs)
parser = argparse.ArgumentParser(
description='Detect lines longer than 79 columns')
aa = parser.add_argument
aa(dest='files', metavar='files', nargs='*')
aa('-c', '--columns', dest='cols', type=int, default=79)
aa('-t', '--tab-width', dest='tabw', type=int, default=4)
aa('--no-color', dest='no_color', action='store_true')
args = parser.parse_args()
try:
if args.no_color:
def colored(text, *args, **kwargs):
return text
else:
from termcolor import colored
except ImportError:
def colored(text, *args, **kwargs):
return text
C = args.cols
labelFmt = '%s[%d]: ' # filename and line number
fileErrors = OrderedDict() # { filename -> errors }
# errors :: [(line number, obedient text, overflow text)]
def errorColor(s):
return colored(s, 'white', on_color='on_red')
def validColor(s):
return colored(s, 'green', attrs=['bold'])
def tabsToSpaces(line):
return line.replace('\t', ' ' * args.tabw)
for f in args.files:
if f in fileErrors:
continue
if not os.access(f, os.R_OK):
eprint('Could not read file "%s"' % f)
continue
fileErrors[f] = []
for i, line in enumerate(open(f), 1):
line = tabsToSpaces(line)
if line[-1] == '\n':
line = line[:-1]
if len(line) > C:
fileErrors[f].append((i, line[:C], errorColor(line[C:])))
someErrors = False
for f, errors in fileErrors.items():
# File heading
if not errors:
continue
someErrors = True
print(errorColor('%s has lines exceeding %d columns:' % (f, C)))
# Some formatting: find the longest string in 'filename[line#]'
labelMax = max(map(lambda x: len(labelFmt % (f, x[0])), errors))
for (i, good, bad) in errors:
label = (labelFmt % (f, i)).ljust(labelMax)
print('%s%s%s' % (label, good, bad))
print()
if someErrors:
sys.exit(1)