From fb4862c21a81bc67e0a0411e9acad3141e334051 Mon Sep 17 00:00:00 2001 From: mferrera Date: Tue, 21 Nov 2023 08:59:25 +0100 Subject: [PATCH] Move to a pyproject.toml based package --- .flake8 | 4 + .github/workflows/ci-xtgeoviz.yml | 46 ++++---- .github/workflows/linting.yml | 50 ++++++-- .github/workflows/xtgeoviz-publish-pypi.yml | 15 ++- pyproject.toml | 120 ++++++++++++++++---- pytest.ini | 12 -- requirements/requirements.txt | 5 - requirements/requirements_docs.txt | 6 - requirements/requirements_setup.txt | 3 - requirements/requirements_test.txt | 1 - requirements/requirements_testx.txt | 6 - scripts/README.txt | 3 - scripts/setup_functions.py | 89 --------------- setup.cfg | 27 ----- setup.py | 65 ----------- 15 files changed, 175 insertions(+), 277 deletions(-) create mode 100644 .flake8 delete mode 100644 pytest.ini delete mode 100644 requirements/requirements.txt delete mode 100644 requirements/requirements_docs.txt delete mode 100644 requirements/requirements_setup.txt delete mode 100644 requirements/requirements_test.txt delete mode 100644 requirements/requirements_testx.txt delete mode 100644 scripts/README.txt delete mode 100644 scripts/setup_functions.py delete mode 100644 setup.cfg delete mode 100755 setup.py diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..f451e26 --- /dev/null +++ b/.flake8 @@ -0,0 +1,4 @@ +[flake8] +max-line-length = 88 +ignore = E402, W503, E203, C901 +exclude = docs/conf.py, version.py diff --git a/.github/workflows/ci-xtgeoviz.yml b/.github/workflows/ci-xtgeoviz.yml index 1ef7a5e..5d5a091 100644 --- a/.github/workflows/ci-xtgeoviz.yml +++ b/.github/workflows/ci-xtgeoviz.yml @@ -1,38 +1,44 @@ -# build and test some end points name: Build and test xtgeoviz -# on: [push, pull_request] - on: + push: + branches: + - main pull_request: - branches: [main] + branches: + - main + release: + types: + - published + schedule: + # Run nightly to check that tests are working with latest dependencies + - cron: "0 0 * * *" jobs: - build_pywheels: - name: PY ${{ matrix.python-version }} on ${{ matrix.os }} - runs-on: ${{ matrix.os }} + test: strategy: matrix: - python-version: [3.8, 3.9, "3.10"] + python-version: ["3.8", "3.9", "3.10", "3.11"] os: [ubuntu-latest] + runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - name: Install library - run: > - pip install pip -U && - pip install . + - name: Clone xtgeo-testdata + run: git clone --depth 1 https://github.com/equinor/xtgeo-testdata ../xtgeo-testdata - - run: git clone --depth 1 https://github.com/equinor/xtgeo-testdata ../xtgeo-testdata - shell: bash + - name: Install + run: | + pip install -U pip + pip install ".[tests]" - - name: Full test - run: > - pip install -r requirements/requirements_test.txt && - pytest --disable-warnings -x + - name: Run tests + run: pytest -n auto --disable-warnings diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 938768c..45109a6 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -1,21 +1,49 @@ -name: linting +name: Linting -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: + branches: + - main + release: + types: + - published + schedule: + # Run nightly to check that tests are working with latest dependencies + - cron: "0 0 * * *" jobs: - linting: + lint: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8"] + python-version: ["3.8", "3.9", "3.10", "3.11"] + steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Set up python - uses: actions/setup-python@v2 - - name: Check black style and linting + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install run: | - pip install black - black --check *.py src tests - pip install flake8 - flake8 src tests + pip install -U pip + pip install ".[tests]" + + - name: Lint with isort + if: ${{ always() }} + run: isort --check-only --profile black src tests + + - name: Lint with black + if: ${{ always() }} + run: black --check src tests + + - name: Lint with flake8 + if: ${{ always() }} + run: flake8 src tests diff --git a/.github/workflows/xtgeoviz-publish-pypi.yml b/.github/workflows/xtgeoviz-publish-pypi.yml index 1583852..31e947c 100644 --- a/.github/workflows/xtgeoviz-publish-pypi.yml +++ b/.github/workflows/xtgeoviz-publish-pypi.yml @@ -8,16 +8,23 @@ jobs: build-n-publish: name: Build and publish Python 🐍 distributions 📦 to PyPI runs-on: ubuntu-latest + steps: - - uses: actions/checkout@master + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Python 3.8 - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: python-version: 3.8 + - name: Install dependencies - run: pip install --upgrade setuptools wheel twine + run: pip install -U setuptools build twine + - name: Build package - run: python setup.py sdist bdist_wheel + run: python -m build + - name: Upload deploy env: TWINE_USERNAME: __token__ diff --git a/pyproject.toml b/pyproject.toml index db8fad9..8612c5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,38 +1,108 @@ -# NOTE: you have to use single-quoted strings in TOML for regular expressions. - [build-system] requires = [ - "pip>=19.1.1", "setuptools>=45", "setuptools_scm[toml]>=6.2", - "wheel", ] +build-backend = "setuptools.build_meta" + +[tool.setuptools_scm] +write_to = "src/xtgeoviz/version.py" [project] name = "xtgeoviz" +description = "Plotting library for xtgeo objects" +readme = "README.md" +requires-python = ">=3.8" +license = { file = "LICENSE" } +authors = [ + { name = "Equinor", email = "fg_fmu-atlas@equinor.com" }, +] +keywords = [ + "energy", + "subsurface", + "reservoir", + "scientific", + "engineering", + "maps", + "xtgeo", +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Science/Research", + "Intended Audience :: Developers", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Physics", + "Topic :: Software Development :: Libraries", + "Topic :: Utilities", + "Operating System :: POSIX :: Linux", + "Operating System :: Microsoft :: Windows", + "Operating System :: MacOS", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Natural Language :: English", + "License :: OSI Approved :: GNU Lesser General Public", + "License v3 or later (LGPLv3+)", +] dynamic = ["version"] +dependencies = [ + "xtgeo>=2.14", + "PyYAML", + "scipy>=1.5.3", + "matplotlib>=3.3.2", + "numpy>=1.19.2", +] + +[project.optional-dependencies] +tests = [ + "black", + "coverage>=4.1", + "flake8", + "isort", + "mypy", + "pylint", + "pytest", + "pytest-cov", + "pytest-runner", + "pytest-mock", + "pytest-xdist", + "rstcheck", + "types-PyYAML", +] +docs = [ + "sphinx", + "autoapi", + "sphinxcontrib-apidoc", + "sphinx-argparse", + "sphinx-autodoc-typehints", + "sphinx-copybutton", + "sphinx-togglebutton", + "sphinx_rtd_theme", +] + +[project.urls] +Homepage = "https://github.com/equinor/xtgeoviz" +Repository = "https://github.com/equinor/xtgeoviz" +Documentation = "https://github.com/equinor/xtgeoviz" +Issues = "https://github.com/equinor/xtgeoviz/issues" [tool.black] line-length = 88 -target-version = ['py36', 'py37', 'py38', 'py39', 'py310'] -include = '\.pyi?$' -exclude = ''' -/( - \.eggs - | \.git - | \.hg - | \.mypy_cache - | \.tox - | \.venv - | _buildsetuptools.scm - | buck-out - | build - | dist - # The following are specific to Black, you probably don't want those. - | blib2to3 - | profiling -)/ -''' -[tool.setuptools_scm] -write_to = "src/xtgeoviz/version.py" +[tool.isort] +profile = "black" + +[tool.mypy] +ignore_missing_imports = true + +[tool.pytest.ini_options] +minversion = "6.0" +addopts = "--verbose" +log_cli = "False" +log_cli_format = "%(levelname)8s (%(relativeCreated)6.0fms) %(filename)44s [%(funcName)40s()] %(lineno)4d >> %(message)s" +log_cli_level = "INFO" +testpaths = "tests" +markers = [ + "integration: Integration tests", +] diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index ff31a0d..0000000 --- a/pytest.ini +++ /dev/null @@ -1,12 +0,0 @@ -#pytest tests/test_grid3d/test_grid.py::test_roffbin_import_v2_emerald -o log_cli=true -s - -[pytest] -minversion = 6.0 -addopts = --verbose -log_cli = False -log_cli_format = %(levelname)8s (%(relativeCreated)6.0fms) %(name)45s [%(funcName)32s()] %(lineno)4d >> %(message)s -log_cli_level = INFO -testpaths = - tests -markers = - style: from matplotlib test diff --git a/requirements/requirements.txt b/requirements/requirements.txt deleted file mode 100644 index 62d4b66..0000000 --- a/requirements/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -xtgeo>=2.14 -PyYAML -scipy>=1.5.3 -matplotlib>=3.3.2 -numpy>=1.19.2 diff --git a/requirements/requirements_docs.txt b/requirements/requirements_docs.txt deleted file mode 100644 index a4107c5..0000000 --- a/requirements/requirements_docs.txt +++ /dev/null @@ -1,6 +0,0 @@ -sphinx<6,>=1.6 -sphinx-rtd-theme -autoapi -sphinx-autodoc-typehints -sphinxcontrib-apidoc -docutils<0.18 diff --git a/requirements/requirements_setup.txt b/requirements/requirements_setup.txt deleted file mode 100644 index 797c305..0000000 --- a/requirements/requirements_setup.txt +++ /dev/null @@ -1,3 +0,0 @@ -setuptools>=45 -setuptools_scm>=6.2 -pytest-runner diff --git a/requirements/requirements_test.txt b/requirements/requirements_test.txt deleted file mode 100644 index 55b033e..0000000 --- a/requirements/requirements_test.txt +++ /dev/null @@ -1 +0,0 @@ -pytest \ No newline at end of file diff --git a/requirements/requirements_testx.txt b/requirements/requirements_testx.txt deleted file mode 100644 index 6e7bea8..0000000 --- a/requirements/requirements_testx.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Extras for tests, formatting and linting -black>=20.8b0 -flake8 -pytest-cov -pytest-mock -rstcheck diff --git a/scripts/README.txt b/scripts/README.txt deleted file mode 100644 index fc73810..0000000 --- a/scripts/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -Helper functions and extra requirements for setup.py. - -The purpose is to keep setup.py lean and clean diff --git a/scripts/setup_functions.py b/scripts/setup_functions.py deleted file mode 100644 index de0aa2e..0000000 --- a/scripts/setup_functions.py +++ /dev/null @@ -1,89 +0,0 @@ -"""Setup helpers for setup.py in xtgeoviz package.""" -import os -from os.path import exists -from shutil import rmtree -import fnmatch - -from distutils.command.clean import clean as _clean - - -def parse_requirements(filename): - """Load requirements from a pip requirements file.""" - try: - lineiter = (line.strip() for line in open(filename)) - return [line for line in lineiter if line and not line.startswith("#")] - except OSError: - return [] - - -# ====================================================================================== -# Overriding and extending setup commands; here "clean" -# ====================================================================================== - - -class CleanUp(_clean): - """Custom implementation of ``clean`` command. - - Overriding clean in order to get rid if "dist" folder and etc, see setup.py. - """ - - CLEANFOLDERS = ( - "__pycache__", - "pip-wheel-metadata", - ".eggs", - "dist", - "build", - "sdist", - "wheel", - ".pytest_cache", - "docs/apiref", - "docs/_build", - "result_images", - ) - - CLEANFOLDERSRECURSIVE = ["__pycache__", "_tmp_*", "*.egg-info"] - CLEANFILESRECURSIVE = ["*.pyc", "*.pyo"] - - @staticmethod - def ffind(pattern, path): - """Find files.""" - result = [] - for root, _, files in os.walk(path): - for name in files: - if fnmatch.fnmatch(name, pattern): - result.append(os.path.join(root, name)) - return result - - @staticmethod - def dfind(pattern, path): - """Find folders.""" - result = [] - for root, dirs, _ in os.walk(path): - for name in dirs: - if fnmatch.fnmatch(name, pattern): - result.append(os.path.join(root, name)) - return result - - def run(self): - """Execute run. - - After calling the super class implementation, this function removes - the directories specific to scikit-build ++. - """ - super(CleanUp, self).run() - - for dir_ in CleanUp.CLEANFOLDERS: - if exists(dir_): - print(f"Removing: {dir_}") - if not self.dry_run and exists(dir_): - rmtree(dir_) - - for dir_ in CleanUp.CLEANFOLDERSRECURSIVE: - for pdir in self.dfind(dir_, "."): - print(f"Remove folder {pdir}") - rmtree(pdir) - - for fil_ in CleanUp.CLEANFILESRECURSIVE: - for pfil in self.ffind(fil_, "."): - print(f"Remove file {pfil}") - os.unlink(pfil) diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 7c0843e..0000000 --- a/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[bdist_wheel] -universal = 1 - -[aliases] -test = pytest - -[flake8] -max-line-length = 88 -ignore = E203, W503 - -[tool:pytest] -norecursedirs = - .git - .tox - .env - dist - build - -addopts = - -ra - --strict-markers - --ignore=docs/conf.py - --ignore=setup.py - --ignore=.eggs - -markers = - integration: marks a test as an integration test diff --git a/setup.py b/setup.py deleted file mode 100755 index 37b5a2f..0000000 --- a/setup.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python3 -"""Setup for xtgeoviz package.""" -from glob import glob -from os.path import basename, splitext - -import setuptools - -from scripts import setup_functions as sf - -CMDCLASS = {"clean": sf.CleanUp} - -try: - from sphinx.setup_command import BuildDoc - - CMDCLASS.update({"build_sphinx": BuildDoc}) -except ImportError: - # sphinx not installed - do not provide build_sphinx cmd - pass - -REQUIREMENTS = sf.parse_requirements("requirements/requirements.txt") - -SETUP_REQUIREMENTS = sf.parse_requirements("requirements/requirements_setup.txt") -TEST_REQUIREMENTS = sf.parse_requirements("requirements/requirements_test.txt") -TEST_REQUIREMENTS.extend(sf.parse_requirements("requirements/requirements_testx.txt")) -DOCS_REQUIREMENTS = sf.parse_requirements("requirements/requirements_docs.txt") - -EXTRAS_REQUIRE = {"tests": TEST_REQUIREMENTS, "docs": DOCS_REQUIREMENTS} - -setuptools.setup( - name="xtgeoviz", - description="Plotting library for xtgeo objects", - author="Equinor", - author_email="____@equinor.com", - url="https://github.com/equinor/xtgeoviz", - project_urls={ - "Documentation": "https://xtgeoviz.notyet_on_readthedocs.io/", - "Issue Tracker": "https://github.com/equinor/xtgeoviz/issues", - }, - keywords=[], - license="LGPL-3.0", - platforms="any", - cmdclass=CMDCLASS, - include_package_data=True, - packages=setuptools.find_packages("src"), - package_dir={"": "src"}, - py_modules=[splitext(basename(path))[0] for path in glob("src/*.py")], - install_requires=REQUIREMENTS, - setup_requires=SETUP_REQUIREMENTS, - use_scm_version={"write_to": "src/xtgeoviz/version.py"}, - test_suite="tests", - extras_require=EXTRAS_REQUIRE, - classifiers=[ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "License :: OSI Approved :: GNU Lesser General Public " - "License v3 or later (LGPLv3+)", - "Natural Language :: English", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Intended Audience :: Science/Research", - "Topic :: Scientific/Engineering", - "Topic :: Software Development :: Libraries", - ], -)