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 (c969a93b0ca7)

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 90 91 92 93 94 95 96 97 98 99 100 101
# 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/.

from __future__ import absolute_import, print_function, unicode_literals

import argparse
import copy
import os

from mozbuild.base import (
    BuildEnvironmentNotFoundException,
    MachCommandBase,
)


from mach.decorators import (
    CommandArgument,
    CommandProvider,
    Command,
)


here = os.path.abspath(os.path.dirname(__file__))
EXCLUSION_FILES = [
    os.path.join('tools', 'rewriting', 'Generated.txt'),
    os.path.join('tools', 'rewriting', 'ThirdPartyPaths.txt'),
]
GLOBAL_EXCLUDES = [
    'node_modules',
    'tools/lint/test/files',
]


def setup_argument_parser():
    from mozlint import cli
    return cli.MozlintParser()


def get_global_excludes(topsrcdir):
    # exclude misc paths
    excludes = GLOBAL_EXCLUDES[:]

    # exclude top level paths that look like objdirs
    excludes.extend([name for name in os.listdir(topsrcdir)
                     if name.startswith('obj') and os.path.isdir(name)])

    for path in EXCLUSION_FILES:
        # exclude third party paths
        with open(os.path.join(topsrcdir, path), 'r') as fh:
            excludes.extend([f.strip() for f in fh.readlines()])

    return excludes


@CommandProvider
class MachCommands(MachCommandBase):

    @Command(
        'lint', category='devenv',
        description='Run linters.',
        parser=setup_argument_parser)
    def lint(self, *runargs, **lintargs):
        """Run linters."""
        self._activate_virtualenv()
        from mozlint import cli, parser

        try:
            buildargs = {}
            buildargs['substs'] = copy.deepcopy(dict(self.substs))
            buildargs['defines'] = copy.deepcopy(dict(self.defines))
            buildargs['topobjdir'] = self.topobjdir
            lintargs.update(buildargs)
        except BuildEnvironmentNotFoundException:
            pass

        lintargs.setdefault('root', self.topsrcdir)
        lintargs['exclude'] = get_global_excludes(lintargs['root'])
        cli.SEARCH_PATHS.append(here)
        for path in EXCLUSION_FILES:
            parser.GLOBAL_SUPPORT_FILES.append(os.path.join(self.topsrcdir, path))
        return cli.run(*runargs, **lintargs)

    @Command('eslint', category='devenv',
             description='Run eslint or help configure eslint for optimal development.')
    @CommandArgument('paths', default=None, nargs='*',
                     help="Paths to file or directories to lint, like "
                          "'browser/' Defaults to the "
                          "current directory if not given.")
    @CommandArgument('-s', '--setup', default=False, action='store_true',
                     help='Configure eslint for optimal development.')
    @CommandArgument('-b', '--binary', default=None,
                     help='Path to eslint binary.')
    @CommandArgument('--fix', default=False, action='store_true',
                     help='Request that eslint automatically fix errors, where possible.')
    @CommandArgument('extra_args', nargs=argparse.REMAINDER,
                     help='Extra args that will be forwarded to eslint.')
    def eslint(self, paths, extra_args=[], **kwargs):
        self._mach_context.commands.dispatch('lint', self._mach_context,
                                             linters=['eslint'], paths=paths,
                                             argv=extra_args, **kwargs)