forked from adamhajari/spyre
-
Notifications
You must be signed in to change notification settings - Fork 1
/
pylinter
executable file
·153 lines (124 loc) · 3.36 KB
/
pylinter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env python
"""
Lint python files before commit with flake8 lint tool.
INSTALL:
1. sudo pip install flake8
2. to setup up pre-commit hook run "./nbslint --setup"
To run on the entire repo run
$ ./nbslint --all
"""
import sys
import subprocess
import argparse
import os
try:
import flake8
except Exception:
print('you need to install flake8. Run "pip install flake8" and try again.')
raise
LINTER = 'flake8'
# available settings list
AVAILABLE_SETTINGS = (
'exclude', 'filename', 'select', 'ignore', 'max-line-length', 'count',
'quiet', 'show-pep8', 'show-source', 'statistics', 'verbose'
)
SETTINGS_WITH_PARAMS = (
'exclude', 'filename', 'select', 'ignore', 'max-line-length', 'format'
)
FILES_TO_IGNORE = [
'.tox/',
'build/',
'docs/source/conf.py'
]
CONFIG = {
'max-line-length': 100,
'exclude': ','.join(FILES_TO_IGNORE),
'ignore': 'F401,E402,W503,E711'
}
def parse_settings():
"""
Get lint settings
"""
settings = list()
for key, value in CONFIG.items():
if key in SETTINGS_WITH_PARAMS:
settings.append("--%s=%s" % (key, value))
else:
settings.append("--%s" % key)
return settings
def system(*args, **kwargs):
"""
Run system command.
"""
kwargs.setdefault('stdout', subprocess.PIPE)
proc = subprocess.Popen(args, **kwargs)
out, err = proc.communicate()
return out
def get_changed_files():
"""
Get python files from 'files to commit' git cache list.
"""
files = []
filelist = system('git', 'diff', '--cached', '--name-status').strip()
for line in filelist.split('\n'):
try:
action, filename = line.strip().split()
if filename.endswith('.py') and action != 'D':
files.append(filename)
except Exception:
pass
return files
def lint(files, settings):
"""
Run linter.
"""
args = settings[:]
args.insert(0, LINTER)
args.extend(files)
out = system(*args)
return filter(None, out.decode('utf8').strip().split('\n'))
def setup():
src = '../../nbslint'
dst = '.git/hooks/pre-commit'
if os.path.exists(dst):
print('%s already exists' % dst)
return
print("creating sym link from %s to %s" % (src, dst))
os.symlink(src, dst)
return
def main(args):
"""
Do work
"""
if args.setup:
setup()
return
settings = parse_settings()
errors = list()
if args.all:
files = ['.']
else:
files = get_changed_files()
if len(files) == 0:
print("No files are staged for commit. Run with the --all flag to run on all files")
return
for err in lint(files, settings):
divider = err.find(' ', err.find(' ') + 1)
pep8_error = err[0:divider]
if not any(error[0:divider] == pep8_error for error in errors):
errors.append(err)
if not errors:
print("Python lint: OK")
return
print("Python lint: FAIL")
print
print("\n".join(sorted(errors)))
print
print("Aborting commit due to python lint errors.")
sys.exit(1)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Process Config Location")
parser.add_argument('--all', action='store_true')
parser.add_argument('--setup', action='store_true')
args = parser.parse_args()
main(args)