[tox] envlist = py{26,27,py,py3}-{test,pylint,flake8,vulture} py{33,34,35,36,37}-{test,mypy,pylint,flake8,vulture} cov skipsdist = true skip_missing_interpreters = true [testenv] deps = test: pytest==3.0.7 test,cov: {[testenv:cov]deps} test,py{33,34,35,36,37}-{type,mypy}: colorama==0.3.7 py{33,34,35,36,37}-{type,mypy}: {[testenv:mypy]deps} lint,pylint: {[testenv:pylint]deps} lint,flake8: {[testenv:flake8]deps} lint,vulture: {[testenv:vulture]deps} setenv = SSHAUDIT = {toxinidir}/ssh-audit.py test: COVERAGE_FILE = {toxinidir}/.coverage.{envname} type,mypy: MYPYPATH = {toxinidir}/test/stubs type,mypy: MYPYHTML = {toxinidir}/html/mypy commands = test: coverage run --source ssh-audit -m -- pytest -v {posargs:test} test: coverage report --show-missing test: - coverage html -d {toxinidir}/html/coverage.{envname} py{33,34,35,36,37}-{type,mypy}: {[testenv:mypy]commands} lint,pylint: {[testenv:pylint]commands} lint,flake8: {[testenv:flake8]commands} lint,vulture: {[testenv:vulture]commands} ignore_outcome = type: true lint: true [testenv:cov] deps = coverage==4.3.4 setenv = COVERAGE_FILE = {toxinidir}/.coverage commands = coverage erase coverage combine coverage report --show-missing - coverage html -d {toxinidir}/html/coverage [testenv:mypy] deps = colorama==0.3.7 mypy==0.501 lxml==3.7.3 commands = mypy \ --show-error-context \ --config-file {toxinidir}/tox.ini \ --html-report {env:MYPYHTML}.py3.{envname} \ {posargs:{env:SSHAUDIT}} mypy \ -2 \ --no-warn-incomplete-stub \ --show-error-context \ --config-file {toxinidir}/tox.ini \ --html-report {env:MYPYHTML}.py2.{envname} \ {posargs:{env:SSHAUDIT}} [testenv:pylint] deps = mccabe pylint commands = pylint \ --rcfile tox.ini \ --load-plugins=pylint.extensions.bad_builtin \ --load-plugins=pylint.extensions.check_elif \ --load-plugins=pylint.extensions.mccabe \ {posargs:{env:SSHAUDIT}} [testenv:flake8] deps = flake8 commands = flake8 {posargs:{env:SSHAUDIT}} [testenv:vulture] deps = vulture commands = python -c "import sys; from subprocess import Popen, PIPE; \ a = ['vulture'] + r'{posargs:{env:SSHAUDIT}}'.split(' '); \ o = Popen(a, shell=False, stdout=PIPE).communicate()[0]; \ l = [x for x in o.split(b'\n') if x and b'Unused import' not in x]; \ print(b'\n'.join(l).decode('utf-8')); \ sys.exit(1 if len(l) > 0 else 0)" [mypy] ignore_missing_imports = False follow_imports = error disallow_untyped_calls = True disallow_untyped_defs = True check_untyped_defs = True disallow_subclassing_any = True warn_incomplete_stub = True warn_redundant_casts = True warn_return_any = True warn_unused_ignores = True strict_optional = True #strict_boolean = False [pylint] reports = no #output-format = colorized indent-string = \t disable = locally-disabled, bad-continuation, multiple-imports, invalid-name, trailing-whitespace, missing-docstring max-complexity = 15 max-args = 8 max-locals = 20 max-returns = 6 max-branches = 15 max-statements = 60 max-parents = 7 max-attributes = 8 min-public-methods = 1 max-public-methods = 20 max-bool-expr = 5 max-nested-blocks = 6 max-line-length = 80 ignore-long-lines = ^\s*(#\s+type:\s+.*|[A-Z0-9_]+\s+=\s+.*|('.*':\s+)?\[.*\],?)$ max-module-lines = 2500 [flake8] ignore = # indentation contains tabs W191, # blank line contains whitespace W293, # indentation contains mixed spaces and tabs E101, # multiple spaces before operator E221, # multiple spaces after operator E241, # multiple imports on one line E401, # line too long E501, # module imported but unused F401, # undefined name F821