Backed out changeset e8fcfc7f8108 (bug 1811850) Backed out changeset f8950d716c9e (bug 1811850) Backed out changeset f650123cc188 (bug 1811850) Backed out changeset d96f90c2c58b (bug 1811850) Backed out changeset c3b0f9666183 (bug 1811850)
134 lines
3.7 KiB
Python
134 lines
3.7 KiB
Python
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
import json
|
|
import os
|
|
import signal
|
|
import subprocess
|
|
|
|
from mach.site import InstallPipRequirementsException
|
|
from mozlint import result
|
|
from mozlint.pathutils import expand_exclusions
|
|
from mozprocess import ProcessHandler
|
|
|
|
here = os.path.abspath(os.path.dirname(__file__))
|
|
PYLINT_REQUIREMENTS_PATH = os.path.join(here, "pylint_requirements.txt")
|
|
|
|
PYLINT_NOT_FOUND = """
|
|
Could not find pylint! Install pylint and try again.
|
|
|
|
$ pip install -U --require-hashes -r {}
|
|
""".strip().format(
|
|
PYLINT_REQUIREMENTS_PATH
|
|
)
|
|
|
|
|
|
PYLINT_INSTALL_ERROR = """
|
|
Unable to install correct version of pylint
|
|
Try to install it manually with:
|
|
$ pip install -U --require-hashes -r {}
|
|
""".strip().format(
|
|
PYLINT_REQUIREMENTS_PATH
|
|
)
|
|
|
|
|
|
class PylintProcess(ProcessHandler):
|
|
def __init__(self, config, *args, **kwargs):
|
|
self.config = config
|
|
kwargs["stream"] = False
|
|
kwargs["universal_newlines"] = True
|
|
ProcessHandler.__init__(self, *args, **kwargs)
|
|
|
|
def run(self, *args, **kwargs):
|
|
orig = signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
ProcessHandler.run(self, *args, **kwargs)
|
|
signal.signal(signal.SIGINT, orig)
|
|
|
|
|
|
def setup(root, **lintargs):
|
|
virtualenv_manager = lintargs["virtualenv_manager"]
|
|
try:
|
|
virtualenv_manager.install_pip_requirements(
|
|
PYLINT_REQUIREMENTS_PATH,
|
|
quiet=True,
|
|
)
|
|
except (subprocess.CalledProcessError, InstallPipRequirementsException):
|
|
print(PYLINT_INSTALL_ERROR)
|
|
return 1
|
|
|
|
|
|
def get_pylint_binary():
|
|
return "pylint"
|
|
|
|
|
|
def run_process(config, cmd):
|
|
proc = PylintProcess(config, cmd)
|
|
proc.run()
|
|
try:
|
|
proc.wait()
|
|
except KeyboardInterrupt:
|
|
proc.kill()
|
|
|
|
return proc.output
|
|
|
|
|
|
def parse_issues(log, config, issues_json, path):
|
|
results = []
|
|
|
|
try:
|
|
issues = json.loads(issues_json)
|
|
except json.decoder.JSONDecodeError:
|
|
log.debug("Could not parse the output:")
|
|
log.debug("pylint output: {}".format(issues_json))
|
|
return []
|
|
|
|
for issue in issues:
|
|
res = {
|
|
"path": issue["path"],
|
|
"level": issue["type"],
|
|
"lineno": issue["line"],
|
|
"column": issue["column"],
|
|
"message": issue["message"],
|
|
"rule": issue["message-id"],
|
|
}
|
|
results.append(result.from_config(config, **res))
|
|
return results
|
|
|
|
|
|
def get_pylint_version(binary):
|
|
return subprocess.check_output(
|
|
[binary, "--version"],
|
|
universal_newlines=True,
|
|
stderr=subprocess.STDOUT,
|
|
)
|
|
|
|
|
|
def lint(paths, config, **lintargs):
|
|
log = lintargs["log"]
|
|
|
|
binary = get_pylint_binary()
|
|
|
|
log = lintargs["log"]
|
|
paths = list(expand_exclusions(paths, config, lintargs["root"]))
|
|
|
|
cmd_args = [binary]
|
|
results = []
|
|
|
|
# list from https://code.visualstudio.com/docs/python/linting#_pylint
|
|
# And ignore a bit more elements
|
|
cmd_args += [
|
|
"-fjson",
|
|
"--disable=all",
|
|
"--enable=F,E,unreachable,duplicate-key,unnecessary-semicolon,global-variable-not-assigned,unused-variable,binary-op-exception,bad-format-string,anomalous-backslash-in-string,bad-open-mode,no-else-return", # NOQA: E501
|
|
"--disable=import-error,no-member",
|
|
]
|
|
|
|
base_command = cmd_args + paths
|
|
log.debug("Command: {}".format(" ".join(cmd_args)))
|
|
log.debug("pylint version: {}".format(get_pylint_version(binary)))
|
|
output = " ".join(run_process(config, base_command))
|
|
results = parse_issues(log, config, str(output), [])
|
|
|
|
return results
|