diff options
author | Eric Lin <anselor@gmail.com> | 2020-07-07 13:59:43 -0400 |
---|---|---|
committer | anselor <anselor@gmail.com> | 2020-07-08 14:51:31 -0400 |
commit | ff64eff8854c9b52a1f48e4b843e9a738d2b388d (patch) | |
tree | 734419988bbb26a31ecc1caa9e18b0a6686cc6f3 /tasks.py | |
parent | bc50e370c6113ada43acbfaf94d211f3917a7870 (diff) | |
download | cmd2-git-ff64eff8854c9b52a1f48e4b843e9a738d2b388d.tar.gz |
Swap out tox for nox
Diffstat (limited to 'tasks.py')
-rw-r--r-- | tasks.py | 265 |
1 files changed, 187 insertions, 78 deletions
@@ -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) |