-
Notifications
You must be signed in to change notification settings - Fork 946
/
export_linter.py
86 lines (71 loc) · 3.21 KB
/
export_linter.py
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
import json
import os
import platform
import sys
from subprocess import PIPE, Popen
from conans import __path__ as root_path
from conans.client.output import Color
from conans.errors import ConanException
def conan_linter(conanfile_path, out):
if getattr(sys, 'frozen', False):
out.info("No linter available. Use a pip installed conan for recipe linting")
return
apply_lint = os.environ.get("CONAN_RECIPE_LINTER", True)
if not apply_lint or apply_lint == "False":
return
dir_path = os.path.dirname(root_path[0]).replace("\\", "/")
dirname = os.path.dirname(conanfile_path).replace("\\", "/")
hook = '--init-hook="import sys;sys.path.extend([\'%s\', \'%s\'])"' % (dirname, dir_path)
try:
py3_msgs = None
msgs, py3_msgs = _normal_linter(conanfile_path, hook)
except Exception as e:
out.warn("Failed pylint: %s" % e)
else:
if py3_msgs:
out.writeln("Python 3 incompatibilities\n ERROR: %s"
% "\n ERROR: ".join(py3_msgs),
front=Color.BRIGHT_MAGENTA)
if msgs:
out.writeln("Linter warnings\n WARN: %s" % "\n WARN: ".join(msgs),
front=Color.MAGENTA)
pylint_werr = os.environ.get("CONAN_PYLINT_WERR", None)
if pylint_werr and (py3_msgs or msgs):
raise ConanException("Package recipe has linter errors. Please fix them.")
def _runner(args):
command = ["pylint", "--output-format=json"] + args
command = " ".join(command)
shell = True if platform.system() != "Windows" else False
proc = Popen(command, shell=shell, bufsize=10, stdout=PIPE, stderr=PIPE)
stdout, _ = proc.communicate()
return json.loads(stdout.decode("utf-8")) if stdout else {}
def _normal_linter(conanfile_path, hook):
args = ["--py3k", "--enable=all", "--reports=no", "--disable=no-absolute-import",
"--persistent=no", "--load-plugins=conans.pylint_plugin",
hook, '"%s"' % conanfile_path]
pylintrc = os.environ.get("CONAN_PYLINTRC", None)
if pylintrc:
if not os.path.exists(pylintrc):
raise ConanException("File %s defined by PYLINTRC doesn't exist" % pylintrc)
args.append('--rcfile="%s"' % pylintrc)
output_json = _runner(args)
def _accept_message(msg):
symbol = msg.get("symbol")
if symbol in ("bare-except", "broad-except"): # No exception type(s) specified
return False
if symbol == "import-error" and msg.get("column") > 3: # Import of a conan python package
return False
if symbol == "no-name-in-module" and "python_requires" in msg.get("message"):
return False
return True
result = []
py3msgs = []
for msg in output_json:
if msg.get("type") in ("warning", "error"):
message_id = msg.get("symbol")
if message_id in ("print-statement", "dict-iter-method"):
py3msgs.append("Py3 incompatibility. Line %s: %s"
% (msg.get("line"), msg.get("message")))
elif _accept_message(msg):
result.append("Linter. Line %s: %s" % (msg.get("line"), msg.get("message")))
return result, py3msgs