зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1373368 - [mozlint] Raise if a non-existant path is specified in a lint config, r=standard8
Since I left the next two patches to bitrot, I realized that a path I had added didn't exist anymore. We should definitely error out if non-existant paths are specified, otherwise the lists will become outdated and it will be possible to accidentally disable linting on some files. I discovered a few instances of this already in our existing definitions. MozReview-Commit-ID: 8jsTKLI0nFE --HG-- extra : rebase_source : acceb0b129fc472fb456ff527e4c8c52228edd59
This commit is contained in:
Родитель
88729f16df
Коммит
e04895a098
|
@ -4,8 +4,6 @@
|
|||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
|
||||
|
||||
class LintException(Exception):
|
||||
pass
|
||||
|
@ -18,7 +16,7 @@ class LinterNotFound(LintException):
|
|||
|
||||
class LinterParseError(LintException):
|
||||
def __init__(self, path, message):
|
||||
LintException.__init__(self, "{}: {}".format(os.path.basename(path), message))
|
||||
LintException.__init__(self, "{}: {}".format(path, message))
|
||||
|
||||
|
||||
class LintersNotConfigured(LintException):
|
||||
|
|
|
@ -21,33 +21,57 @@ class Parser(object):
|
|||
'payload',
|
||||
)
|
||||
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
|
||||
def __call__(self, path):
|
||||
return self.parse(path)
|
||||
|
||||
def _validate(self, linter):
|
||||
relpath = os.path.relpath(linter['path'], self.root)
|
||||
|
||||
missing_attrs = []
|
||||
for attr in self.required_attributes:
|
||||
if attr not in linter:
|
||||
missing_attrs.append(attr)
|
||||
|
||||
if missing_attrs:
|
||||
raise LinterParseError(linter['path'], "Missing required attribute(s): "
|
||||
"{}".format(','.join(missing_attrs)))
|
||||
raise LinterParseError(relpath, "Missing required attribute(s): "
|
||||
"{}".format(','.join(missing_attrs)))
|
||||
|
||||
if linter['type'] not in supported_types:
|
||||
raise LinterParseError(linter['path'], "Invalid type '{}'".format(linter['type']))
|
||||
raise LinterParseError(relpath, "Invalid type '{}'".format(linter['type']))
|
||||
|
||||
for attr in ('include', 'exclude'):
|
||||
if attr in linter and (not isinstance(linter[attr], list) or
|
||||
not all(isinstance(a, basestring) for a in linter[attr])):
|
||||
raise LinterParseError(linter['path'], "The {} directive must be a "
|
||||
"list of strings!".format(attr))
|
||||
if attr not in linter:
|
||||
continue
|
||||
|
||||
if not isinstance(linter[attr], list) or \
|
||||
not all(isinstance(a, basestring) for a in linter[attr]):
|
||||
raise LinterParseError(relpath, "The {} directive must be a "
|
||||
"list of strings!".format(attr))
|
||||
invalid_paths = set()
|
||||
for path in linter[attr]:
|
||||
if '*' in path:
|
||||
continue
|
||||
|
||||
abspath = path
|
||||
if not os.path.isabs(abspath):
|
||||
abspath = os.path.join(self.root, path)
|
||||
|
||||
if not os.path.exists(abspath):
|
||||
invalid_paths.add(' ' + path)
|
||||
|
||||
if invalid_paths:
|
||||
raise LinterParseError(relpath, "The {} directive contains the following "
|
||||
"paths that don't exist:\n{}".format(
|
||||
attr, '\n'.join(sorted(invalid_paths))))
|
||||
|
||||
if 'setup' in linter:
|
||||
if linter['setup'].count(':') != 1:
|
||||
raise LinterParseError(linter['path'], "The setup attribute '{!r}' must have the "
|
||||
"form 'module:object'".format(
|
||||
linter['setup']))
|
||||
raise LinterParseError(relpath, "The setup attribute '{!r}' must have the "
|
||||
"form 'module:object'".format(
|
||||
linter['setup']))
|
||||
|
||||
if 'extensions' in linter:
|
||||
linter['extensions'] = [e.strip('.') for e in linter['extensions']]
|
||||
|
|
|
@ -90,7 +90,7 @@ class LintRoller(object):
|
|||
MAX_PATHS_PER_JOB = 50 # set a max size to prevent command lines that are too long on Windows
|
||||
|
||||
def __init__(self, root, **lintargs):
|
||||
self.parse = Parser()
|
||||
self.parse = Parser(root)
|
||||
try:
|
||||
self.vcs = get_repository_object(root)
|
||||
except InvalidRepoPath:
|
||||
|
|
|
@ -3,6 +3,6 @@ ExplicitPathLinter:
|
|||
description: Only lint a specific file name
|
||||
rule: no-foobar
|
||||
include:
|
||||
- no_foobar.js
|
||||
- files/no_foobar.js
|
||||
type: string
|
||||
payload: foobar
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
BadExcludeLinter:
|
||||
description: Has an invalid exclude directive.
|
||||
exclude:
|
||||
- files/does_not_exist
|
||||
type: string
|
||||
payload: foobar
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
BadIncludeLinter:
|
||||
description: Has an invalid include directive.
|
||||
include:
|
||||
- files/does_not_exist
|
||||
type: string
|
||||
payload: foobar
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
BadSupportFilesLinter:
|
||||
description: Has an invalid support-files directive.
|
||||
support-files:
|
||||
- files/does_not_exist
|
||||
type: string
|
||||
payload: foobar
|
|
@ -5,8 +5,8 @@
|
|||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import mozunit
|
||||
import pytest
|
||||
|
||||
from mozlint import pathutils
|
||||
|
@ -90,4 +90,4 @@ def test_include_exclude(filterpaths):
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(pytest.main(['--verbose', __file__]))
|
||||
mozunit.main()
|
||||
|
|
|
@ -15,10 +15,12 @@ from mozlint.errors import (
|
|||
LinterParseError,
|
||||
)
|
||||
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def parse(lintdir):
|
||||
parser = Parser()
|
||||
parser = Parser(here)
|
||||
|
||||
def _parse(name):
|
||||
path = os.path.join(lintdir, name)
|
||||
|
@ -48,6 +50,9 @@ def test_parse_valid_linter(parse):
|
|||
'invalid_exclude.yml',
|
||||
'missing_attrs.yml',
|
||||
'missing_definition.yml',
|
||||
'non_existing_include.yml',
|
||||
'non_existing_exclude.yml',
|
||||
'non_existing_support_files.yml',
|
||||
])
|
||||
def test_parse_invalid_linter(parse, linter):
|
||||
with pytest.raises(LinterParseError):
|
||||
|
|
|
@ -11,7 +11,6 @@ mingw-capitalization:
|
|||
- gfx/angle/checkout/src/common/tls.cpp
|
||||
- gfx/cairo/cairo/src/cairo-atomic-private.h
|
||||
- gfx/harfbuzz/src/hb-directwrite.cc
|
||||
- gfx/skia/skia/src/views/win/SkOSWindow_win.cpp
|
||||
- gfx/skia/skia/src/xps/SkXPSDevice.cpp
|
||||
- gfx/skia/skia/src/xps/SkXPSDevice.h
|
||||
- gfx/skia/skia/src/xps/SkXPSDocument.h
|
||||
|
|
|
@ -26,13 +26,11 @@ py2:
|
|||
- netwerk
|
||||
- nsprpub
|
||||
- other-licenses
|
||||
- probes/trace-gen.py
|
||||
- python/devtools
|
||||
- python/mach
|
||||
- python/mozbuild
|
||||
- python/mozversioncontrol
|
||||
- security
|
||||
- services/common/tests/mach_commands.py
|
||||
- servo
|
||||
- taskcluster/docker/funsize-update-generator
|
||||
- testing/awsy
|
||||
|
|
|
@ -26,7 +26,6 @@ py3:
|
|||
- nsprpub
|
||||
- security/manager/ssl
|
||||
- security/nss
|
||||
- services/common/tests/mach_commands.py
|
||||
- servo
|
||||
- testing/awsy
|
||||
- testing/firefox-ui/harness/firefox_ui_harness/runners/update.py
|
||||
|
|
|
@ -55,7 +55,7 @@ def config(request):
|
|||
|
||||
name = request.module.LINTER
|
||||
config_path = os.path.join(lintdir, '{}.yml'.format(name))
|
||||
parser = Parser()
|
||||
parser = Parser(build.topsrcdir)
|
||||
# TODO Don't assume one linter per yaml file
|
||||
return parser.parse(config_path)[0]
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче