Initial pylint support for ansible-test sanity.
This commit is contained in:
parent
572e9a8959
commit
1daa69d685
4 changed files with 117 additions and 0 deletions
|
@ -53,6 +53,8 @@ COMMAND = 'sanity'
|
|||
PEP8_SKIP_PATH = 'test/sanity/pep8/skip.txt'
|
||||
PEP8_LEGACY_PATH = 'test/sanity/pep8/legacy-files.txt'
|
||||
|
||||
PYLINT_SKIP_PATH = 'test/sanity/pylint/skip.txt'
|
||||
|
||||
|
||||
def command_sanity(args):
|
||||
"""
|
||||
|
@ -431,6 +433,89 @@ def command_sanity_pep8(args, targets):
|
|||
return SanitySuccess(test)
|
||||
|
||||
|
||||
def command_sanity_pylint(args, targets):
|
||||
"""
|
||||
:type args: SanityConfig
|
||||
:type targets: SanityTargets
|
||||
:rtype: SanityResult
|
||||
"""
|
||||
test = 'pylint'
|
||||
|
||||
with open(PYLINT_SKIP_PATH, 'r') as skip_fd:
|
||||
skip_paths = skip_fd.read().splitlines()
|
||||
|
||||
with open('test/sanity/pylint/disable.txt', 'r') as disable_fd:
|
||||
disable = set(disable_fd.read().splitlines())
|
||||
|
||||
skip_paths_set = set(skip_paths)
|
||||
|
||||
paths = sorted(i.path for i in targets.include if os.path.splitext(i.path)[1] == '.py' and i.path not in skip_paths_set)
|
||||
|
||||
if not paths:
|
||||
return SanitySkipped(test)
|
||||
|
||||
cmd = [
|
||||
'pylint',
|
||||
'--jobs', '0',
|
||||
'--reports', 'n',
|
||||
'--max-line-length', '160',
|
||||
'--rcfile', '/dev/null',
|
||||
'--output-format', 'json',
|
||||
'--disable', ','.join(sorted(disable)),
|
||||
] + paths
|
||||
|
||||
env = ansible_environment(args)
|
||||
|
||||
try:
|
||||
stdout, stderr = run_command(args, cmd, env=env, capture=True)
|
||||
status = 0
|
||||
except SubprocessError as ex:
|
||||
stdout = ex.stdout
|
||||
stderr = ex.stderr
|
||||
status = ex.status
|
||||
|
||||
if stderr or status >= 32:
|
||||
raise SubprocessError(cmd=cmd, status=status, stderr=stderr, stdout=stdout)
|
||||
|
||||
if args.explain:
|
||||
return SanitySkipped(test)
|
||||
|
||||
if stdout:
|
||||
messages = json.loads(stdout)
|
||||
else:
|
||||
messages = []
|
||||
|
||||
errors = [SanityMessage(
|
||||
message=m['message'],
|
||||
path=m['path'],
|
||||
line=int(m['line']),
|
||||
column=int(m['column']),
|
||||
level=m['type'],
|
||||
code=m['symbol'],
|
||||
) for m in messages]
|
||||
|
||||
line = 0
|
||||
|
||||
for path in skip_paths:
|
||||
line += 1
|
||||
|
||||
if not os.path.exists(path):
|
||||
# Keep files out of the list which no longer exist in the repo.
|
||||
errors.append(SanityMessage(
|
||||
code='A101',
|
||||
message='Remove "%s" since it does not exist' % path,
|
||||
path=PYLINT_SKIP_PATH,
|
||||
line=line,
|
||||
column=1,
|
||||
confidence=calculate_best_confidence(((PYLINT_SKIP_PATH, line), (path, 0)), args.metadata) if args.metadata.changes else None,
|
||||
))
|
||||
|
||||
if errors:
|
||||
return SanityFailure(test, messages=errors)
|
||||
|
||||
return SanitySuccess(test)
|
||||
|
||||
|
||||
def command_sanity_yamllint(args, targets):
|
||||
"""
|
||||
:type args: SanityConfig
|
||||
|
@ -642,6 +727,7 @@ class SanityFunc(SanityTest):
|
|||
SANITY_TESTS = (
|
||||
SanityFunc('shellcheck', command_sanity_shellcheck, intercept=False),
|
||||
SanityFunc('pep8', command_sanity_pep8, intercept=False),
|
||||
SanityFunc('pylint', command_sanity_pylint, intercept=False),
|
||||
SanityFunc('yamllint', command_sanity_yamllint, intercept=False),
|
||||
SanityFunc('validate-modules', command_sanity_validate_modules, intercept=False),
|
||||
SanityFunc('ansible-doc', command_sanity_ansible_doc),
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
coverage >= 4.2, != 4.3.2 # features in 4.2+ required, avoid known bug in 4.3.2 on python 2.6
|
||||
pywinrm >= 0.2.1 # 0.1.1 required, but 0.2.1 provides better performance
|
||||
pylint >= 1.5.3 # 1.4.1 adds JSON output, but 1.5.3 fixes bugs related to JSON output
|
||||
|
|
30
test/sanity/pylint/disable.txt
Normal file
30
test/sanity/pylint/disable.txt
Normal file
|
@ -0,0 +1,30 @@
|
|||
access-member-before-definition
|
||||
assignment-from-no-return
|
||||
bad-format-character
|
||||
C
|
||||
function-redefined
|
||||
import-error
|
||||
locally-disabled
|
||||
locally-enabled
|
||||
method-hidden
|
||||
misplaced-bare-raise
|
||||
no-member
|
||||
no-name-in-module
|
||||
no-value-for-parameter
|
||||
not-a-mapping
|
||||
not-an-iterable
|
||||
not-callable
|
||||
R
|
||||
raising-bad-type
|
||||
raising-non-exception
|
||||
return-in-init
|
||||
too-few-format-args
|
||||
too-many-format-args
|
||||
too-many-function-args
|
||||
truncated-format-string
|
||||
undefined-variable
|
||||
unexpected-keyword-arg
|
||||
unsubscriptable-object
|
||||
unsupported-membership-test
|
||||
used-before-assignment
|
||||
W
|
0
test/sanity/pylint/skip.txt
Normal file
0
test/sanity/pylint/skip.txt
Normal file
Loading…
Reference in a new issue