Bug 1177933 - Add |mach eslint| command. r=mcomella,dmose

DONTBUILD NPOTB
This commit is contained in:
Nick Alexander
2015-07-02 12:18:52 -07:00
parent f49ace1f2c
commit eaebad76b9

View File

@@ -8,6 +8,7 @@ import argparse
import logging
import mozpack.path as mozpath
import os
import which
from mozbuild.base import (
MachCommandBase,
@@ -20,6 +21,17 @@ from mach.decorators import (
)
ESLINT_NOT_FOUND_MESSAGE = '''
Could not find eslint! We looked at the --binary option, at the ESLINT
environment variable, and then at your path. Install eslint and needed plugins
with
npm install -g eslint eslint-plugin-react
and try again.
'''.strip()
@CommandProvider
class MachCommands(MachCommandBase):
@Command('python', category='devenv',
@@ -32,8 +44,8 @@ class MachCommands(MachCommandBase):
self._activate_virtualenv()
return self.run_process([self.virtualenv_manager.python_path] + args,
pass_thru=True, # Allow user to run Python interactively.
ensure_exit_code=False, # Don't throw on non-zero exit code.
pass_thru=True, # Allow user to run Python interactively.
ensure_exit_code=False, # Don't throw on non-zero exit code.
# Note: subprocess requires native strings in os.environ on Windows
append_env={b'PYTHONDONTWRITEBYTECODE': str('1')})
@@ -89,14 +101,15 @@ class MachCommands(MachCommandBase):
return 1
for f in files:
file_displayed_test = [] # Used as a boolean.
file_displayed_test = [] # Used as a boolean.
def _line_handler(line):
if not file_displayed_test and line.startswith('TEST-'):
file_displayed_test.append(True)
inner_return_code = self.run_process(
[self.virtualenv_manager.python_path, f],
ensure_exit_code=False, # Don't throw on non-zero exit code.
ensure_exit_code=False, # Don't throw on non-zero exit code.
log_name='python-test',
# subprocess requires native strings in os.environ on Windows
append_env={b'PYTHONDONTWRITEBYTECODE': str('1')},
@@ -118,3 +131,54 @@ class MachCommands(MachCommandBase):
return 1
return 0 if return_code == 0 else 1
@Command('eslint', category='devenv')
@CommandArgument('path', nargs='?', default='.',
help='Path to files to lint, like "browser/components/loop" '
'or "mobile/android". '
'Defaults to the current directory if not given.')
@CommandArgument('-e', '--ext', default='[.js,.jsm,.jsx]',
help='Filename extensions to lint, default: "[.js,.jsm,.jsx]".')
@CommandArgument('-b', '--binary', default=None,
help='Path to eslint binary.')
@CommandArgument('args', nargs=argparse.REMAINDER) # Passed through to eslint.
def eslint(self, path, ext=None, binary=None, args=[]):
'''Run eslint.'''
if not binary:
binary = os.environ.get('ESLINT', None)
if not binary:
try:
binary = which.which('eslint')
except which.WhichError:
pass
if not binary:
print(ESLINT_NOT_FOUND_MESSAGE)
return 1
# The cwd below is unfortunate. eslint --config=PATH/TO/.eslintrc works,
# but --ignore-path=PATH/TO/.eslintignore treats paths as relative to
# the current directory, rather than as relative to the location of
# .eslintignore (see https://github.com/eslint/eslint/issues/1382).
# mach commands always execute in the topsrcdir, so we could make all
# paths in .eslint relative to the topsrcdir, but it's not clear if
# that's a good choice for future eslint and IDE integrations.
# Unfortunately, running after chdir does not print the full path to
# files (convenient for opening with copy-and-paste). In the meantime,
# we just print the active path.
self.log(logging.INFO, 'eslint', {'binary': binary, 'path': path},
'Running {binary} in {path}')
cmd_args = [binary,
'--ext', ext, # This keeps ext as a single argument.
] + args
# Path must come after arguments. Path is '.' due to cwd below.
cmd_args += ['.']
return self.run_process(cmd_args,
cwd=path,
pass_thru=True, # Allow user to run eslint interactively.
ensure_exit_code=False, # Don't throw on non-zero exit code.
)