Skip to content

Commit

Permalink
invoke: add 'lint' task
Browse files Browse the repository at this point in the history
  • Loading branch information
pyroscope committed Feb 23, 2020
1 parent b99f096 commit e458c23
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 4 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ install:
- pip install -r requirements-dev.txt

script:
- invoke lint --with-report
- invoke test
2 changes: 1 addition & 1 deletion CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Here are some common project tasks::

pytest # Run unit tests
inv docs -o # Build documentation and show in browser
paver lint -m # Check code quality
inv lint # Check code quality
inv cov # Run unit tests & show coverage report
tox # Run unit tests in various test environments (multiple Python versions)

Expand Down
87 changes: 84 additions & 3 deletions tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
from __future__ import print_function, unicode_literals

import os
import sys
import time
import shutil
import contextlib
import subprocess
import webbrowser

try:
from pathlib import Path
except ImportError:
Expand All @@ -22,6 +25,17 @@
SPHINX_AUTOBUILD_PORT = int(os.environ.get('SPHINX_AUTOBUILD_PORT', '8340'))


@contextlib.contextmanager
def pushd(folder):
"""Context manager to temporarily change directory."""
cwd = os.getcwd()
try:
os.chdir(folder)
yield folder
finally:
os.chdir(cwd)


@task
def test(ctx):
"""Run unit tests."""
Expand All @@ -30,14 +44,79 @@ def test(ctx):

@task
def cov(ctx):
"""Run unit tests & show coverage report"""
"""Run unit tests & show coverage report."""
coverage_index = Path("build/coverage/index.html")
coverage_index.unlink()
ctx.run(PYTEST_CMD)
coverage_index.exists() and webbrowser.open(
'file://{}'.format(os.path.abspath(coverage_index)))


@task(help={
'output': 'Create report file (.html, .log, or .txt) [stdout]',
'rcfile': 'Configuration file [./pylint.cfg]',
'with-report': 'Include summary report',
})
def lint(ctx, output='', rcfile='', with_report=False):
"""Report pylint results."""
# report according to file extension
report_formats = {
".html": "html",
".log": "parseable",
".txt": "text",
}

lint_build_dir = Path("build/lint")
lint_build_dir.exists() or lint_build_dir.makedirs() # pylint: disable=expression-not-assigned

argv = []
if not rcfile and Path("pylint.cfg").exists():
rcfile = "pylint.cfg"
if rcfile:
argv += ["--rcfile", os.path.abspath(rcfile)]
if not with_report:
argv += ["-rn"]
argv += [
"--import-graph", str((lint_build_dir / "imports.dot").resolve()),
]
argv += [PROJECT_NAME]

sys.stderr.write("Running %s::pylint '%s'\n" % (sys.argv[0], "' '".join(argv)))
outfile = output
if outfile:
outfile = os.path.abspath(outfile)

try:
with pushd("src" if Path("src").exists() else "."):
if outfile:
argv.extend(["-f", report_formats.get(Path(outfile).ext, "text")])
sys.stderr.write("Writing output to %r\n" % (str(outfile),))
with open(outfile, "w", encoding='utf-8') as outhandle:
subprocess.check_call(["pylint"] + argv, stdout=outhandle)
else:
subprocess.check_call(["pylint"] + argv, )
sys.stderr.write("invoke::lint - No problems found.\n")
except subprocess.CalledProcessError as exc:
if exc.returncode & 32:
# usage error (internal error in this code)
sys.stderr.write("invoke::lint - Usage error, bad arguments %r?!\n" % (argv,))
sys.exit(exc.returncode)
else:
bits = {
1: "fatal",
2: "error",
4: "warning",
8: "refactor",
16: "convention",
}
sys.stderr.write("invoke::lint - Some %s message(s) issued.\n" % (
", ".join([text for bit, text in bits.items() if exc.returncode & bit])
))
if exc.returncode & 3:
sys.stderr.write("invoke::lint - Exiting due to fatal / error message.\n")
sys.exit(exc.returncode)


def watchdog_pid(ctx):
"""Get watchdog PID via ``netstat``."""
result = ctx.run('netstat -tulpn 2>/dev/null | grep 127.0.0.1:{:d}'
Expand All @@ -49,7 +128,9 @@ def watchdog_pid(ctx):
return pid


@task(help={'open-tab': "Open docs in new browser tab after initial build"})
@task(help={
'open-tab': "Open docs in new browser tab after initial build"
})
def docs(ctx, open_tab=False):
"""Start watchdog to build the Sphinx docs."""
build_dir = 'docs/_build'
Expand Down Expand Up @@ -86,7 +167,7 @@ def docs(ctx, open_tab=False):

@task
def stop(ctx):
"Stop Sphinx watchdog"
"Stop Sphinx watchdog."
print("\n*** Stopping watchdog ***\n")
for i in range(4):
pid = watchdog_pid(ctx)
Expand Down

0 comments on commit e458c23

Please sign in to comment.