DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (517de066cc6f)

VCS Links

Line Code
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
# 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
from distutils.spawn import find_executable

import mozfile
from mozprocess import ProcessHandlerMixin

from mozlint import result
from mozlint.pathutils import expand_exclusions

here = os.path.abspath(os.path.dirname(__file__))

results = []


class PyCompatProcess(ProcessHandlerMixin):
    def __init__(self, config, *args, **kwargs):
        self.config = config
        kwargs['processOutputLine'] = [self.process_line]
        ProcessHandlerMixin.__init__(self, *args, **kwargs)

    def process_line(self, line):
        try:
            res = json.loads(line)
        except ValueError:
            print('Non JSON output from {} linter: {}'.format(self.config['name'], line))
            return

        res['level'] = 'error'
        results.append(result.from_config(self.config, **res))


def setup(python):
    """Setup doesn't currently do any bootstrapping. For now, this function
    is only used to print the warning message.
    """
    binary = find_executable(python)
    if not binary:
        # TODO Bootstrap python2/python3 if not available
        print('warning: {} not detected, skipping py-compat check'.format(python))


def run_linter(python, paths, config, **lintargs):
    log = lintargs['log']
    binary = find_executable(python)
    if not binary:
        # If we're in automation, this is fatal. Otherwise, the warning in the
        # setup method was already printed.
        if 'MOZ_AUTOMATION' in os.environ:
            return 1
        return []

    files = expand_exclusions(paths, config, lintargs['root'])

    with mozfile.NamedTemporaryFile(mode='w') as fh:
        fh.write('\n'.join(files))
        fh.flush()

        cmd = [binary, os.path.join(here, 'check_compat.py'), fh.name]
        log.debug("Command: {}".format(' '.join(cmd)))

        proc = PyCompatProcess(config, cmd)
        proc.run()
        try:
            proc.wait()
        except KeyboardInterrupt:
            proc.kill()

    return results


def setuppy2(**lintargs):
    return setup('python2')


def lintpy2(*args, **kwargs):
    return run_linter('python2', *args, **kwargs)


def setuppy3(**lintargs):
    return setup('python3')


def lintpy3(*args, **kwargs):
    return run_linter('python3', *args, **kwargs)