Commit bbd3ba0a authored by Andrew Halberstadt's avatar Andrew Halberstadt
Browse files

Bug 1460856 - [mozlint] Encapsulate all result state in a ResultSummary class r=sylvestre

Currently there are 3 things that can impact the result of a lint run:

1. The list of lint issues found
2. The set of failures that happened during the setup phase
3. The set of failures that happened during the execution phase

All three of these things are stored as instance variables on the LintRoller
object, and then passed into a formatter when it comes time to print the
results. I'd like to add even more things that can impact the result, and it
became clear that the current scenario does not scale well.

This patch moves all data that could impact the end result of a lint run off of
the LintRoller object and onto a new 'result.ResultSummary' class. To avoid
confusion, this patch also renames the 'result.ResultContainer' class to
'result.Issue'.

With this new nomenclature:

result  -> overall state of an entire lint run (can comprise multiple linters)
issue   -> one specific lint infraction (at either 'warning' or 'error' level)
failure -> a non-recoverable error in the linter implementation itself

A "result" is comprised of 0 or more "issues" and 0 or more "failures".

Differential Revision: https://phabricator.services.mozilla.com/D3819

--HG--
extra : moz-landing-system : lando
parent 10b80b68
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6,4 +6,4 @@
from __future__ import absolute_import

from .roller import LintRoller
from .result import ResultContainer
from .result import Issue
+7 −8
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ def find_linters(linters=None):
def run(paths, linters, fmt, outgoing, workdir, edit,
        setup=False, list_linters=False, **lintargs):
    from mozlint import LintRoller, formatters
    from mozlint.editor import edit_results
    from mozlint.editor import edit_issues

    if list_linters:
        lint_paths = find_linters(linters)
@@ -165,21 +165,20 @@ def run(paths, linters, fmt, outgoing, workdir, edit,
        return ret

    # run all linters
    results = lint.roll(paths, outgoing=outgoing, workdir=workdir)
    result = lint.roll(paths, outgoing=outgoing, workdir=workdir)

    if edit and results:
        edit_results(results)
        results = lint.roll(results.keys())
    if edit and result.issues:
        edit_issues(result.issues)
        result = lint.roll(result.issues.keys())

    formatter = formatters.get(fmt)

    # Encode output with 'replace' to avoid UnicodeEncodeErrors on
    # environments that aren't using utf-8.
    out = formatter(results, failed=lint.failed | lint.failed_setup).encode(
                    sys.stdout.encoding or 'ascii', 'replace')
    out = formatter(result).encode(sys.stdout.encoding or 'ascii', 'replace')
    if out:
        print(out)
    return 1 if results or lint.failed else 0
    return result.returncode


if __name__ == '__main__':
+4 −4
Original line number Diff line number Diff line
@@ -15,8 +15,8 @@ def get_editor():
    return os.environ.get('EDITOR')


def edit_results(results):
    if not results:
def edit_issues(issues):
    if not issues:
        return

    editor = get_editor()
@@ -41,7 +41,7 @@ def edit_results(results):
        ]

        with tempfile.NamedTemporaryFile() as fh:
            s = formatters.get('compact', summary=False)(results)
            s = formatters.get('compact', summary=False)(issues)
            fh.write(s)
            fh.flush()

@@ -49,5 +49,5 @@ def edit_results(results):
            subprocess.call(cmd)

    else:
        for path, errors in results.iteritems():
        for path, errors in issues.iteritems():
            subprocess.call([editor, path])
+3 −3
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ from __future__ import absolute_import

import json

from ..result import ResultEncoder
from ..result import IssueEncoder
from .compact import CompactFormatter
from .stylish import StylishFormatter
from .summary import SummaryFormatter
@@ -15,8 +15,8 @@ from .unix import UnixFormatter


class JSONFormatter(object):
    def __call__(self, results, **kwargs):
        return json.dumps(results, cls=ResultEncoder)
    def __call__(self, result):
        return json.dumps(result.issues, cls=IssueEncoder)


all_formatters = {
+4 −4
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@

from __future__ import absolute_import, unicode_literals

from ..result import ResultContainer
from ..result import Issue


class CompactFormatter(object):
@@ -19,13 +19,13 @@ class CompactFormatter(object):
    def __init__(self, summary=True):
        self.summary = summary

    def __call__(self, result, **kwargs):
    def __call__(self, result):
        message = []
        num_problems = 0
        for path, errors in sorted(result.iteritems()):
        for path, errors in sorted(result.issues.iteritems()):
            num_problems += len(errors)
            for err in errors:
                assert isinstance(err, ResultContainer)
                assert isinstance(err, Issue)

                d = {s: getattr(err, s) for s in err.__slots__}
                d["column"] = ", col %s" % d["column"] if d["column"] else ""
Loading