From e06e636641fc2cc1c22a7e97a19ccd0f2d4e9606 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Thu, 30 Nov 2023 16:23:47 +0100 Subject: [PATCH] maint: migrate to PEP517/518 packaging --- .circleci/config.yml | 16 +- .git_archival.txt | 5 +- .gitattributes | 1 - .github/workflows/docs-build-pr.yml | 6 +- .github/workflows/docs-build-update.yml | 6 +- .github/workflows/pythonpackage.yml | 6 +- .github/workflows/unittests.yml | 4 +- .gitignore | 2 +- MANIFEST.in | 7 - pyproject.toml | 192 ++++++++++++++++++++++-- setup.cfg | 113 -------------- setup.py | 18 --- 12 files changed, 207 insertions(+), 169 deletions(-) delete mode 100644 MANIFEST.in delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/.circleci/config.yml b/.circleci/config.yml index 20057a3500..8d91c9e98c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -229,10 +229,10 @@ jobs: command: | export PY3=$( pyenv versions | awk '/^\* 3/ { print $2 }' ) pyenv local $PY3 - python3 -m pip install --upgrade setuptools setuptools_scm pip + python3 -m pip install -U build hatch hatchling pip twine docutils # Get version, update files. - THISVERSION=$( python3 -m setuptools_scm ) + THISVERSION=$( python3 -m hatch version | tail -n1 | xargs ) if [[ ${THISVERSION:0:1} == "0" ]] ; then echo "WARNING: latest git tag could not be found" echo "Please, make sure you fetch all tags from upstream with" @@ -255,7 +255,7 @@ jobs: export PY3=$( pyenv versions | awk '/^\* 3/ { print $2 }' ) pyenv local $PY3 # Get version, update files. - THISVERSION=$( python3 -m setuptools_scm ) + THISVERSION=$( python3 -m hatch version | tail -n1 | xargs ) BUILT_VERSION=$( docker run --rm --entrypoint=python nipreps/sdcflows:latest -c "import sdcflows; print(sdcflows.__version__)" ) BUILT_VERSION=${BUILT_VERSION%$'\r'} echo "VERSION: \"$THISVERSION\"" @@ -376,13 +376,13 @@ jobs: command: | python -m venv /tmp/venv source /tmp/venv/bin/activate - python -m pip install -U pip setuptools setuptools_scm - pip install --no-cache-dir -r docs/requirements.txt + python -m pip install -U build hatch hatchling pip twine docutils + python -m pip install --no-cache-dir -r docs/requirements.txt - run: name: Build only this commit command: | source /tmp/venv/bin/activate - python -m setuptools_scm + python -m hatch version | tail -n1 | xargs BRANCH=$( echo $CIRCLE_BRANCH | sed 's+/+_+g' ) make -C docs SPHINXOPTS="-W" BUILDDIR="$HOME/docs" OUTDIR=${CIRCLE_TAG:-$BRANCH} html - store_artifacts: @@ -422,7 +422,7 @@ jobs: command: | python -m venv /tmp/buildenv source /tmp/buildenv/bin/activate - python -m pip install -U build twine setuptools_scm + python3 -m pip install -U build hatch hatchling pip twine docutils python3 -m build twine check dist/sdcflows* - store_artifacts: @@ -435,7 +435,7 @@ jobs: name: Validate version command: | source /tmp/buildenv/bin/activate - THISVERSION=$( python -m setuptools_scm ) + THISVERSION=$( python -m hatch version | tail -n1 | xargs ) python -m pip install dist/*.whl mkdir empty cd empty diff --git a/.git_archival.txt b/.git_archival.txt index 95cb3eea4e..b1a286bbb6 100644 --- a/.git_archival.txt +++ b/.git_archival.txt @@ -1 +1,4 @@ -ref-names: $Format:%D$ +node: $Format:%H$ +node-date: $Format:%cI$ +describe-name: $Format:%(describe:tags=true,match=*[0-9]*)$ +ref-names: $Format:%D$ \ No newline at end of file diff --git a/.gitattributes b/.gitattributes index 555b4f7438..00a7b00c94 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1 @@ -sdcflows/_version.py export-subst .git_archival.txt export-subst diff --git a/.github/workflows/docs-build-pr.yml b/.github/workflows/docs-build-pr.yml index 5052f3a86a..49ce59f696 100644 --- a/.github/workflows/docs-build-pr.yml +++ b/.github/workflows/docs-build-pr.yml @@ -46,9 +46,9 @@ jobs: - name: Install dependencies run: | - pip install -r docs/requirements.txt - pip install --no-cache-dir "setuptools ~= 45.0" "setuptools_scm[toml] >= 3.4" - python setup.py --version + python -m pip install -U build hatch hatchling pip docutils + python -m pip install -r docs/requirements.txt + python -m hatch version | tail -n1 | xargs - name: Build docs run: | diff --git a/.github/workflows/docs-build-update.yml b/.github/workflows/docs-build-update.yml index 9079c0538a..0bfa5451f2 100644 --- a/.github/workflows/docs-build-update.yml +++ b/.github/workflows/docs-build-update.yml @@ -46,9 +46,9 @@ jobs: - name: Install dependencies run: | - pip install -r docs/requirements.txt - pip install --no-cache-dir "setuptools ~= 45.0" "setuptools_scm[toml] >= 3.4" - python setup.py --version + python -m pip install -U build hatch hatchling pip docutils + python -m pip install -r docs/requirements.txt + python -m hatch version | tail -n1 | xargs - name: Build docs run: | diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 63cdfa897c..1433fe7537 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -45,8 +45,8 @@ jobs: if [[ "$GITHUB_REF" == refs/tags/* ]]; then VERSION=${GITHUB_REF##*/} else - pip install setuptools_scm - VERSION=$( python -m setuptools_scm ) + pip install -U build hatch hatchling pip twine docutils + VERSION=$( python -m hatch version | tail -n1 | xargs ) fi echo version=$VERSION | tee -a $GITHUB_OUTPUT @@ -78,7 +78,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.12"] + python-version: ["3.10", "3.12"] install: [repo, sdist, wheel, editable] env: diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index cdbaec4c50..576cbe4d05 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -35,10 +35,10 @@ jobs: strategy: max-parallel: 5 matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.10", "3.11", "3.12"] deps: ["requirements"] include: - - python-version: "3.8" + - python-version: "3.10" deps: "min-requirements" steps: diff --git a/.gitignore b/.gitignore index cc963e99c6..bada2f41a9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # setuptools-scm -sdcflows/_version.py +_version.py # Byte-compiled / optimized / DLL files pip-wheel-metadata diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index f3d419c384..0000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,7 +0,0 @@ -recursive-exclude .circleci/ * -recursive-exclude .docker/ * -recursive-exclude .github/ * -recursive-exclude docs/ * - -exclude .* -exclude Dockerfile diff --git a/pyproject.toml b/pyproject.toml index fee7fc6618..8616d34884 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,184 @@ [build-system] -requires = ["setuptools >= 42.0", "wheel", "setuptools_scm[toml] >= 3.4"] - -[tool.setuptools_scm] -write_to = "sdcflows/_version.py" -write_to_template = """\ -\"\"\"Version file, automatically generated by setuptools_scm.\"\"\" -__version__ = "{version}" -""" -fallback_version = "0.0" +requires = ["hatchling", "hatch-vcs", "nipreps-versions"] +build-backend = "hatchling.build" + +[project] +name = "sdcflows" +description = "Susceptibility Distortion Correction (SDC) workflows for EPI MR schemes." +readme = "README.rst" +authors = [{name = "The NiPreps Developers", email = "nipreps@gmail.com"}] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering :: Image Recognition", + "Topic :: Scientific/Engineering :: Bio-Informatics", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +license = "Apache-2.0" +requires-python = ">=3.10" +dependencies = [ + "attrs >= 20.1.0", + "nibabel >=3.1.0", + "nipype >=1.8.5,<2.0", + "traits <6.4", + "niworkflows >= 1.7.0", + "nitransforms >= 23.0.1", + "numpy >= 1.21.0", + "pybids >= 0.15.1", + "scikit-image >= 0.18", + "scipy >= 1.8.1", + "templateflow", +] +dynamic = ["version"] + +[project.urls] +Documentation = "https://www.nipreps.org/sdcflows" +Home = "https://github.com/nipreps/sdcflows" +NiPreps = "https://www.nipreps.org/" + +[project.optional-dependencies] +doc = [ + "attrs >= 20.1.0", + "furo", + "importlib_resources", + "matplotlib >= 2.2.0", + "nibabel", + "nipype >= 1.5.1", + "traits < 6.4", + "niworkflows ~= 1.6.3", + "numpy", + "packaging", + "pydot >= 1.2.3", + "pydotplus", + "sphinx >= 7.2.2", + "sphinxcontrib-apidoc", + "templateflow" +] + +mem = [ + "psutil" +] + +dev = [ + "black", + "pre-commit", + "isort", + "flake8-pyproject", +] + +test = [ + "coverage", + "pytest", + "pytest-cov", + "pytest-env", + "pytest-xdist" +] + +# Aliases +docs = ["sdcflows[doc]"] +tests = ["sdcflows[test]"] +all = ["sdcflows[doc,test,mem,dev,test]"] + +[project.scripts] +sdcflows-find-estimators = "sdcflows.cli.find_estimators:main" + +# +# Hatch configurations +# + +[tool.hatch.metadata] +allow-direct-references = true + +[tool.hatch.build.targets.sdist] +exclude = [".git_archival.txt"] # No longer needed in sdist + +[tool.hatch.build.targets.wheel] +packages = ["sdcflows"] +# exclude = [ +# "sdcflows/tests/data", # Large test data directory +# ] + +## The following two sections configure setuptools_scm in the hatch way + +[tool.hatch.version] +validate-bump = true +source = "vcs" +raw-options = { version_scheme = "nipreps-calver" } + +[tool.hatch.build.hooks.vcs] +version-file = "sdcflows/_version.py" + +# +# Developer tool configurations +# + +[tool.black] +line-length = 99 +target-version = ['py39'] +skip-string-normalization = true +exclude = ''' +# Directories +/( + \.eggs + | \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | venv + | _build + | build + | dist +)/ +''' + +[tool.isort] +profile = 'black' +skip_gitignore = true + +[tool.flake8] +max-line-length = "99" +doctests = "False" +exclude = "*build/" +ignore = ["W503", "E203"] +per-file-ignores = [ + "**/__init__.py : F401", + "docs/conf.py : E265", +] + +[tool.pytest.ini_options] +norecursedirs = [".git"] +addopts = "-svx --doctest-modules" +doctest_optionflags = "ALLOW_UNICODE NORMALIZE_WHITESPACE ELLIPSIS" +env = "PYTHONHASHSEED=0" +filterwarnings = ["ignore::DeprecationWarning"] +junit_family = "xunit2" + + +[tool.coverage.run] +branch = true +concurrency = 'multiprocessing' +omit = [ + '*/tests/*', + '*/__init__.py', + '*/conftest.py', + 'sdcflows/_version.py' +] + +[tool.coverage.report] +# Regexes for lines to exclude from consideration +exclude_lines = [ + 'raise NotImplementedError', + 'warnings\.warn', +] + +[tool.codespell] +# nd - import scipy.ndimage as nd +# mapp, reson -- Mapp. and Reson. abbreviations in citation +ignore-words-list = 'nd,mapp,reson' +skip = """ +./.git,*.pdf,*.svg,*.min.js,*.ipynb,ORIGINAL_LICENSE,\ +./docs/source/_static/example_anatreport.html""" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index bf6733a744..0000000000 --- a/setup.cfg +++ /dev/null @@ -1,113 +0,0 @@ -[metadata] -author = The SDCflows developers -author_email = nipreps@gmail.com -classifiers = - Development Status :: 4 - Beta - Intended Audience :: Science/Research - Topic :: Scientific/Engineering :: Image Recognition - License :: OSI Approved :: Apache Software License - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: 3.12 -description = Susceptibility Distortion Correction (SDC) workflows for EPI MR schemes. -license = Apache-2.0 -long_description = file:README.rst -long_description_content_type = text/x-rst; charset=UTF-8 -name = sdcflows -project_urls = - Documentation = https://www.nipreps.org/sdcflows - GitHub = https://github.com/nipreps/sdcflows - fMRIPrep = https://fmriprep.readthedocs.io -url = https://www.nipreps.org/sdcflows - -[options] -python_requires = >=3.8 -install_requires = - attrs >= 20.1.0 - importlib_resources >= 5.7; python_version < '3.11' - nibabel >=3.1.0 - nipype >=1.8.5,<2.0 - traits <6.4 - niworkflows >= 1.7.0 - nitransforms >= 23.0.1 - numpy >= 1.21.0 - pybids >= 0.15.1 - scikit-image >= 0.18 - scipy >= 1.8.1 - templateflow -packages = find: -include_package_data = True -zip_safe = True - -[options.exclude_package_data] -* = tests - -[options.extras_require] -doc = - furo ~= 2021.10.09 - pydot - pydotplus - sphinx - sphinxcontrib-apidoc - sphinxcontrib-napoleon -docs = - %(doc)s -mem = - psutil - -test = - coverage - pytest - pytest-cov - pytest-env - pytest-xdist -tests = - %(test)s - -all = - %(doc)s - %(mem)s - %(test)s - -[options.package_data] -sdcflows = - data/*.json - data/*.nii.gz - data/*.mat - data/flirtsch/*.cnf - -[options.entry_points] -console_scripts = - sdcflows-find-estimators=sdcflows.cli.find_estimators:main - -[flake8] -max-line-length = 99 -doctests = False -ignore = - W503 - E231 - E203 -exclude = - *build/ - docs/sphinxext/ - docs/tools/ -per-file-ignores = - **/__init__.py : F401 - docs/conf.py : E265 - -[tool:pytest] -norecursedirs = .git -addopts = -vsx --doctest-modules -doctest_optionflags = ALLOW_UNICODE NORMALIZE_WHITESPACE NUMBER -env = - PYTHONHASHSEED=0 -filterwarnings = - ignore::DeprecationWarning - ignore::PendingDeprecationWarning - ignore:cmp not installed:UserWarning - ignore:This has not been fully tested:UserWarning - -[coverage:run] -concurrency = multiprocessing diff --git a/setup.py b/setup.py deleted file mode 100644 index c2b82d2f5b..0000000000 --- a/setup.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Author: oesteban -# @Date: 2015-11-19 16:44:27 -"""sdcflows setup script.""" - - -def main(): - """Install entry-point.""" - from setuptools import setup - - setup( - name="sdcflows", use_scm_version=True, - ) - - -if __name__ == "__main__": - main()