diff --git a/python/mozlint/mozlint/cli.py b/python/mozlint/mozlint/cli.py index a4e0f0210256..24ecde8cc65d 100644 --- a/python/mozlint/mozlint/cli.py +++ b/python/mozlint/mozlint/cli.py @@ -6,6 +6,7 @@ import os import sys from argparse import REMAINDER, SUPPRESS, ArgumentParser +from mozlint.errors import NoValidLinter from mozlint.formatters import all_formatters @@ -252,7 +253,9 @@ def find_linters(config_paths, linters=None): continue lints[name] = os.path.join(search_path, f) - return lints.values() + + linters_not_found = list(set(linters).difference(set(lints.keys()))) + return {"lint_paths": lints.values(), "linters_not_found": linters_not_found} def run( @@ -278,27 +281,44 @@ def run( if list_linters: lint_paths = find_linters(lintargs["config_paths"], linters) - linters = [os.path.splitext(os.path.basename(l))[0] for l in lint_paths] + linters = [ + os.path.splitext(os.path.basename(l))[0] for l in lint_paths["lint_paths"] + ] print("\n".join(sorted(linters))) return 0 lint = LintRoller(**lintargs) - lint.read(find_linters(lintargs["config_paths"], linters)) + linters_info = find_linters(lintargs["config_paths"], linters) - # Always run bootstrapping, but return early if --setup was passed in. - ret = lint.setup(virtualenv_manager=virtualenv_manager) - if setup: - return ret + result = None - # run all linters - result = lint.roll( - paths, outgoing=outgoing, workdir=workdir, rev=rev, num_procs=num_procs - ) + try: + + lint.read(linters_info["lint_paths"]) + + # Always run bootstrapping, but return early if --setup was passed in. + ret = lint.setup(virtualenv_manager=virtualenv_manager) + if setup: + return ret + + if linters_info["linters_not_found"] != []: + raise NoValidLinter + + # run all linters + result = lint.roll( + paths, outgoing=outgoing, workdir=workdir, rev=rev, num_procs=num_procs + ) + except NoValidLinter as e: + result = lint.result + print(str(e)) if edit and result.issues: edit_issues(result) result = lint.roll(result.issues.keys(), num_procs=num_procs) + for every in linters_info["linters_not_found"]: + result.failed_setup.add(every) + for formatter_name, path in formats: formatter = formatters.get(formatter_name) diff --git a/python/mozlint/mozlint/errors.py b/python/mozlint/mozlint/errors.py index 9102a88f80f7..4b36f00f69ab 100644 --- a/python/mozlint/mozlint/errors.py +++ b/python/mozlint/mozlint/errors.py @@ -12,6 +12,14 @@ class LinterNotFound(LintException): LintException.__init__(self, "Could not find lint file '{}'".format(path)) +class NoValidLinter(LintException): + def __init__(self): + LintException.__init__( + self, + "Invalid linters given, run again using valid linters or no linters", + ) + + class LinterParseError(LintException): def __init__(self, path, message): LintException.__init__(self, "{}: {}".format(path, message)) diff --git a/python/mozlint/mozlint/roller.py b/python/mozlint/mozlint/roller.py index 31044432f57f..b498c53317dc 100644 --- a/python/mozlint/mozlint/roller.py +++ b/python/mozlint/mozlint/roller.py @@ -25,7 +25,7 @@ from mozversioncontrol import ( InvalidRepoPath, ) -from .errors import LintersNotConfigured +from .errors import LintersNotConfigured, NoValidLinter from .parser import Parser from .pathutils import findobject from .result import ResultSummary @@ -189,7 +189,7 @@ class LintRoller(object): def setup(self, virtualenv_manager=None): """Run setup for applicable linters""" if not self.linters: - raise LintersNotConfigured + raise NoValidLinter for linter in self.linters: if "setup" not in linter: diff --git a/python/mozlint/test/test_cli.py b/python/mozlint/test/test_cli.py index e9be01f1850d..1a303e3be10c 100644 --- a/python/mozlint/test/test_cli.py +++ b/python/mozlint/test/test_cli.py @@ -94,5 +94,17 @@ def test_cli_run_with_setup(run, capfd): assert ret == 1 +def test_cli_run_with_wrong_linters(run, capfd): + + run(["-l", "external", "-l", "foobar"]) + out, err = capfd.readouterr() + + # Check if it identifes foobar as invalid linter + assert "A failure occurred in the foobar linter." in out + + # Check for exception message + assert "Invalid linters given, run again using valid linters or no linters" in out + + if __name__ == "__main__": mozunit.main() diff --git a/python/mozlint/test/test_roller.py b/python/mozlint/test/test_roller.py index 3d9679efb194..691f7f7e6419 100644 --- a/python/mozlint/test/test_roller.py +++ b/python/mozlint/test/test_roller.py @@ -12,7 +12,7 @@ import time import mozunit import pytest -from mozlint.errors import LintersNotConfigured +from mozlint.errors import LintersNotConfigured, NoValidLinter from mozlint.result import Issue, ResultSummary from itertools import chain @@ -311,7 +311,7 @@ def test_support_files(lint, linters, filedir, monkeypatch, files): def test_setup(lint, linters, filedir, capfd): - with pytest.raises(LintersNotConfigured): + with pytest.raises(NoValidLinter): lint.setup() lint.read(linters("setup", "setupfailed", "setupraised"))