summaryrefslogtreecommitdiff
path: root/tasks.py
diff options
context:
space:
mode:
authorEric Lin <anselor@gmail.com>2020-07-07 13:59:43 -0400
committeranselor <anselor@gmail.com>2020-07-08 14:51:31 -0400
commitff64eff8854c9b52a1f48e4b843e9a738d2b388d (patch)
tree734419988bbb26a31ecc1caa9e18b0a6686cc6f3 /tasks.py
parentbc50e370c6113ada43acbfaf94d211f3917a7870 (diff)
downloadcmd2-git-ff64eff8854c9b52a1f48e4b843e9a738d2b388d.tar.gz
Swap out tox for nox
Diffstat (limited to 'tasks.py')
-rw-r--r--tasks.py265
1 files changed, 187 insertions, 78 deletions
diff --git a/tasks.py b/tasks.py
index f95a42c0..e1d9da0d 100644
--- a/tasks.py
+++ b/tasks.py
@@ -9,16 +9,20 @@ Make sure you satisfy the following Python module requirements if you are trying
- setuptools >= 39.1.0
"""
import os
+import invoke
+import pathlib
import re
import shutil
import sys
-import invoke
+
+TASK_ROOT = pathlib.Path(__file__).resolve().parent
+TASK_ROOT_STR = str(TASK_ROOT)
# shared function
def rmrf(items, verbose=True):
- "Silently remove a list of directories or files"
+ """Silently remove a list of directories or files"""
if isinstance(items, str):
items = [items]
@@ -40,52 +44,93 @@ namespace.add_collection(namespace_clean, 'clean')
#####
#
-# pytest, tox, pylint, and codecov
+# pytest, tox, nox, pylint, and codecov
#
#####
+
+
@invoke.task
-def pytest(context):
- "Run tests and code coverage using pytest"
- context.run("pytest --cov=cmd2 --cov-report=term --cov-report=html", pty=True)
+def pytest(context, junit=False, pty=True):
+ """Run tests and code coverage using pytest"""
+ with context.cd(TASK_ROOT_STR):
+ command_str = 'pytest --cov=cmd2 --cov-report=term --cov-report=html'
+ if junit:
+ # command_str += ' --junitxml={}/junit/test-results.xml'.format(TASK_ROOT_STR)
+ command_str += ' --junitxml=junit/test-results.xml'
+ command_str += ' tests'
+ context.run(command_str, pty=pty)
+
+
namespace.add_task(pytest)
+
@invoke.task
def pytest_clean(context):
- "Remove pytest cache and code coverage files and directories"
- #pylint: disable=unused-argument
- dirs = ['.pytest_cache', '.cache', 'htmlcov', '.coverage']
+ """Remove pytest cache and code coverage files and directories"""
+ # pylint: disable=unused-argument
+ with context.cd(str(TASK_ROOT/'tests')):
+ dirs = ['.pytest_cache', '.cache', 'htmlcov', '.coverage']
+ rmrf(dirs)
rmrf(dirs)
+
+
namespace_clean.add_task(pytest_clean, 'pytest')
+
@invoke.task
def mypy(context):
- "Run mypy optional static type checker"
- context.run("mypy main.py")
- namespace.add_task(mypy)
+ """Run mypy optional static type checker"""
+ with context.cd(TASK_ROOT_STR):
+ context.run("mypy main.py")
+
+
namespace.add_task(mypy)
+
@invoke.task
def mypy_clean(context):
- "Remove mypy cache directory"
- #pylint: disable=unused-argument
- dirs = ['.mypy_cache', 'dmypy.json', 'dmypy.sock']
- rmrf(dirs)
+ """Remove mypy cache directory"""
+ # pylint: disable=unused-argument
+ with context.cd(TASK_ROOT_STR):
+ dirs = ['.mypy_cache', 'dmypy.json', 'dmypy.sock']
+ rmrf(dirs)
+
+
namespace_clean.add_task(mypy_clean, 'mypy')
+
@invoke.task
def tox(context):
- "Run unit and integration tests on multiple python versions using tox"
- context.run("tox")
+ """Run unit and integration tests on multiple python versions using tox"""
+ with context.cd(TASK_ROOT_STR):
+ context.run("tox")
+
+
namespace.add_task(tox)
+
@invoke.task
def tox_clean(context):
- "Remove tox virtualenvs and logs"
- #pylint: disable=unused-argument
- rmrf('.tox')
+ """Remove tox virtualenvs and logs"""
+ # pylint: disable=unused-argument
+ with context.cd(TASK_ROOT_STR):
+ rmrf('.tox')
+
+
namespace_clean.add_task(tox_clean, 'tox')
+@invoke.task
+def nox_clean(context):
+ """Remove nox virtualenvs and logs"""
+ # pylint: disable=unused-argument
+ with context.cd(TASK_ROOT_STR):
+ rmrf('.nox')
+
+
+namespace_clean.add_task(nox_clean, 'nox')
+
+
#####
#
# documentation
@@ -95,39 +140,59 @@ DOCS_SRCDIR = 'docs'
DOCS_BUILDDIR = os.path.join('docs', '_build')
SPHINX_OPTS = '-nvWT' # Be nitpicky, verbose, and treat warnings as errors
+
@invoke.task()
def docs(context, builder='html'):
- "Build documentation using sphinx"
- cmdline = 'python -msphinx -M {} {} {} {}'.format(builder, DOCS_SRCDIR, DOCS_BUILDDIR, SPHINX_OPTS)
- context.run(cmdline, pty=True)
+ """Build documentation using sphinx"""
+ with context.cd(TASK_ROOT_STR):
+ cmdline = 'python -msphinx -M {} {} {} {}'.format(builder, DOCS_SRCDIR, DOCS_BUILDDIR, SPHINX_OPTS)
+ context.run(cmdline, pty=True)
+
+
namespace.add_task(docs)
+
@invoke.task()
def doc8(context):
- "Check documentation with doc8"
- context.run('doc8 docs --ignore-path docs/_build')
+ """Check documentation with doc8"""
+ with context.cd(TASK_ROOT_STR):
+ context.run('doc8 docs --ignore-path docs/_build')
+
+
namespace.add_task(doc8)
+
@invoke.task
def docs_clean(context):
- "Remove rendered documentation"
- #pylint: disable=unused-argument
- rmrf(DOCS_BUILDDIR)
+ """Remove rendered documentation"""
+ # pylint: disable=unused-argument
+ with context.cd(TASK_ROOT_STR):
+ rmrf(DOCS_BUILDDIR)
+
+
namespace_clean.add_task(docs_clean, name='docs')
+
@invoke.task()
def linkcheck(context):
"""Check external links in Sphinx documentation for integrity."""
- context.run('cd docs && make linkcheck', pty=True)
+ with context.cd(str(TASK_ROOT/'docs')):
+ context.run('make linkcheck', pty=True)
+
+
namespace.add_task(linkcheck)
+
@invoke.task
def livehtml(context):
- "Launch webserver on http://localhost:8000 with rendered documentation"
- builder = 'html'
- outputdir = os.path.join(DOCS_BUILDDIR, builder)
- cmdline = 'sphinx-autobuild -b {} {} {}'.format(builder, DOCS_SRCDIR, outputdir)
- context.run(cmdline, pty=True)
+ """Launch webserver on http://localhost:8000 with rendered documentation"""
+ with context.cd(TASK_ROOT_STR):
+ builder = 'html'
+ outputdir = os.path.join(DOCS_BUILDDIR, builder)
+ cmdline = 'sphinx-autobuild -b {} {} {}'.format(builder, DOCS_SRCDIR, outputdir)
+ context.run(cmdline, pty=True)
+
+
namespace.add_task(livehtml)
@@ -139,112 +204,156 @@ namespace.add_task(livehtml)
BUILDDIR = 'build'
DISTDIR = 'dist'
+
@invoke.task
def build_clean(context):
- "Remove the build directory"
- #pylint: disable=unused-argument
- rmrf(BUILDDIR)
+ """Remove the build directory"""
+ # pylint: disable=unused-argument
+ with context.cd(TASK_ROOT_STR):
+ rmrf(BUILDDIR)
+
+
namespace_clean.add_task(build_clean, 'build')
+
@invoke.task
def dist_clean(context):
- "Remove the dist directory"
- #pylint: disable=unused-argument
- rmrf(DISTDIR)
+ """Remove the dist directory"""
+ # pylint: disable=unused-argument
+ with context.cd(TASK_ROOT_STR):
+ rmrf(DISTDIR)
+
+
namespace_clean.add_task(dist_clean, 'dist')
+
@invoke.task
def eggs_clean(context):
- "Remove egg directories"
- #pylint: disable=unused-argument
- dirs = set()
- dirs.add('.eggs')
- for name in os.listdir(os.curdir):
- if name.endswith('.egg-info'):
- dirs.add(name)
- if name.endswith('.egg'):
- dirs.add(name)
- rmrf(dirs)
+ """Remove egg directories"""
+ # pylint: disable=unused-argument
+ with context.cd(TASK_ROOT_STR):
+ dirs = set()
+ dirs.add('.eggs')
+ for name in os.listdir(os.curdir):
+ if name.endswith('.egg-info'):
+ dirs.add(name)
+ if name.endswith('.egg'):
+ dirs.add(name)
+ rmrf(dirs)
+
+
namespace_clean.add_task(eggs_clean, 'eggs')
+
@invoke.task
def pycache_clean(context):
- "Remove __pycache__ directories"
- #pylint: disable=unused-argument
- dirs = set()
- for root, dirnames, _ in os.walk(os.curdir):
- if '__pycache__' in dirnames:
- dirs.add(os.path.join(root, '__pycache__'))
- print("Removing __pycache__ directories")
- rmrf(dirs, verbose=False)
+ """Remove __pycache__ directories"""
+ # pylint: disable=unused-argument
+ with context.cd(TASK_ROOT_STR):
+ dirs = set()
+ for root, dirnames, _ in os.walk(os.curdir):
+ if '__pycache__' in dirnames:
+ dirs.add(os.path.join(root, '__pycache__'))
+ print("Removing __pycache__ directories")
+ rmrf(dirs, verbose=False)
+
+
namespace_clean.add_task(pycache_clean, 'pycache')
#
# make a dummy clean task which runs all the tasks in the clean namespace
clean_tasks = list(namespace_clean.tasks.values())
+
+
@invoke.task(pre=list(namespace_clean.tasks.values()), default=True)
-def clean_all(context):
- "Run all clean tasks"
- #pylint: disable=unused-argument
+def clean_all(_):
+ """Run all clean tasks"""
+ # pylint: disable=unused-argument
pass
+
+
namespace_clean.add_task(clean_all, 'all')
+
@invoke.task
def tag(context, name, message=''):
- "Add a Git tag and push it to origin"
+ """Add a Git tag and push it to origin"""
# If a tag was provided on the command-line, then add a Git tag and push it to origin
if name:
context.run('git tag -a {} -m {!r}'.format(name, message))
context.run('git push origin {}'.format(name))
+
+
namespace.add_task(tag)
+
@invoke.task()
def validatetag(context):
- "Check to make sure that a tag exists for the current HEAD and it looks like a valid version number"
+ """Check to make sure that a tag exists for the current HEAD and it looks like a valid version number"""
# Validate that a Git tag exists for the current commit HEAD
result = context.run("git describe --exact-match --tags $(git log -n1 --pretty='%h')")
- tag = result.stdout.rstrip()
+ git_tag = result.stdout.rstrip()
# Validate that the Git tag appears to be a valid version number
ver_regex = re.compile(r'(\d+)\.(\d+)\.(\d+)')
- match = ver_regex.fullmatch(tag)
+ match = ver_regex.fullmatch(git_tag)
if match is None:
- print('Tag {!r} does not appear to be a valid version number'.format(tag))
+ print('Tag {!r} does not appear to be a valid version number'.format(git_tag))
sys.exit(-1)
else:
- print('Tag {!r} appears to be a valid version number'.format(tag))
+ print('Tag {!r} appears to be a valid version number'.format(git_tag))
namespace.add_task(validatetag)
+
@invoke.task(pre=[clean_all])
def sdist(context):
- "Create a source distribution"
- context.run('python setup.py sdist')
+ """Create a source distribution"""
+ with context.cd(TASK_ROOT_STR):
+ context.run('python setup.py sdist')
+
+
namespace.add_task(sdist)
+
@invoke.task(pre=[clean_all])
def wheel(context):
- "Build a wheel distribution"
- context.run('python setup.py bdist_wheel')
+ """Build a wheel distribution"""
+ with context.cd(TASK_ROOT_STR):
+ context.run('python setup.py bdist_wheel')
+
+
namespace.add_task(wheel)
+
@invoke.task(pre=[validatetag, sdist, wheel])
def pypi(context):
- "Build and upload a distribution to pypi"
- context.run('twine upload dist/*')
+ """Build and upload a distribution to pypi"""
+ with context.cd(TASK_ROOT_STR):
+ context.run('twine upload dist/*')
+
+
namespace.add_task(pypi)
+
@invoke.task(pre=[validatetag, sdist, wheel])
def pypi_test(context):
- "Build and upload a distribution to https://test.pypi.org"
- context.run('twine upload --repository-url https://test.pypi.org/legacy/ dist/*')
+ """Build and upload a distribution to https://test.pypi.org"""
+ with context.cd(TASK_ROOT_STR):
+ context.run('twine upload --repository-url https://test.pypi.org/legacy/ dist/*')
+
+
namespace.add_task(pypi_test)
# Flake8 - linter and tool for style guide enforcement and linting
@invoke.task
def flake8(context):
- "Run flake8 linter and tool for style guide enforcement"
- context.run("flake8 --ignore=E252,W503 --max-complexity=26 --max-line-length=127 --show-source --statistics --exclude=.git,__pycache__,.tox,.eggs,*.egg,.venv,.idea,.pytest_cache,.vscode,build,dist,htmlcov")
+ """Run flake8 linter and tool for style guide enforcement"""
+ with context.cd(TASK_ROOT_STR):
+ context.run("flake8 --ignore=E252,W503 --max-complexity=26 --max-line-length=127 --show-source --statistics "
+ "--exclude=.git,__pycache__,.tox,.nox,.eggs,*.egg,.venv,.idea,.pytest_cache,.vscode,build,dist,htmlcov")
+
+
namespace.add_task(flake8)