mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Bug 1379151 - Add --fix and --edit to mozlint, r=standard8
While --fix previously worked with eslint, it is now more official (will show up in the |mach lint --help|). ESlint is still the only thing that implements it, but we can implement it for flake8 using the `autopep8` module. --edit is a new concept that will open an editor for each failing file to let you fix the errors manually. For now it is very naive (just opens the file), and is only really useful if you have an editor integration for the linter(s). But in the future I'd like to have editor-specific implementations for this. For example, with vim, we can use -q to pass in an error file that will start the editor pre-populated with a list of all errors that can then be easily jumped to. Other editors may just open up to the line containing the error. --fix and --edit can be used in conjunction with one another. Doing that means only errors that can't be fixed automatically will show up in your editor. MozReview-Commit-ID: 5JJJhMIrMIB --HG-- extra : rebase_source : 2f78a77a91133d7fcc5620ecd5caa500decbce1b
This commit is contained in:
parent
015f8de9b5
commit
10f8b7e161
@ -5,9 +5,12 @@
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from argparse import REMAINDER, ArgumentParser
|
||||
|
||||
from mozlint.formatters import all_formatters
|
||||
|
||||
SEARCH_PATHS = []
|
||||
|
||||
|
||||
@ -36,6 +39,7 @@ class MozlintParser(ArgumentParser):
|
||||
[['-f', '--format'],
|
||||
{'dest': 'fmt',
|
||||
'default': 'stylish',
|
||||
'choices': all_formatters.keys(),
|
||||
'help': "Formatter to use. Defaults to 'stylish'.",
|
||||
}],
|
||||
[['-n', '--no-filter'],
|
||||
@ -63,6 +67,18 @@ class MozlintParser(ArgumentParser):
|
||||
"can be used to only consider staged files. Works with "
|
||||
"mercurial or git.",
|
||||
}],
|
||||
[['--fix'],
|
||||
{'action': 'store_true',
|
||||
'default': False,
|
||||
'help': "Fix lint errors if possible. Any errors that could not be fixed "
|
||||
"will be printed as normal."
|
||||
}],
|
||||
[['--edit'],
|
||||
{'action': 'store_true',
|
||||
'default': False,
|
||||
'help': "Each file containing lint errors will be opened in $EDITOR one after "
|
||||
"the other."
|
||||
}],
|
||||
[['extra_args'],
|
||||
{'nargs': REMAINDER,
|
||||
'help': "Extra arguments that will be forwarded to the underlying linter.",
|
||||
@ -87,8 +103,14 @@ class MozlintParser(ArgumentParser):
|
||||
# when using mach's dispatch functionality.
|
||||
args, extra = ArgumentParser.parse_known_args(self, *args, **kwargs)
|
||||
args.extra_args = extra
|
||||
|
||||
self.validate(args)
|
||||
return args, extra
|
||||
|
||||
def validate(self, args):
|
||||
if args.edit and not os.environ.get('EDITOR'):
|
||||
self.error("must set the $EDITOR environment variable to use --edit")
|
||||
|
||||
|
||||
def find_linters(linters=None):
|
||||
lints = []
|
||||
@ -113,7 +135,7 @@ def find_linters(linters=None):
|
||||
return lints
|
||||
|
||||
|
||||
def run(paths, linters, fmt, outgoing, workdir, list_linters=None, **lintargs):
|
||||
def run(paths, linters, fmt, outgoing, workdir, edit, list_linters=None, **lintargs):
|
||||
from mozlint import LintRoller, formatters
|
||||
|
||||
if list_linters:
|
||||
@ -133,6 +155,13 @@ def run(paths, linters, fmt, outgoing, workdir, list_linters=None, **lintargs):
|
||||
|
||||
# run all linters
|
||||
results = lint.roll(paths, outgoing=outgoing, workdir=workdir)
|
||||
|
||||
if edit:
|
||||
editor = os.environ['EDITOR']
|
||||
for path in results:
|
||||
subprocess.call([editor, path])
|
||||
return 1 if lint.failed else 0
|
||||
|
||||
formatter = formatters.get(fmt)
|
||||
|
||||
# Encode output with 'replace' to avoid UnicodeEncodeErrors on
|
||||
|
@ -11,6 +11,10 @@ def badreturncode(files, config, **lintargs):
|
||||
|
||||
|
||||
def external(files, config, **lintargs):
|
||||
if lintargs.get('fix'):
|
||||
# mimics no results because they got fixed
|
||||
return []
|
||||
|
||||
results = []
|
||||
for path in files:
|
||||
with open(path, 'r') as fh:
|
||||
|
@ -1,6 +1,7 @@
|
||||
[DEFAULT]
|
||||
subsuite = mozlint, os == "linux"
|
||||
|
||||
[test_cli.py]
|
||||
[test_formatters.py]
|
||||
[test_parser.py]
|
||||
[test_roller.py]
|
||||
|
55
python/mozlint/test/test_cli.py
Normal file
55
python/mozlint/test/test_cli.py
Normal file
@ -0,0 +1,55 @@
|
||||
# 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 os
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
from mozlint import cli
|
||||
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def parser():
|
||||
return cli.MozlintParser()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def run(parser, lintdir, files):
|
||||
if lintdir not in cli.SEARCH_PATHS:
|
||||
cli.SEARCH_PATHS.append(lintdir)
|
||||
|
||||
def inner(args=None):
|
||||
args = args or []
|
||||
args.extend(files)
|
||||
lintargs = vars(parser.parse_args(args))
|
||||
lintargs['root'] = here
|
||||
return cli.run(**lintargs)
|
||||
return inner
|
||||
|
||||
|
||||
def test_cli_run_with_fix(run, capfd):
|
||||
ret = run(['-f', 'json', '--fix', '--linter', 'external'])
|
||||
out, err = capfd.readouterr()
|
||||
assert ret == 0
|
||||
assert out.endswith('{}\n')
|
||||
|
||||
|
||||
def test_cli_run_with_edit(run, parser, capfd):
|
||||
os.environ['EDITOR'] = 'echo'
|
||||
|
||||
ret = run(['-f', 'json', '--edit', '--linter', 'external'])
|
||||
out = capfd.readouterr()[0].strip()
|
||||
assert ret == 0
|
||||
assert os.path.basename(out) == 'foobar.js'
|
||||
|
||||
del os.environ['EDITOR']
|
||||
with pytest.raises(SystemExit):
|
||||
parser.parse_args(['--edit'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(pytest.main(['--verbose', __file__]))
|
Loading…
Reference in New Issue
Block a user