diff --git a/.gitignore b/.gitignore index b763147ae1..7acca23d32 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ sourmash/_minhash.cpp .pytest_cache .python-version sourmash/version.py +.tox/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..e9c6f446ab --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,39 @@ +repos: +- repo: https://github.com/python/black + rev: 19.3b0 + hooks: + - id: black + args: [--safe] + language_version: python3.7 +- repo: https://github.com/asottile/blacken-docs + rev: v0.5.0 + hooks: + - id: blacken-docs + additional_dependencies: [black==19.3b0] + language_version: python3.7 +- repo: https://github.com/asottile/seed-isort-config + rev: v1.7.0 + hooks: + - id: seed-isort-config + args: [--application-directories, "sourmash:."] +- repo: https://github.com/pre-commit/mirrors-isort + rev: v4.3.15 + hooks: + - id: isort + additional_dependencies: [toml] +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.1.0 + hooks: + - id: trailing-whitespace + exclude: 'tests/test-data' + - id: end-of-file-fixer + exclude: 'tests/test-data' + - id: check-yaml + - id: debug-statements + - id: flake8 + additional_dependencies: ["flake8-bugbear == 18.8.0"] + language_version: python3.7 +- repo: https://github.com/asottile/pyupgrade + rev: v1.12.0 + hooks: + - id: pyupgrade diff --git a/.travis.yml b/.travis.yml index b9ddbbafcf..e9fc36075a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ language: python os: linux dist: xenial +addons: + apt_packages: + - pandoc cache: directories: @@ -56,7 +59,7 @@ jobs: - CIBW_SKIP='*-manylinux1_i686' install: skip script: - - sudo $PIP install cibuildwheel==0.10.2 + - $PIP install cibuildwheel==0.11.1 - cibuildwheel --output-dir wheelhouse deploy: provider: releases @@ -71,8 +74,6 @@ jobs: os: osx osx_image: xcode10.1 language: generic - before_script: - - sudo $PIP install -U pip setuptools env: - PIP=pip2 - CIBW_ENVIRONMENT_MACOS='MACOSX_DEPLOYMENT_TARGET=10.11' diff --git a/Makefile b/Makefile index c51b7ffcd0..ac79e16b3b 100644 --- a/Makefile +++ b/Makefile @@ -15,17 +15,14 @@ install: all dist: FORCE $(PYTHON) setup.py sdist -test: all - pip install -e '.[test]' - $(PYTHON) -m pytest +test: + tox -e py37 doc: .PHONY - cd doc && make html + tox -e docs coverage: all - $(PYTHON) setup.py clean --all - SOURMASH_COVERAGE=1 $(PYTHON) setup.py build_ext -i - $(PYTHON) -m pytest --cov=. + tox -e coverage benchmark: all asv continuous master diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000..90ef6610c6 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,9 @@ +[build-system] +requires = [ + "setuptools >= 40.0.4", + "setuptools_scm >= 2.0.0, <4", + "setuptools_scm_git_archive", + "wheel >= 0.29.0", + "Cython >= 0.25.2", +] +build-backend = 'setuptools.build_meta' diff --git a/setup.py b/setup.py index 259da9b0de..317b682406 100644 --- a/setup.py +++ b/setup.py @@ -69,9 +69,9 @@ 'setuptools_scm', 'setuptools_scm_git_archive'], "use_scm_version": {"write_to": "sourmash/version.py"}, "extras_require": { - 'test' : ['pytest', 'pytest-cov', 'numpy', 'matplotlib', 'scipy','recommonmark'], + 'test' : ['pytest', 'pytest-cov', 'numpy', 'matplotlib', 'scipy'], 'demo' : ['jupyter', 'jupyter_client', 'ipython'], - 'doc' : ['sphinx'], + 'doc' : ['sphinx', 'recommonmark', "sphinxcontrib-napoleon", "nbsphinx"], '10x': ['pathos', 'bamnostic>=0.9.2'], }, "include_package_data": True, diff --git a/tox.ini b/tox.ini index 5afa1e9c42..ba5f302792 100644 --- a/tox.ini +++ b/tox.ini @@ -1,18 +1,111 @@ [tox] -envlist=py27,py35,py36,py37 +envlist = + py35, + py36, + py37, + coverage, + docs, + package_description +# fix_lint, +isolated_build = true +skip_missing_interpreters = true [testenv] -passenv = CI TRAVIS TRAVIS_* -whitelist_externals= - make -deps= - codecov - ipfshttpclient - redis - bamnostic - pathos -commands= - pip install -r requirements.txt - pip install -e .[test] - make coverage - codecov --gcov-glob third-party +description = run the tests with pytest under {basepython} +setenv = PIP_DISABLE_VERSION_CHECK = 1 + COVERAGE_FILE = {env:COVERAGE_FILE:{toxworkdir}/.coverage.{envname}} + VIRTUALENV_NO_DOWNLOAD = 1 +passenv = http_proxy https_proxy no_proxy SSL_CERT_FILE PYTEST_* +deps = + pip >= 19.1 +extras = test +changedir = tests +commands = pytest \ + --cov "{envsitepackagesdir}/sourmash" \ + --cov-config "{toxinidir}/tox.ini" \ + --junitxml {toxworkdir}/junit.{envname}.xml \ + {posargs:.} + +[tox:.package] +basepython = python3 + +[testenv:docs] +description = invoke sphinx-build to build the HTML docs +basepython = python3.7 +extras = doc +whitelist_externals = pandoc +passenv = HOME +changedir = {toxinidir} +#commands = sphinx-build -d "{toxworkdir}/docs_doctree" doc "{toxworkdir}/docs_out" --color -W -bhtml {posargs} +commands = sphinx-build -d "{toxworkdir}/docs_doctree" doc "{toxworkdir}/docs_out" --color -bhtml {posargs} + python -c 'import pathlib; print("documentation available under file://\{0\}".format(pathlib.Path(r"{toxworkdir}") / "docs_out" / "index.html"))' + +[testenv:package_description] +description = check that the long description is valid +basepython = python3.7 +deps = twine >= 1.12.1 + # TODO installing readme-renderer[md] should not be necessary + readme-renderer[md] >= 24.0 + pip >= 19.1 +skip_install = true +changedir = {toxinidir} +extras = +commands = pip wheel -w {envtmpdir}/build --no-deps . + twine check {envtmpdir}/build/* + +[testenv:fix_lint] +description = format the code base to adhere to our styles, and complain about what we cannot do automatically +basepython = python3.7 +passenv = {[testenv]passenv} + # without PROGRAMDATA cloning using git for Windows will fail with an + # `error setting certificate verify locations` error + PROGRAMDATA +extras = lint +deps = pre-commit >= 1.14.4, < 2 +skip_install = True +commands = pre-commit run --all-files --show-diff-on-failure + python -c 'import pathlib; print("hint: run \{\} install to add checks as pre-commit hook".format(pathlib.Path(r"{envdir}") / "bin" / "pre-commit"))' + +[testenv:coverage] +description = [run locally after tests]: combine coverage data and create report; + generates a diff coverage against origin/master (can be changed by setting DIFF_AGAINST env var) +deps = {[testenv]deps} + coverage >= 4.4.1, < 5 + diff_cover +skip_install = True +passenv = {[testenv]passenv} + DIFF_AGAINST +setenv = COVERAGE_FILE={toxworkdir}/.coverage +commands = coverage combine + coverage report -m + coverage xml -o {toxworkdir}/coverage.xml + coverage html -d {toxworkdir}/htmlcov + diff-cover --compare-branch {env:DIFF_AGAINST:origin/master} {toxworkdir}/coverage.xml +depends = py27, py34, py35, py36, py37, pypy, pypy3 +parallel_show_output = True + +[testenv:codecov] +description = [only run on CI]: upload coverage data to codecov (depends on coverage running first) +passenv = {[testenv]passenv} + CODECOV_TOKEN +deps = codecov +skip_install = True +changedir = {toxinidir} +depends = coverage +commands = codecov --file "{toxworkdir}/coverage.xml" {posargs} + +[coverage:run] +branch = true +parallel = true + +[travis] +python = + 3.7: py37, docs, package_description + +[flake8] +max-complexity = 22 +max-line-length = 99 +ignore = E203, W503, C901, E402 + +[pep8] +max-line-length = 99