From 3ae6b3a91fa49e2b943b2965dd477c572d53b954 Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Fri, 17 Nov 2023 14:09:19 -0500 Subject: [PATCH 01/18] adopt pyproject.toml standard, fast-forward cookiecutter --- .cruft.json | 3 +- .../workflows/actions-versions-updater.yml | 24 ++ .github/workflows/bump-version.yml | 58 +++++ .github/workflows/main.yml | 119 ++++++---- .github/workflows/publish-pypi.yml | 8 +- .github/workflows/tag-testpypi.yml | 30 ++- .pre-commit-config.yaml | 23 +- .readthedocs.yml | 2 +- HISTORY.rst => CHANGES.rst | 6 +- CONTRIBUTING.rst | 41 ++-- MANIFEST.in | 26 --- Makefile | 21 +- README.rst | 6 +- docs/changes.rst | 1 + docs/history.rst | 1 - docs/index.rst | 2 +- docs/installation.rst | 4 +- environment.yml => environment-dev.yml | 0 figanos/__init__.py | 2 +- pyproject.toml | 221 ++++++++++++++++++ requirements_dev.txt | 15 -- requirements_docs.txt | 20 -- setup.cfg | 59 ++--- tox.ini | 12 +- 24 files changed, 494 insertions(+), 210 deletions(-) create mode 100644 .github/workflows/actions-versions-updater.yml create mode 100644 .github/workflows/bump-version.yml rename HISTORY.rst => CHANGES.rst (99%) delete mode 100644 MANIFEST.in create mode 100644 docs/changes.rst delete mode 100644 docs/history.rst rename environment.yml => environment-dev.yml (100%) create mode 100644 pyproject.toml delete mode 100644 requirements_dev.txt delete mode 100644 requirements_docs.txt diff --git a/.cruft.json b/.cruft.json index 01a9e689..d1889f0e 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/Ouranosinc/cookiecutter-pypackage", - "commit": "240a2c784f89cb1e2c5952869413c5582e590345", + "commit": "d4c119c04266c970bc4785a04916475bf95b5d0a", "checkout": null, "context": { "cookiecutter": { @@ -14,6 +14,7 @@ "version": "0.2.0", "use_pytest": "y", "use_black": "y", + "use_conda": "y", "add_pyup_badge": "n", "make_docs": "y", "command_line_interface": "Click", diff --git a/.github/workflows/actions-versions-updater.yml b/.github/workflows/actions-versions-updater.yml new file mode 100644 index 00000000..bb05b24e --- /dev/null +++ b/.github/workflows/actions-versions-updater.yml @@ -0,0 +1,24 @@ +name: GitHub Actions Version Updater + +on: + schedule: + # 12:00 AM on the first of every month + - cron: '0 0 1 * *' + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4.1.1 + with: + # This requires a personal access token with the privileges to push directly to `main` + token: ${{ secrets.WORKFLOW_TOKEN }} + persist-credentials: true + - name: Run GitHub Actions Version Updater + uses: saadmk11/github-actions-version-updater@v0.8.1 + with: + token: ${{ secrets.WORKFLOW_TOKEN }} + committer_email: 'bumpversion[bot]@ouranos.ca' + committer_username: 'update-github-actions[bot]' + pull_request_title: '[bot] Update GitHub Action Versions' diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml new file mode 100644 index 00000000..6c511900 --- /dev/null +++ b/.github/workflows/bump-version.yml @@ -0,0 +1,58 @@ +name: "Bump Patch Version" + +on: + push: + branches: + - main + paths-ignore: + - .cruft.json + - .editorconfig + - .github/**.yml + - .gitignore + - .pre-commit-config.yaml + - .yamllint.yaml + - .zenodo.json + - AUTHORS.rst + - CONTRIBUTING.rst + - CHANGES.rst + - Makefile + - .readthedocs.yml + - docs/*.py + - docs/*.rst + - environment-docs.yml + - environment-dev.yml + - setup.cfg + - pyproject.toml + - tests/**.py + - tox.ini + - figanos/__init__.py + workflow_dispatch: + +jobs: + bump_patch_version: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + - name: Config Commit Bot + run: | + git config --local user.email "bumpversion[bot]@ouranos.ca" + git config --local user.name "bumpversion[bot]" + - name: Current Version + run: echo "current_version=$(grep -E '__version__' figanos/__init__.py | cut -d ' ' -f3)" + - name: Bump Patch Version + run: | + pip install bump2version + echo "Bumping version" + bump2version patch + echo "new_version=$(grep -E '__version__' figanos/__init__.py | cut -d ' ' -f3)" + - name: Push Changes + uses: ad-m/github-push-action@master + with: + force: false + github_token: ${{ secrets.WORKFLOW_TOKEN }} + branch: ${{ github.ref }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0a528328..90dcccf4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,40 +5,41 @@ on: branches: - main paths-ignore: - - HISTORY.rst - - MANIFEST.in + - CHANGES.rst - README.rst - - setup.py + - pyproject.toml - setup.cfg - figanos/__init__.py pull_request: jobs: - black: - name: Black (Python${{ matrix.python-version }}) + lint: + name: Lint (Python${{ matrix.python-version }}) runs-on: ubuntu-latest strategy: matrix: python-version: - - "3.8" + - "3.x" steps: - name: Cancel previous runs uses: styfle/cancel-workflow-action@0.11.0 with: access_token: ${{ secrets.GITHUB_TOKEN }} - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install tox - run: pip install tox + run: | + python -m pip install tox - name: Run linting suite - run: tox -e black + run: | + python -m tox -e lint - test: - name: test-${{ matrix.tox-env }} (Python${{ matrix.python-version }}) - needs: black + test-pypi: + name: Test with Python${{ matrix.python-version }} (Python${{ matrix.python-version }} + tox) + needs: lint runs-on: ubuntu-latest strategy: matrix: @@ -52,38 +53,76 @@ jobs: - tox-env: "py311" python-version: "3.11" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} -# - name: Install tox -# run: pip install tox -# - name: Test with tox -# run: tox -e ${{ matrix.tox-env }} -# env: -# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -# COVERALLS_FLAG_NAME: run-${{ matrix.tox-env }} -# COVERALLS_PARALLEL: true -# COVERALLS_SERVICE_NAME: github - - name: Install figanos (no dependencies) + - name: Install tox + run: pip install tox + - name: Test with tox + run: tox -e ${{ matrix.tox-env }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COVERALLS_FLAG_NAME: run-${{ matrix.tox-env }} + COVERALLS_PARALLEL: true + COVERALLS_SERVICE_NAME: github + + test-conda: + name: Test with Python${{ matrix.python-version }} (Anaconda) + needs: lint + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11"] + defaults: + run: + shell: bash -l {0} + steps: + - uses: actions/checkout@v4 + - name: Setup Conda (Micromamba) with Python${{ matrix.python-version }} + uses: mamba-org/setup-micromamba@v1 + with: + cache-downloads: true + environment-file: environment-dev.yml + create-args: >- + mamba + python=${{ matrix.python-version }} + - name: Conda and Mamba versions + run: | + mamba --version + echo "micromamba $(micromamba --version)" + - name: Compile catalogs and install xscen + run: | + make translate + python -m pip install --no-deps --editable . + - name: Check versions + run: | + conda list + python -m pip check || true + - name: Test with pytest run: | - python -m pip install -e . --no-dependencies - - name: Smoke tests + python -m pytest tests + - name: Report coverage run: | - python -m pip install pytest - pytest + python -m coveralls + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COVERALLS_FLAG_NAME: run-Python__PYTHON_VERSION_-conda + COVERALLS_PARALLEL: true + COVERALLS_SERVICE_NAME: github -# finish: -# needs: -# - test -# runs-on: ubuntu-latest -# container: python:3-slim -# steps: -# - name: Coveralls Finished -# run: | -# pip install --upgrade coveralls -# coveralls --finish -# env: -# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -# COVERALLS_SERVICE_NAME: github + finish: + needs: + - test-pypi + - test-conda + runs-on: ubuntu-latest + container: python:3-slim + steps: + - name: Coveralls Finished + run: | + python -m pip install --upgrade coveralls + python -m coveralls --finish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COVERALLS_SERVICE_NAME: github diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 08a5bf77..fd8758a5 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -8,22 +8,22 @@ on: jobs: build-n-publish-pypi: name: Build and publish Python 🐍 distributions 📦 to PyPI - environment: production runs-on: ubuntu-latest + environment: production permissions: # IMPORTANT: this permission is mandatory for trusted publishing id-token: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python3 uses: actions/setup-python@v4 with: python-version: "3.x" - name: Install packaging libraries run: | - pip install setuptools wheel + python -m pip install flit - name: Build a binary wheel and a source tarball run: | - python setup.py sdist bdist_wheel + python -m flit build - name: Publish distribution 📦 to PyPI uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/tag-testpypi.yml b/.github/workflows/tag-testpypi.yml index ef6c5894..d9b3a4d0 100644 --- a/.github/workflows/tag-testpypi.yml +++ b/.github/workflows/tag-testpypi.yml @@ -3,28 +3,46 @@ name: Publish Python 🐍 distributions 📦 to TestPyPI on: push: tags: - - '*' + - 'v*.*' # Push events to matching v*, i.e. v1.0, v20.15.10 jobs: - build-n-publish-testpypi: + + release: + name: Create Release from tag + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Create Release + uses: softprops/action-gh-release@v1 + env: + # This token is provided by Actions, you do not need to create your own token + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + name: Release ${{ github.ref }} + draft: true + prerelease: false + + deploy-testpypi: name: Build and publish Python 🐍 distributions 📦 to TestPyPI - environment: staging runs-on: ubuntu-latest + environment: staging permissions: # IMPORTANT: this permission is mandatory for trusted publishing id-token: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python3 uses: actions/setup-python@v4 with: python-version: "3.x" - name: Install packaging libraries run: | - pip install setuptools wheel + python -m pip install flit - name: Build a binary wheel and a source tarball run: | - python setup.py sdist bdist_wheel + python -m flit build - name: Publish distribution 📦 to Test PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7c476b5e..91d85e85 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,8 +18,13 @@ repos: - id: pretty-format-json args: [ '--autofix', '--no-ensure-ascii', '--no-sort-keys' ] exclude: .ipynb + - id: check-toml - id: check-yaml args: [ '--allow-multiple-documents' ] + - repo: https://github.com/pappasam/toml-sort + rev: v0.23.1 + hooks: + - id: toml-sort-fix - repo: https://github.com/pre-commit/pygrep-hooks rev: v1.10.0 hooks: @@ -29,11 +34,15 @@ repos: hooks: - id: black exclude: ^docs/ + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.1.4 + hooks: + - id: ruff - repo: https://github.com/pycqa/flake8 rev: 6.1.0 hooks: - id: flake8 - additional_dependencies: [ 'flake8-rst-docstrings' ] + additional_dependencies: [ 'flake8-alphabetize', 'flake8-rst-docstrings' ] args: ['--config=setup.cfg'] - repo: https://github.com/PyCQA/isort rev: 5.12.0 @@ -50,7 +59,7 @@ repos: rev: v0.3.9 hooks: - id: blackdoc - additional_dependencies: [ 'black==23.10.1' ] + additional_dependencies: [ 'black==23.11.0' ] - repo: https://github.com/kynan/nbstripout rev: 0.6.1 hooks: @@ -67,11 +76,11 @@ repos: hooks: - id: yamllint args: [ '--config-file=.yamllint.yaml' ] -# Git version too old on server -# - repo: https://github.com/mgedmin/check-manifest -# rev: "0.49" -# hooks: -# - id: check-manifest + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.27.1 + hooks: + - id: check-github-workflows + - id: check-readthedocs - repo: meta hooks: - id: check-hooks-apply diff --git a/.readthedocs.yml b/.readthedocs.yml index d812bec2..9738fc25 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -22,7 +22,7 @@ build: - sphinx-apidoc -o docs/apidoc --module-first figanos conda: - environment: environment.yml + environment: environment-dev.yml python: install: diff --git a/HISTORY.rst b/CHANGES.rst similarity index 99% rename from HISTORY.rst rename to CHANGES.rst index d114f606..af30371c 100644 --- a/HISTORY.rst +++ b/CHANGES.rst @@ -1,6 +1,6 @@ -======= -History -======= +========= +Changelog +========= 0.3.0 (Unreleased) ------------------ diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 4df44c47..b59d002c 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -59,18 +59,18 @@ Get Started! Ready to contribute? Here's how to set up `figanos` for local development for developers outside Ouranos. -1. Fork the `figanos` repo on GitHub. -2. Clone your fork locally:: +#. Fork the `figanos` repo on GitHub. +#. Clone your fork locally:: $ git clone git@github.com:your_name_here/figanos.git -3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:: +#. Install your local copy into a development environment. Using `mamba`, you can create a new development environment with:: - $ mkvirtualenv figanos - $ cd figanos/ - $ pip install -e . + $ mamba env create -f environment-dev.yml + $ conda activate figanos + $ flit install --symlink . -4. To ensure a consistent style, please install the pre-commit hooks to your repo:: +#. To ensure a consistent style, please install the pre-commit hooks to your repo:: $ pre-commit install @@ -79,36 +79,37 @@ Ready to contribute? Here's how to set up `figanos` for local development for de $ pre-commit run -a -5. Create a branch for local development:: +#. Create a branch for local development:: $ git checkout -b name-of-your-bugfix-or-feature Now you can make your changes locally. -6. When you're done making changes, check that your changes pass flake8, black, and the +#. When you're done making changes, check that your changes pass black, flake8, isort, and the tests, including testing other Python versions with tox:: - $ flake8 figanos tests $ black --check figanos tests - $ python setup.py test or pytest + $ flake8 figanos tests + $ isort --check-only --diff figanos tests + $ python -m pytest $ tox To get flake8, black, and tox, just pip install them into your virtualenv. -6. Commit your changes and push your branch to GitHub:: +#. Commit your changes and push your branch to GitHub:: $ git add . $ git commit -m "Your detailed description of your changes." $ git push origin name-of-your-bugfix-or-feature -7. If you are editing the docs, compile and open them with:: +#. If you are editing the docs, compile and open them with:: $ make docs # or to simply generate the html $ cd docs/ $ make html -7. Submit a pull request through the GitHub website. +#. Submit a pull request through the GitHub website. Pull Request Guidelines ----------------------- @@ -128,7 +129,6 @@ To run a subset of tests:: $ pytest tests.test_figanos - Versioning/Tagging ------------------ @@ -182,8 +182,7 @@ Before updating the main conda-forge recipe, we echo the conda-forge documentati Subsequent releases ^^^^^^^^^^^^^^^^^^^ -If the conda-forge feedstock recipe is built from PyPI, then when a new release is published on PyPI, `regro-cf-autotick-bot` will open Pull Requests automatically on the conda-forge feedstock. -It is up to the conda-forge feedstock maintainers to verify that the package is building properly before merging the Pull Request to the main branch. +If the conda-forge feedstock recipe is built from PyPI, then when a new release is published on PyPI, `regro-cf-autotick-bot` will open Pull Requests automatically on the conda-forge feedstock. It is up to the conda-forge feedstock maintainers to verify that the package is building properly before merging the Pull Request to the main branch. Building sources for wide support with `manylinux` image ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -192,8 +191,7 @@ Building sources for wide support with `manylinux` image This section is for building source files that link to or provide links to C/C++ dependencies. It is not necessary to perform the following when building pure Python packages. -In order to do ensure best compatibility across architectures, we suggest building wheels using the `PyPA`'s `manylinux` -docker images (at time of writing, we endorse using `manylinux_2_24_x86_64`). +In order to do ensure best compatibility across architectures, we suggest building wheels using the `PyPA`'s `manylinux` docker images (at time of writing, we endorse using `manylinux_2_24_x86_64`). With `docker` installed and running, begin by pulling the image:: @@ -205,9 +203,8 @@ From the figanos source folder we can enter into the docker container, providing Finally, to build the wheel, we run it against the provided Python3.8 binary:: - $ /opt/python/cp38-cp38m/bin/python setup.py sdist bdist_wheel + $ /opt/python/cp38-cp38m/bin/python -m build --sdist --wheel -This will then place two files in `figanos/dist/` ("figanos-1.2.3-py3-none-any.whl" and "figanos-1.2.3.tar.gz"). -We can now leave our docker container (`$ exit`) and continue with uploading the files to PyPI:: +This will then place two files in `figanos/dist/` ("figanos-1.2.3-py3-none-any.whl" and "figanos-1.2.3.tar.gz"). We can now leave our docker container (`$ exit`) and continue with uploading the files to PyPI:: $ twine upload dist/* diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 0bfe6d38..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,26 +0,0 @@ -include AUTHORS.rst -include CONTRIBUTING.rst -include HISTORY.rst -include LICENSE -include README.rst -include .zenodo.json -include requirements_dev.txt -include requirements_docs.txt - -recursive-include figanos *.json *.mplstyle *.py *.txt -recursive-include docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif -recursive-include figanos/data *.json *.png *.txt *.yml - -recursive-exclude * __pycache__ -recursive-exclude * *.py[co] - -exclude .coveralls.yml -exclude .cruft.json -exclude .editorconfig -exclude .pre-commit-config.yaml -exclude .readthedocs.yml -exclude .yamllint.yaml -exclude Makefile -exclude environment.yml -exclude environment-docs.yml -exclude tox.ini diff --git a/Makefile b/Makefile index b77edbc1..5fb3945b 100644 --- a/Makefile +++ b/Makefile @@ -53,15 +53,18 @@ clean-test: ## remove test and coverage artifacts rm -fr .pytest_cache lint/flake8: ## check style with flake8 - flake8 figanos tests + ruff figanos tests + flake8 --config=setup.cfg figanos tests lint/black: ## check style with black black --check figanos tests + blackdoc --check figanos docs + isort --check figanos tests lint: lint/flake8 lint/black ## check style test: ## run tests quickly with the default Python - pytest + python -m pytest test-all: ## run tests on every Python version with tox tox @@ -87,13 +90,15 @@ endif servedocs: docs ## compile the docs watching for changes watchmedo shell-command -p '*.rst' -c '$(MAKE) -C docs html' -R -D . -release: dist ## package and upload a release - twine upload dist/* - dist: clean ## builds source and wheel package - python -m build --sdist - python -m build --wheel + python -m flit build ls -l dist +release: dist ## package and upload a release + python -m flit publish dist/* + install: clean ## install the package to the active Python's site-packages - python setup.py install + python -m flit install . + +dev: clean ## install the package to the active Python's site-packages + python -m flit install --symlink . diff --git a/README.rst b/README.rst index f18e7e1a..6061f81b 100644 --- a/README.rst +++ b/README.rst @@ -2,7 +2,6 @@ figanos ======= - .. image:: https://img.shields.io/pypi/v/figanos.svg :target: https://pypi.python.org/pypi/figanos :alt: PyPI @@ -21,10 +20,7 @@ figanos Figanos: Tool to create FIGures in the OurANOS style - -Pour nous partager vos codes à ajouter dans figanos, s.v.p créer un issue sur le repo github avec une description de la fonction et -le code de celle-ci. - +Pour nous partager vos codes à ajouter dans figanos, s.v.p créer un issue sur le repo github avec une description de la fonction et le code de celle-ci. * Free software: Apache Software License 2.0 * Documentation: https://figanos.readthedocs.io. diff --git a/docs/changes.rst b/docs/changes.rst new file mode 100644 index 00000000..d9e113ec --- /dev/null +++ b/docs/changes.rst @@ -0,0 +1 @@ +.. include:: ../CHANGES.rst diff --git a/docs/history.rst b/docs/history.rst deleted file mode 100644 index 25064996..00000000 --- a/docs/history.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../HISTORY.rst diff --git a/docs/index.rst b/docs/index.rst index 8c7a259b..db5c3dd3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -21,7 +21,7 @@ Need help? api contributing authors - history + changes .. toctree:: :maxdepth: 1 diff --git a/docs/installation.rst b/docs/installation.rst index dde5c32d..0994af05 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -10,7 +10,7 @@ To install figanos, run these commands in your terminal: .. code-block:: console $ mamba install -c conda-forge gdal - $ pip install figanos + $ python -m pip install figanos Development Installation (conda + pip) -------------------------------------- @@ -34,6 +34,6 @@ Finally, perform an `--editable` install of figanos: .. code-block:: console - $ pip install -e . + $ python -m pip install . .. _Github repo: https://github.com/Ouranosinc/figanos diff --git a/environment.yml b/environment-dev.yml similarity index 100% rename from environment.yml rename to environment-dev.yml diff --git a/figanos/__init__.py b/figanos/__init__.py index 6b4ed4f3..693ae7d6 100644 --- a/figanos/__init__.py +++ b/figanos/__init__.py @@ -1,4 +1,4 @@ -"""Top-level package for figanos.""" +"""Outils pour produire des graphiques informatifs sur les impacts des changements climatiques.""" __author__ = """Sarah-Claude Bourdeau-Goulet""" __email__ = "bourdeau-goulet.sarah-claude@ouranos.ca" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..9aea7781 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,221 @@ +[build-system] +requires = ["flit_core >=3.8,<4"] +build-backend = "flit_core.buildapi" + +[project] +name = "figanos" +authors = [ + {name = "Sarah-Claude Bourdeau-Goulet", email = "bourdeau-goulet.sarah-claude@ouranos.ca"} +] +maintainers = [] +readme = {file = "README.rst", content-type = "text/x-rst"} +requires-python = ">=3.8.0" +keywords = ["figanos"] +license = {file = "LICENSE"} +classifiers = [ + "Development Status :: 2 - Pre-Alpha", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: Implementation :: CPython" +] +dynamic = ["description", "version"] +dependencies = [ + "cartopy", + "cairosvg", + "geopandas", + "matplotlib", + "numpy", + "pandas", + "platformdirs", + "pyyaml", + "seaborn", + "scikit-image", + "xarray", + "xclim" +] + +[project.optional-dependencies] +dev = [ + # Dev tools and testing + "pip>=23.3", + "bump2version>=1.0.1", + "watchdog>=3.0.0", + "flake8>=6.1.0", + "flake8-rst-docstrings>=0.3.0", + "flit", + "tox>=4.5.1", + "coverage>=7.2.5", + "coveralls>=3.3.1", + "pytest>=7.3.1", + "pytest-cov>=4.0.0", + "black>=23.10.1", + "blackdoc>=0.3.9", + "isort>=5.12.0", + "pre-commit>=3.3.2" +] +docs = [ + # Documentation and examples + "xclim>=0.38", + "dask", + "h5py", + "netcdf4", + "pyyaml", + "zarr", + "geoviews", + "holoviews", + "ipykernel", + "ipython", + "jupyter_client", + "nbsphinx", + "pandoc", + "sphinx-click", + "sphinx-codeautolink", + "sphinx-copybutton", + "sphinx>=7.0", + "sphinx_book_theme", + "sphinxcontrib-napoleon" +] + +[project.scripts] +figanos = "figanos.cli:cli" + +[project.urls] +# "Homepage" = "https://figanos.readthedocs.io/" +# "Changelog" = "https://figanos.readthedocs.io/en/stable/history.html" +# "About Ouranos" = "https://www.ouranos.ca/en/" +"Source" = "https://github.com/Sarahclaude/figanos" +"Issue tracker" = "https://github.com/Sarahclaude/figanos/issues" + +[tool] + +[tool.black] +target-version = [ + "py38", + "py39", + "py310", + "py311" +] + +[tool.coverage.run] +relative_files = true +include = ["figanos/*"] +omit = ["tests/*.py"] + +[tool.flit.sdist] +include = [ + ".zenodo.json", + "AUTHORS.rst", + "CHANGES.rst", + "CONTRIBUTING.rst", + "LICENSE", + "README.rst", + "docs/**/*.rst", + "docs/**/*.jpg", + "docs/**/*.png", + "docs/**/*.gif", + "docs/Makefile", + "docs/conf.py", + "docs/make.bat", + "setup.cfg", + "tests/*.py", + "figanos/**/*.json", + "figanos/**/*.mplstyle", + "figanos/**/*.png", + "figanos/**/*.py", + "figanos/**/*.txt", + "figanos/**/*.yml" +] +exclude = [ + "**/*.py[co]", + "**/__pycache__", + ".coveralls.yml", + ".gitignore", + ".editorconfig", + ".pre-commit-config.yaml", + ".yamllint.yaml", + "Makefile", + "docs/modules.rst", + "docs/figanos*.rst", + "environment-dev.yml", + "environment-docs.yml", + "tox.ini" +] + +[tool.isort] +profile = "black" +py_version = 38 + +[tool.mypy] +python_version = 3.8 +show_error_codes = true +warn_return_any = true +warn_unused_configs = true + +[[tool.mypy.overrides]] +module = [] +ignore_missing_imports = true + +[tool.pytest.ini_options] +addopts = [ + "--verbose", + "--color=yes" +] +filterwarnings = ["ignore::UserWarning"] +testpaths = "tests" + +[tool.ruff] +src = [""] +line-length = 150 +target-version = "py38" +exclude = [ + ".eggs", + ".git", + "build", + "docs", + "tests" +] +ignore = [ + "D205", + "D400", + "D401" +] +select = [ + "C9", + "D", + "E", + "F", + "W" +] + +[tool.ruff.flake8-bandit] +check-typed-exception = true + +[tool.ruff.format] +line-ending = "auto" + +[tool.ruff.isort] +known-first-party = ["figanos"] +case-sensitive = true +detect-same-package = false +lines-after-imports = 1 +no-lines-before = ["future", "standard-library"] + +[tool.ruff.mccabe] +max-complexity = 15 + +[tool.ruff.per-file-ignores] +"figanos/**/__init__.py" = ["F401", "F403"] + +[tool.ruff.pycodestyle] +max-doc-length = 180 + +[tool.ruff.pydocstyle] +convention = "numpy" diff --git a/requirements_dev.txt b/requirements_dev.txt deleted file mode 100644 index bccebb04..00000000 --- a/requirements_dev.txt +++ /dev/null @@ -1,15 +0,0 @@ -pip==23.3 -bump2version==1.0.1 -wheel==0.40.0 -build==0.10.0 -flake8==6.0.0 -tox==4.5.1 -coverage==7.2.5 -coveralls==3.3.1 -sphinx==7.0.1 -twine==4.0.2 -pytest==7.3.1 -pytest-cov==4.0.0 -black==23.3.0 -isort==5.12.0 -pre-commit==3.3.2 diff --git a/requirements_docs.txt b/requirements_docs.txt deleted file mode 100644 index 7e222ffc..00000000 --- a/requirements_docs.txt +++ /dev/null @@ -1,20 +0,0 @@ -xclim>=0.38 -dask -h5py -netcdf4 -pyyaml -zarr -geoviews -holoviews -ipykernel -ipython -jupyter_client -nbsphinx -pandoc -sphinx -sphinx-autoapi -sphinx-click -sphinx-codeautolink -sphinx-copybutton -sphinx_book_theme -sphinxcontrib-napoleon diff --git a/setup.cfg b/setup.cfg index 9c112791..b11845cc 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,10 +3,6 @@ current_version = 0.2.0 commit = True tag = False -[bumpversion:file:setup.py] -search = version="{current_version}" -replace = version="{new_version}" - [bumpversion:file:figanos/__init__.py] search = __version__ = "{current_version}" replace = __version__ = "{new_version}" @@ -19,38 +15,28 @@ replace = __version__ = "{new_version}" search = "version": "{current_version}", replace = "version": "{new_version}", -[aliases] -test = pytest - -[tool:pytest] -collect_ignore = ['setup.py'] -addopts = - --verbose -filterwarnings = - ignore::UserWarning - [flake8] -exclude = +exclude = + .eggs, .git, - docs, build, - .eggs, - docs/conf.py, + docs, + tests max-line-length = 88 max-complexity = 12 -ignore = - C901 - E203 - E231 - E266 - E501 - F401 - F403 +ignore = + AZ100, + AZ200, + AZ300, + C, + D, + E, + F, W503 - W504 -per-file-ignores = +per-file-ignores = tests/*:E402 -rst-roles = +rst-roles = + doc, mod, py:attr, py:attribute, @@ -61,17 +47,4 @@ rst-roles = py:meth, py:mod, py:obj, - py:ref, - ref - -[coverage:run] -relative_files = True -omit = */tests/*.py - -[isort] -profile = black -py_version = 38 - -[pydocstyle] -convention = numpy -match = ((?!test_|conf).)*\.py + py:ref diff --git a/tox.ini b/tox.ini index bd282306..4c6cbb57 100644 --- a/tox.ini +++ b/tox.ini @@ -1,20 +1,24 @@ [tox] min_version = 4.0 envlist = - black + lint py{38,39,310,311} docs coveralls requires = - pip >= 21.0 + flit + pip >= 23.3.0 opts = --verbose -[testenv:black] +[testenv:lint] skip_install = True deps = - flake8 black + blackdoc + isort + flake8 + ruff commands = make lint allowlist_externals = From 108f68970b2fd56f0e50cd410b4dd4a644101f5a Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Mon, 20 Nov 2023 11:24:07 -0500 Subject: [PATCH 02/18] ignore complexity for matplotlib functions for now, no more pydocstyle hook (uses ruff) --- .pre-commit-config.yaml | 5 ----- pyproject.toml | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 91d85e85..17a5ba7b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -66,11 +66,6 @@ repos: - id: nbstripout files: '.ipynb' args: [ '--extra-keys=metadata.kernelspec' ] - - repo: https://github.com/pycqa/pydocstyle - rev: 6.3.0 - hooks: - - id: pydocstyle - args: [ '--config=setup.cfg' ] - repo: https://github.com/adrienverge/yamllint.git rev: v1.32.0 hooks: diff --git a/pyproject.toml b/pyproject.toml index 9aea7781..0946adbb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -213,6 +213,7 @@ max-complexity = 15 [tool.ruff.per-file-ignores] "figanos/**/__init__.py" = ["F401", "F403"] +"figanos/matplotlib/**/*.py" = ["C901"] [tool.ruff.pycodestyle] max-doc-length = 180 From 12bd010541c7fd65d4b07daaf5b3b62401b272f7 Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Mon, 20 Nov 2023 11:39:02 -0500 Subject: [PATCH 03/18] only run conda python3.11, relax coveralls version --- .github/workflows/main.yml | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 90dcccf4..dee20014 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -74,7 +74,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.9", "3.10", "3.11"] + python-version: ["3.11"] defaults: run: shell: bash -l {0} diff --git a/pyproject.toml b/pyproject.toml index 0946adbb..27097d38 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,7 @@ dev = [ "flake8-rst-docstrings>=0.3.0", "flit", "tox>=4.5.1", - "coverage>=7.2.5", + "coverage>=6.2,<7.0", "coveralls>=3.3.1", "pytest>=7.3.1", "pytest-cov>=4.0.0", From 2ae9a7a09936cdb564299849f575031180995fc5 Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:02:19 -0500 Subject: [PATCH 04/18] install gdal and pin coveralls --- .github/workflows/main.yml | 4 ++++ environment-dev.yml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dee20014..0e73423c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -58,6 +58,10 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + - name: Install GDAL + run: | + sudo apt-get update + sudo apt-get install -y libgdal-dev - name: Install tox run: pip install tox - name: Test with tox diff --git a/environment-dev.yml b/environment-dev.yml index 397f2d0d..93aa8076 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -28,8 +28,8 @@ dependencies: # Development - black - bump2version - - coverage - - coveralls + - coverage >=6.2,<7.0 + - coveralls >=3.3.1 - flake8 - isort - pip From 849344502fbb7a2dd328969b2db2fb340387aa64 Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:57:47 -0500 Subject: [PATCH 05/18] final touches --- .github/workflows/main.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0e73423c..4bd495ff 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -98,8 +98,7 @@ jobs: echo "micromamba $(micromamba --version)" - name: Compile catalogs and install xscen run: | - make translate - python -m pip install --no-deps --editable . + python -m pip install --no-deps . - name: Check versions run: | conda list @@ -112,7 +111,7 @@ jobs: python -m coveralls env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - COVERALLS_FLAG_NAME: run-Python__PYTHON_VERSION_-conda + COVERALLS_FLAG_NAME: run-Python${{ matrix.python-version }}-conda COVERALLS_PARALLEL: true COVERALLS_SERVICE_NAME: github From 4e7657fe9faed1765d7774e8e2d677511c497f1b Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Mon, 20 Nov 2023 13:05:22 -0500 Subject: [PATCH 06/18] update cookiecutter --- .cruft.json | 2 +- pyproject.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.cruft.json b/.cruft.json index d1889f0e..f2c22578 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/Ouranosinc/cookiecutter-pypackage", - "commit": "d4c119c04266c970bc4785a04916475bf95b5d0a", + "commit": "04e4e20634c3a90cd796b4e7acfe92ae817a2b75", "checkout": null, "context": { "cookiecutter": { diff --git a/pyproject.toml b/pyproject.toml index 27097d38..9df8c4af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,7 @@ dev = [ "flake8-rst-docstrings>=0.3.0", "flit", "tox>=4.5.1", - "coverage>=6.2,<7.0", + "coverage>=6.2.2,<7.0.0", "coveralls>=3.3.1", "pytest>=7.3.1", "pytest-cov>=4.0.0", @@ -79,7 +79,7 @@ docs = [ "sphinx-click", "sphinx-codeautolink", "sphinx-copybutton", - "sphinx>=7.0", + "sphinx", "sphinx_book_theme", "sphinxcontrib-napoleon" ] From a76bf92005900dcaddb8cb09db89cfc700197542 Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Mon, 20 Nov 2023 16:09:56 -0500 Subject: [PATCH 07/18] documentation dependency fixes and metadata adjustments --- environment-dev.yml | 4 ++-- pyproject.toml | 30 +++++++++++++++++------------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/environment-dev.yml b/environment-dev.yml index 93aa8076..209530ef 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -45,9 +45,9 @@ dependencies: - nbsphinx - notebook - pandoc - - sphinx + - sphinx >=6.2.0 - sphinx-autoapi - - sphinx-book-theme + - sphinx-book-theme >=1.0.0 - sphinx-click - sphinx-codeautolink - sphinx-copybutton diff --git a/pyproject.toml b/pyproject.toml index 9df8c4af..1e05f990 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,9 +5,15 @@ build-backend = "flit_core.buildapi" [project] name = "figanos" authors = [ - {name = "Sarah-Claude Bourdeau-Goulet", email = "bourdeau-goulet.sarah-claude@ouranos.ca"} + {name = "Sarah-Claude Bourdeau-Goulet", email = "bourdeau-goulet.sarah-claude@ouranos.ca"}, + {name = "Juliette Lavoie", email = "lavoie.juliette@ouranos.ca"}, + {name = "Alexis Beaupré-Laperrière", email = "Beaupre-Laperriere.Alexis@ouranos.ca"} +] +maintainers = [ + {name = "Sarah-Claude Bourdeau-Goulet", email = "bourdeau-goulet.sarah-claude@ouranos.ca"}, + {name = "Juliette Lavoie", email = "lavoie.juliette@ouranos.ca"}, + {name = "Trevor James Smith", email = "smith.trevorj@ouranos.ca"} ] -maintainers = [] readme = {file = "README.rst", content-type = "text/x-rst"} requires-python = ">=3.8.0" keywords = ["figanos"] @@ -39,7 +45,7 @@ dependencies = [ "seaborn", "scikit-image", "xarray", - "xclim" + "xclim>=0.38" ] [project.optional-dependencies] @@ -56,18 +62,16 @@ dev = [ "coveralls>=3.3.1", "pytest>=7.3.1", "pytest-cov>=4.0.0", - "black>=23.10.1", + "black>=23.11.0", "blackdoc>=0.3.9", "isort>=5.12.0", "pre-commit>=3.3.2" ] docs = [ # Documentation and examples - "xclim>=0.38", "dask", "h5py", "netcdf4", - "pyyaml", "zarr", "geoviews", "holoviews", @@ -79,8 +83,8 @@ docs = [ "sphinx-click", "sphinx-codeautolink", "sphinx-copybutton", - "sphinx", - "sphinx_book_theme", + "sphinx>=6.2.0", + "sphinx-book-theme>=1.0", "sphinxcontrib-napoleon" ] @@ -88,11 +92,11 @@ docs = [ figanos = "figanos.cli:cli" [project.urls] -# "Homepage" = "https://figanos.readthedocs.io/" -# "Changelog" = "https://figanos.readthedocs.io/en/stable/history.html" -# "About Ouranos" = "https://www.ouranos.ca/en/" -"Source" = "https://github.com/Sarahclaude/figanos" -"Issue tracker" = "https://github.com/Sarahclaude/figanos/issues" +"Homepage" = "https://figanos.readthedocs.io/" +"Changelog" = "https://figanos.readthedocs.io/en/stable/changes.html" +"Issue tracker" = "https://github.com/Ouranosinc/figanos/issues" +"Source" = "https://github.com/Ouranosinc/figanos" +"About Ouranos" = "https://www.ouranos.ca/en/" [tool] From b00f9f1f729ac420e0d1e83ef60b417debde69d6 Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Mon, 20 Nov 2023 16:39:43 -0500 Subject: [PATCH 08/18] python-pandoc not needed --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1e05f990..66a1b311 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,7 +79,6 @@ docs = [ "ipython", "jupyter_client", "nbsphinx", - "pandoc", "sphinx-click", "sphinx-codeautolink", "sphinx-copybutton", From 1e015fc3b0341d4ca5c18540d733a52144bf20da Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Mon, 20 Nov 2023 16:57:33 -0500 Subject: [PATCH 09/18] update CHANGES.rst --- CHANGES.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index af30371c..b210bd1a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -15,6 +15,7 @@ New features and enhancements * Logo plotting now supports both PNG and SVG file types (via `cairosvg`). (:pull:`119`). * Use small geojson in the notebook. (:pull:`124`). * Add the Colours of Figanos page (:issue:`126`, :pull:`127`). +* Figanos now adheres to PEPs 517/518/621 using the `flit` backend for building and packaging. (:pull:`135`). Bug fixes ^^^^^^^^^ @@ -30,10 +31,20 @@ Internal changes * Cleaned up the docstrings of a few functions, added some module-level strings, minor typo fixes. * Set `nbsphinx` in the documentation to always run (with th exception of one complex cell). * The `environment.yml` Python version is set to 3.11 to reduce the dependency solver complexity. +* The `cookiecutter` template has been updated to the latest commit via `cruft`. (:pull:`138`): + * `Manifest.in`, `requirements_dev.txt`, `requirements_docs.txt` and `setup.py` have been removed. + * `pyproject.toml` has been added, with most package configurations migrated into it. + * `HISTORY.rst` has been renamed to `CHANGES.rst`. + * `actions-version-updater.yml` has been added to automate the versioning of the package. + * `bump-version.yml` has been added to automate patch versioning of the package. + * `pre-commit` hooks have been updated to the latest versions; `check-toml` and `toml-sort` have been added to cleanup the `pyproject.toml` file. + * `ruff` has been added to the linting tools to replace most `flake8` and `pydocstyle` verifications. + * GitHub workflows now run proper pytest suites for `conda`-based testing. Bug fixes ^^^^^^^^^ * Fixed an issue with the `divergent` argument getting ignored (:pull:`132`). +* Some small documentation fixes for working uniquely in a `conda` environment. (:pull:`138`). 0.2.0 (2023-06-19) ------------------ From f4cea115113439d811c11409db0746db7ac50e3d Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Mon, 20 Nov 2023 17:09:45 -0500 Subject: [PATCH 10/18] remove setup.py --- setup.py | 69 -------------------------------------------------------- 1 file changed, 69 deletions(-) delete mode 100644 setup.py diff --git a/setup.py b/setup.py deleted file mode 100644 index 3866360a..00000000 --- a/setup.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python - -"""The setup script.""" - -from setuptools import find_packages, setup - -with open("README.rst") as readme_file: - readme = readme_file.read() - -requirements = [ - "cartopy", - "cairosvg", - "geopandas", - "matplotlib", - "numpy", - "pandas", - "platformdirs", - "pyyaml", - "seaborn", - "scikit-image", - "xarray", - "xclim", -] - -docs_requirements = [ - dependency for dependency in open("requirements_docs.txt").readlines() -] - -dev_requirements = [ - dependency for dependency in open("requirements_dev.txt").readlines() -] - -setup( - author="Sarah-Claude Bourdeau-Goulet", - author_email="bourdeau-goulet.sarah-claude@ouranos.ca", - python_requires=">=3.8", - classifiers=[ - "Development Status :: 2 - Pre-Alpha", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Natural Language :: English", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - ], - description="Outils pour produire des graphiques informatifs sur les impacts des changements climatiques.", - install_requires=requirements, - license="Apache Software License 2.0", - long_description=readme, - long_description_content_type="text/x-rst", - include_package_data=True, - keywords="figanos", - name="figanos", - packages=find_packages(include=["figanos", "figanos.*"]), - test_suite="tests", - extras_require={ - "docs": docs_requirements, - "dev": dev_requirements, - }, - project_urls={ - "Source": "https://github.com/Ouranosinc/figanos", - "Issue tracker": "https://github.com/Ouranosinc/figanos/issues", - "About Ouranos": "https://www.ouranos.ca/en/", - }, - version="0.2.0", - zip_safe=False, -) From 36cf69d6fc7689cfc9c12dcaaced97dba1d34918 Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:07:52 -0500 Subject: [PATCH 11/18] update hooks --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 17a5ba7b..017bf4ac 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,7 +30,7 @@ repos: hooks: - id: rst-inline-touching-normal - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.10.1 + rev: 23.11.0 hooks: - id: black exclude: ^docs/ @@ -43,7 +43,7 @@ repos: hooks: - id: flake8 additional_dependencies: [ 'flake8-alphabetize', 'flake8-rst-docstrings' ] - args: ['--config=setup.cfg'] + args: [ '--config=setup.cfg' ] - repo: https://github.com/PyCQA/isort rev: 5.12.0 hooks: From 946a10ba470af786caeeda31496513fcce493194 Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:18:36 -0500 Subject: [PATCH 12/18] mypy fixes --- figanos/_logo.py | 52 ++++++++++++++----------------------- figanos/matplotlib/utils.py | 22 ++++++++-------- pyproject.toml | 17 +++++++++++- 3 files changed, 47 insertions(+), 44 deletions(-) diff --git a/figanos/_logo.py b/figanos/_logo.py index 9c356774..9b8c9773 100644 --- a/figanos/_logo.py +++ b/figanos/_logo.py @@ -1,10 +1,11 @@ +from __future__ import annotations + import logging import shutil import urllib.parse import urllib.request import warnings from pathlib import Path -from typing import Optional, Union import platformdirs import yaml @@ -56,10 +57,10 @@ class Logos: def __init__(self) -> None: """Initialize the Logo class instance.""" - self._config = None - self._catalogue = None - self._default = None - self._logos = {} + self._config: Path = Path(platformdirs.user_config_dir("figanos")) / "logos" + self._catalogue: Path = self._config / LOGO_CONFIG_FILE + self._default: Path = self._config / "figanos_logo.png" + self._logos: dict[str, str] = {} self.reload_config() if not self._logos.get("default"): @@ -67,30 +68,18 @@ def __init__(self) -> None: self.set_logo(_figanos_logo) self.set_logo(_figanos_logo, name="default") - @property - def config(self) -> Path: - """The path to the logo configuration folder.""" - if self._config is None: - self._config = ( - Path(platformdirs.user_config_dir("figanos", ensure_exists=True)) - / "logos" - ) - return self._config - @property def catalogue(self) -> Path: """The path to the logo configuration file.""" - if self._catalogue is None: - self._catalogue = self.config / LOGO_CONFIG_FILE return self._catalogue @property - def default(self) -> str: + def default(self) -> Path: """The path to the default logo.""" return self._default @default.setter - def default(self, value: Union[str, Path]): + def default(self, value: Path): """Set a default logo.""" self._default = value @@ -103,7 +92,7 @@ def _setup(self) -> None: warnings.warn( f"No logo configuration file found. Creating one at {self.catalogue}." ) - self.config.mkdir(parents=True, exist_ok=True) + self._config.mkdir(parents=True, exist_ok=True) with open(self.catalogue, "w") as f: yaml.dump(dict(logos={}), f) @@ -115,13 +104,13 @@ def __repr__(self) -> str: """Return the default logo filepath.""" return f"{self._default}" - def __getitem__(self, args) -> Optional[str]: + def __getitem__(self, args) -> str | None: """Retrieve a logo filepath by its name. If it does not exist, it will be installed, with the filepath returned. """ try: - return self._logos[args] + return str(self._logos[args]) except (KeyError, TypeError): if isinstance(args, tuple): return self.set_logo(*args) @@ -141,9 +130,7 @@ def installed(self) -> list: """Retrieve a list of installed logos.""" return list(self._logos.keys()) - def set_logo( - self, path: Union[str, Path], name: Optional[str] = None - ) -> Optional[str]: + def set_logo(self, path: str | Path, name: str | None = None) -> str | None: """Copy an image at a given path to the config folder and map it to a given name in the catalogue.""" _logo_mapping = yaml.safe_load(self.catalogue.read_text())["logos"] @@ -151,7 +138,7 @@ def set_logo( if logo_path.exists() and logo_path.is_file(): if name is None: name = logo_path.stem.replace("-", "_") - install_logo_path = self.config / logo_path.name + install_logo_path = self._config / logo_path.name if not install_logo_path.exists(): shutil.copy(logo_path, install_logo_path) @@ -163,12 +150,13 @@ def set_logo( if name != "default": return self._logos[name] else: - return self._default + return str(self._default) elif not logo_path.exists(): warnings.warn(f"Logo file `{logo_path}` not found. Not setting logo.") elif not logo_path.is_file(): warnings.warn(f"Logo path `{logo_path}` is a folder. Not setting logo.") + return None def install_ouranos_logos(self, *, permitted: bool = False) -> None: """Fetch and install the Ouranos logo. @@ -184,11 +172,11 @@ def install_ouranos_logos(self, *, permitted: bool = False) -> None: for orientation in ["horizontal", "vertical"]: for colour in ["couleur", "blanc", "noir"]: file = f"logo-ouranos-{orientation}-{colour}.svg" - if not (self.config / file).exists(): + if not (self._config / file).exists(): logo_url = urllib.parse.urljoin(OURANOS_LOGOS_URL, file) try: - urllib.request.urlretrieve(logo_url, self.config / file) - self.set_logo(self.config / file) + urllib.request.urlretrieve(logo_url, self._config / file) + self.set_logo(self._config / file) except Exception as e: logging.error( f"Error downloading or setting Ouranos logo: {e}" @@ -196,12 +184,12 @@ def install_ouranos_logos(self, *, permitted: bool = False) -> None: if Path(self.default).stem == "figanos_logo": _default_ouranos_logo = ( - self.config / "logo-ouranos-horizontal-couleur.svg" + self._config / "logo-ouranos-horizontal-couleur.svg" ) warnings.warn(f"Setting default logo to {_default_ouranos_logo}.") self.set_logo(_default_ouranos_logo, name="default") self.reload_config() - print(f"Ouranos logos installed at: {self.config}.") + print(f"Ouranos logos installed at: {self._config}.") else: warnings.warn( "You have not indicated that you have permission to use the Ouranos logo. " diff --git a/figanos/matplotlib/utils.py b/figanos/matplotlib/utils.py index 34a83df7..1b5508a6 100644 --- a/figanos/matplotlib/utils.py +++ b/figanos/matplotlib/utils.py @@ -75,10 +75,10 @@ def get_localized_term(term, locale=None): return TERMS[term][locale] -def empty_dict(param): +def empty_dict(param) -> dict: """Return empty dict if input is None.""" if param is None: - param = {} + param = dict() return param @@ -175,7 +175,7 @@ def get_array_categ(array: xr.DataArray | xr.Dataset) -> str: def get_attributes( - string: str, xr_obj: xr.DataArray | xr.Dataset, locale: str = None + string: str, xr_obj: xr.DataArray | xr.Dataset, locale: str | None = None ) -> str: """Fetch attributes or dims corresponding to keys from Xarray objects. @@ -360,8 +360,8 @@ def sort_lines(array_dict: dict[str, Any]) -> dict[str, str]: def loc_mpl( - loc: str | tuple[float, float] | int, -) -> tuple[tuple[float, float], tuple[float, float], str, str]: + loc: str | tuple[int | float, int | float] | int, +) -> tuple[tuple[float, float], tuple[int | float, int | float], str, str]: """Find coordinates and alignment associated to loc string. Parameters @@ -574,11 +574,11 @@ def load_image( The scaled image. """ if pathlib.Path(im).suffix == ".png": - im = mpl.pyplot.imread(im) - original_height, original_width = im.shape[:2] + image = mpl.pyplot.imread(im) + original_height, original_width = image.shape[:2] if height is None and width is None: - return im + return image warnings.warn( "The scikit-image library is used to resize PNG images. This may affect logo image quality." @@ -596,7 +596,7 @@ def load_image( # Only height is provided, derive zoom factor for width based on aspect ratio width = (height / original_height) * original_width - return resize(im, (height, width, im.shape[2]), anti_aliasing=True) + return resize(image, (height, width, image.shape[2]), anti_aliasing=True) elif pathlib.Path(im).suffix == ".svg": cairo_kwargs = dict(url=im) @@ -779,7 +779,7 @@ def fill_between_label( def get_var_group( path_to_json: str | pathlib.Path, da: xr.DataArray | None = None, - unique_str: str = None, + unique_str: str | None = None, ) -> str: """Get IPCC variable group from DataArray or a string using a json file (figanos/data/ipcc_colors/variable_groups.json). @@ -1047,7 +1047,7 @@ def get_mpl_styles() -> dict[str, str]: folder = pathlib.Path(__file__).parent / "style/" paths = sorted(folder.glob("*.mplstyle")) names = [str(p).split("/")[-1].removesuffix(".mplstyle") for p in paths] - styles = {name: path for name, path in zip(names, paths)} + styles = {str(name): path for name, path in zip(names, paths)} return styles diff --git a/pyproject.toml b/pyproject.toml index 66a1b311..62000f17 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -163,7 +163,22 @@ warn_return_any = true warn_unused_configs = true [[tool.mypy.overrides]] -module = [] +module = [ + "cairosvg.*", + "cartopy.*", + "matplotlib.*", + "mpl_toolkits.*", + "geopandas.*", + "holoviews.*", + "numpy.*", + "pandas.*", + "scipy.*", + "seaborn.*", + "skimage.transform.*", + "xarray.*", + "xclim.*", + "yaml.*" +] ignore_missing_imports = true [tool.pytest.ini_options] From a5b89c67d38802d597980979d7bcd5135fe40504 Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:26:38 -0500 Subject: [PATCH 13/18] test coverage --- .github/workflows/main.yml | 10 +++++----- tox.ini | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4bd495ff..82a54d12 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -44,13 +44,13 @@ jobs: strategy: matrix: include: - - tox-env: "py38" + - tox-env: "py38-coveralls" python-version: "3.8" - - tox-env: "py39" + - tox-env: "py39-coveralls" python-version: "3.9" - - tox-env: "py310" + - tox-env: "py310-coveralls" python-version: "3.10" - - tox-env: "py311" + - tox-env: "py311-coveralls" python-version: "3.11" steps: - uses: actions/checkout@v4 @@ -105,7 +105,7 @@ jobs: python -m pip check || true - name: Test with pytest run: | - python -m pytest tests + python -m pytest --cov=figanos - name: Report coverage run: | python -m coveralls diff --git a/tox.ini b/tox.ini index 4c6cbb57..0a6a3374 100644 --- a/tox.ini +++ b/tox.ini @@ -37,6 +37,8 @@ setenv = PYTEST_ADDOPTS = "--color=yes" PYTHONPATH = {toxinidir} passenv = + CI + COVERALLS_* GITHUB_* extras = dev From 59534612b83bed2903eab1ca380a61e81e1ce9ee Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:35:17 -0500 Subject: [PATCH 14/18] only coverage for py311-conda --- .github/workflows/main.yml | 15 ++++++--------- tests/test_figanos.py | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 82a54d12..44b7fe03 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -44,13 +44,13 @@ jobs: strategy: matrix: include: - - tox-env: "py38-coveralls" + - tox-env: "py38" python-version: "3.8" - - tox-env: "py39-coveralls" + - tox-env: "py39" python-version: "3.9" - - tox-env: "py310-coveralls" + - tox-env: "py310" python-version: "3.10" - - tox-env: "py311-coveralls" + - tox-env: "py311" python-version: "3.11" steps: - uses: actions/checkout@v4 @@ -76,9 +76,6 @@ jobs: name: Test with Python${{ matrix.python-version }} (Anaconda) needs: lint runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.11"] defaults: run: shell: bash -l {0} @@ -91,7 +88,7 @@ jobs: environment-file: environment-dev.yml create-args: >- mamba - python=${{ matrix.python-version }} + python=3.11 - name: Conda and Mamba versions run: | mamba --version @@ -111,7 +108,7 @@ jobs: python -m coveralls env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - COVERALLS_FLAG_NAME: run-Python${{ matrix.python-version }}-conda + COVERALLS_FLAG_NAME: run-py311-conda COVERALLS_PARALLEL: true COVERALLS_SERVICE_NAME: github diff --git a/tests/test_figanos.py b/tests/test_figanos.py index 5c533b93..05ecf941 100644 --- a/tests/test_figanos.py +++ b/tests/test_figanos.py @@ -27,7 +27,7 @@ def test_content(response): def test_package_metadata(): """Test the package metadata.""" - project = pkgutil.get_loader("figanos").get_filename() + project = pkgutil.get_loader("figanos").get_filename() # noqa metadata = pathlib.Path(project).resolve().parent.joinpath("__init__.py") From 698d9289e08a7a04b450337bab528dea97981b75 Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:17:33 -0500 Subject: [PATCH 15/18] update to latest commit --- .cruft.json | 2 +- CONTRIBUTING.rst | 75 +++++++++++++++++++++++++++--------------------- pyproject.toml | 9 +++--- 3 files changed, 48 insertions(+), 38 deletions(-) diff --git a/.cruft.json b/.cruft.json index f2c22578..6a38c565 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/Ouranosinc/cookiecutter-pypackage", - "commit": "04e4e20634c3a90cd796b4e7acfe92ae817a2b75", + "commit": "31d78c6bc26d641561e498defe5d383b68d1afc8", "checkout": null, "context": { "cookiecutter": { diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index b59d002c..bd6b16dd 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -4,8 +4,7 @@ Contributing ============ -Contributions are welcome, and they are greatly appreciated! Every little bit -helps, and credit will always be given. +Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given. You can contribute in many ways: @@ -32,15 +31,12 @@ wanted" is open to whoever wants to implement it. Implement Features ~~~~~~~~~~~~~~~~~~ -Look through the GitHub issues for features. Anything tagged with "enhancement" -and "help wanted" is open to whoever wants to implement it. +Look through the GitHub issues for features. Anything tagged with "enhancement" and "help wanted" is open to whoever wants to implement it. Write Documentation ~~~~~~~~~~~~~~~~~~~ -figanos could always use more documentation, whether as part of the -official figanos docs, in docstrings, or even on the web in blog posts, -articles, and such. +``figanos`` could always use more documentation, whether as part of the official ``figanos`` docs, in docstrings, or even on the web in blog posts, articles, and such. Submit Feedback ~~~~~~~~~~~~~~~ @@ -57,14 +53,14 @@ If you are proposing a feature: Get Started! ------------------------------------------------- -Ready to contribute? Here's how to set up `figanos` for local development for developers outside Ouranos. +Ready to contribute? Here's how to set up ``figanos`` for local development for developers outside Ouranos. -#. Fork the `figanos` repo on GitHub. +#. Fork the ``figanos`` repo on GitHub. #. Clone your fork locally:: $ git clone git@github.com:your_name_here/figanos.git -#. Install your local copy into a development environment. Using `mamba`, you can create a new development environment with:: +#. Install your local copy into a development environment. Using ``mamba``, you can create a new development environment with:: $ mamba env create -f environment-dev.yml $ conda activate figanos @@ -85,16 +81,17 @@ Ready to contribute? Here's how to set up `figanos` for local development for de Now you can make your changes locally. -#. When you're done making changes, check that your changes pass black, flake8, isort, and the - tests, including testing other Python versions with tox:: +#. When you're done making changes, check that your changes pass ``black``, ``blackdoc``, ``flake8``, ``isort``, ``ruff``, and the tests, including testing other Python versions with tox:: $ black --check figanos tests + $ isort --check figanos tests + $ ruff figanos tests $ flake8 figanos tests - $ isort --check-only --diff figanos tests + $ blackdoc --check figanos docs $ python -m pytest $ tox - To get flake8, black, and tox, just pip install them into your virtualenv. + To get ``black``, ``blackdoc``, ``flake8``, ``isort``, ``ruff``, and tox, just pip install them into your virtualenv. #. Commit your changes and push your branch to GitHub:: @@ -117,9 +114,7 @@ Pull Request Guidelines Before you submit a pull request, check that it meets these guidelines: 1. The pull request should include tests. -2. If the pull request adds functionality, the docs should be updated. Put - your new functionality into a function with a docstring, and add the - feature to the list in README.rst. +2. If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in ``README.rst``. 3. The pull request should work for all major supported Python versions (3.8, 3.9, 3.10, and 3.11). Tips @@ -132,36 +127,43 @@ $ pytest tests.test_figanos Versioning/Tagging ------------------ -A reminder for the maintainers on how to deploy. -Make sure all your changes are committed (including an entry in HISTORY.rst). -Then run:: +A reminder for the maintainers on how to deploy. This section is only relevant for maintainers when they are producing a new point release for the package. + +In a new branch, make sure all your release information has been committed (in ``CHANGES.rst``). Then run:: $ bumpversion patch # possible: major / minor / patch $ git push $ git push --tags +This will trigger the CI to build the package and upload it to TestPyPI. In order to upload to PyPI, this can be done by publishing a new version on GitHub. This will trigger the workflow to build and upload the package to PyPI. + +.. note:: + + The ``bump-version.yml`` GitHub workflow will automatically bump the patch version when pull requests are pushed to the ``main`` branch on GitHub. It is not necessary to manually bump the version in your branch when merging (non-release) pull requests. + +.. warning:: + + It is important to be aware that any changes to files found within the ``figanos`` folder (with the exception of ``figanos/__init__.py``) will trigger the ``bump-version.yml`` workflow. Be careful not to commit changes to files in this folder when preparing a new release. + Packaging --------- -When a new version has been minted (features have been successfully integrated test coverage and stability is adequate), -maintainers should update the pip-installable package (wheel and source release) on PyPI as well as the binary on conda-forge. +When a new version has been minted (features have been successfully integrated test coverage and stability is adequate), maintainers should update the pip-installable package (wheel and source release) on PyPI as well as the binary on conda-forge. The simple approach ~~~~~~~~~~~~~~~~~~~ -The simplest approach to packaging for general support (pip wheels) requires the following packages installed: - * build - * setuptools - * twine - * wheel +The simplest approach to packaging for general support (pip wheels) requires that ``flit`` be installed:: + + $ python -m pip install flit From the command line on your Linux distribution, simply run the following from the clone's main dev branch:: # To build the packages (sources and wheel) - $ python -m build --sdist --wheel + $ python -m flit build # To upload to PyPI - $ twine upload dist/* + $ python -m flit publish dist/* The new version based off of the version checked out will now be available via `pip` (`$ pip install figanos`). @@ -171,13 +173,20 @@ Releasing on conda-forge Initial Release ^^^^^^^^^^^^^^^ -In order to prepare an initial release on conda-forge, we *strongly* suggest consulting the following links: +Before preparing an initial release on conda-forge, we *strongly* suggest consulting the following links: * https://conda-forge.org/docs/maintainer/adding_pkgs.html * https://github.com/conda-forge/staged-recipes +In order to create a new conda build recipe, to be used when proposing packages to the conda-forge repository, we strongly suggest using the ``grayskull`` tool:: + + $ python -m pip install grayskull + $ grayskull pypi figanos + +For more information on ``grayskull``, please see the following link: https://github.com/conda/grayskull + Before updating the main conda-forge recipe, we echo the conda-forge documentation and *strongly* suggest performing the following checks: * Ensure that dependencies and dependency versions correspond with those of the tagged version, with open or pinned versions for the `host` requirements. - * If possible, configure tests within the conda-forge build CI (e.g. `imports: figanos`, `commands: pytest figanos`) + * If possible, configure tests within the conda-forge build CI (e.g. `imports: figanos`, `commands: pytest figanos`). Subsequent releases ^^^^^^^^^^^^^^^^^^^ @@ -201,9 +210,9 @@ From the figanos source folder we can enter into the docker container, providing $ sudo docker run --rm -ti -v $(pwd):/figanos -w /figanos quay.io/pypa/manylinux_2_24_x86_64 bash -Finally, to build the wheel, we run it against the provided Python3.8 binary:: +Finally, to build the wheel, we run it against the provided Python3.9 binary:: - $ /opt/python/cp38-cp38m/bin/python -m build --sdist --wheel + $ /opt/python/cp39-cp39m/bin/python -m build --sdist --wheel This will then place two files in `figanos/dist/` ("figanos-1.2.3-py3-none-any.whl" and "figanos-1.2.3.tar.gz"). We can now leave our docker container (`$ exit`) and continue with uploading the files to PyPI:: diff --git a/pyproject.toml b/pyproject.toml index 62000f17..bebc6d68 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -120,10 +120,10 @@ include = [ "CONTRIBUTING.rst", "LICENSE", "README.rst", - "docs/**/*.rst", + "docs/**/*.gif", "docs/**/*.jpg", "docs/**/*.png", - "docs/**/*.gif", + "docs/**/*.rst", "docs/Makefile", "docs/conf.py", "docs/make.bat", @@ -140,15 +140,16 @@ exclude = [ "**/*.py[co]", "**/__pycache__", ".coveralls.yml", - ".gitignore", ".editorconfig", + ".gitignore", ".pre-commit-config.yaml", + ".readthedocs.yml", ".yamllint.yaml", "Makefile", "docs/modules.rst", "docs/figanos*.rst", - "environment-dev.yml", "environment-docs.yml", + "environment-dev.yml", "tox.ini" ] From 268ac652a7dd6a3c54b7a488ac0cfca280cf2c32 Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Wed, 22 Nov 2023 15:24:09 -0500 Subject: [PATCH 16/18] update to latest commit --- .cruft.json | 2 +- .flake8 | 30 ++++++++++++++++++ .github/workflows/bump-version.yml | 4 +-- .github/workflows/main.yml | 2 +- .github/workflows/tag-testpypi.yml | 1 + .pre-commit-config.yaml | 20 +++++------- CONTRIBUTING.rst | 29 +++++++++++------ environment-dev.yml | 2 +- pyproject.toml | 27 +++++++++++++++- setup.cfg | 50 ------------------------------ 10 files changed, 88 insertions(+), 79 deletions(-) create mode 100644 .flake8 delete mode 100644 setup.cfg diff --git a/.cruft.json b/.cruft.json index 6a38c565..6cbcad7c 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/Ouranosinc/cookiecutter-pypackage", - "commit": "31d78c6bc26d641561e498defe5d383b68d1afc8", + "commit": "e528361615f8bb4b886206b9cd49ffda76c45b45", "checkout": null, "context": { "cookiecutter": { diff --git a/.flake8 b/.flake8 new file mode 100644 index 00000000..1116575b --- /dev/null +++ b/.flake8 @@ -0,0 +1,30 @@ +[flake8] +exclude = + .eggs, + .git, + build, + docs, + tests +ignore = + AZ100, + AZ200, + AZ300, + C, + D, + E, + F, + W503 +per-file-ignores = +rst-roles = + doc, + mod, + py:attr, + py:attribute, + py:class, + py:const, + py:data, + py:func, + py:meth, + py:mod, + py:obj, + py:ref diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml index 6c511900..3376401d 100644 --- a/.github/workflows/bump-version.yml +++ b/.github/workflows/bump-version.yml @@ -46,9 +46,9 @@ jobs: run: echo "current_version=$(grep -E '__version__' figanos/__init__.py | cut -d ' ' -f3)" - name: Bump Patch Version run: | - pip install bump2version + pip install bump-my-version echo "Bumping version" - bump2version patch + bump-my-version bump patch echo "new_version=$(grep -E '__version__' figanos/__init__.py | cut -d ' ' -f3)" - name: Push Changes uses: ad-m/github-push-action@master diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 44b7fe03..bf00d77c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -102,7 +102,7 @@ jobs: python -m pip check || true - name: Test with pytest run: | - python -m pytest --cov=figanos + python -m pytest --cov figanos - name: Report coverage run: | python -m coveralls diff --git a/.github/workflows/tag-testpypi.yml b/.github/workflows/tag-testpypi.yml index d9b3a4d0..be281ae7 100644 --- a/.github/workflows/tag-testpypi.yml +++ b/.github/workflows/tag-testpypi.yml @@ -10,6 +10,7 @@ jobs: release: name: Create Release from tag runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') && endsWith(github.ref, '.0') steps: - name: Checkout code uses: actions/checkout@v4 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 017bf4ac..d8491590 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,6 @@ repos: rev: v4.5.0 hooks: - id: trailing-whitespace - exclude: setup.cfg - id: end-of-file-fixer - id: debug-statements - id: check-json @@ -34,6 +33,12 @@ repos: hooks: - id: black exclude: ^docs/ + - repo: https://github.com/PyCQA/isort + rev: 5.12.0 + hooks: + - id: isort + args: [ '--profile=black', '--filter-files', "--add_imports='from __future__ import annotations'" ] + exclude: ^docs/ - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.1.4 hooks: @@ -43,18 +48,7 @@ repos: hooks: - id: flake8 additional_dependencies: [ 'flake8-alphabetize', 'flake8-rst-docstrings' ] - args: [ '--config=setup.cfg' ] - - repo: https://github.com/PyCQA/isort - rev: 5.12.0 - hooks: - - id: isort - args: [ '--profile=black', '--filter-files', "--add_imports='from __future__ import annotations'" ] - exclude: ^docs/ - - repo: https://github.com/pycqa/pydocstyle - rev: 6.3.0 - hooks: - - id: pydocstyle - args: [ '--convention=numpy', '--match="(?!test_).*\.py"' ] + args: [ '--config=.flake8' ] - repo: https://github.com/keewis/blackdoc rev: v0.3.9 hooks: diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index bd6b16dd..e7e56240 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -25,8 +25,7 @@ If you are reporting a bug, please include: Fix Bugs ~~~~~~~~ -Look through the GitHub issues for bugs. Anything tagged with "bug" and "help -wanted" is open to whoever wants to implement it. +Look through the GitHub issues for bugs. Anything tagged with "bug" and "help wanted" is open to whoever wants to implement it. Implement Features ~~~~~~~~~~~~~~~~~~ @@ -113,9 +112,12 @@ Pull Request Guidelines Before you submit a pull request, check that it meets these guidelines: -1. The pull request should include tests. -2. If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in ``README.rst``. -3. The pull request should work for all major supported Python versions (3.8, 3.9, 3.10, and 3.11). +#. The pull request should include tests. + +#. If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in ``README.rst``. + +#. The pull request should work for Python 3.8, 3.9, 3.10, and 3.11. Check that the tests pass for all supported Python versions. + Tips ---- @@ -129,13 +131,20 @@ Versioning/Tagging A reminder for the maintainers on how to deploy. This section is only relevant for maintainers when they are producing a new point release for the package. -In a new branch, make sure all your release information has been committed (in ``CHANGES.rst``). Then run:: +#. Create a new branch from `main` (e.g. `release-0.2.0`). +#. Update the `CHANGES.rst` file to change the `Unreleased` section to the current date. +#. Create a pull request from your branch to `main`. +#. Once the pull request is merged, create a new release on GitHub. On the main branch, run: + + .. code-block:: shell + + $ bump-my-version bump minor # In most cases, we will be releasing a minor version + $ git push + $ git push --tags -$ bumpversion patch # possible: major / minor / patch -$ git push -$ git push --tags + This will trigger the CI to build the package and upload it to TestPyPI. In order to upload to PyPI, this can be done by publishing a new version on GitHub. This will then trigger the workflow to build and upload the package to PyPI. -This will trigger the CI to build the package and upload it to TestPyPI. In order to upload to PyPI, this can be done by publishing a new version on GitHub. This will trigger the workflow to build and upload the package to PyPI. +#. Once the release is published, it will go into a `staging` mode on Github Actions. Once the tests pass, admins can approve the release (an e-mail will be sent) and it will be published on PyPI. .. note:: diff --git a/environment-dev.yml b/environment-dev.yml index 209530ef..c50765ba 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -27,7 +27,7 @@ dependencies: - holoviews # Development - black - - bump2version + - bump-my-version >=0.12.0 - coverage >=6.2,<7.0 - coveralls >=3.3.1 - flake8 diff --git a/pyproject.toml b/pyproject.toml index bebc6d68..4e980cff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,7 @@ dependencies = [ dev = [ # Dev tools and testing "pip>=23.3", - "bump2version>=1.0.1", + "bump-my-version>=0.12.0", "watchdog>=3.0.0", "flake8>=6.1.0", "flake8-rst-docstrings>=0.3.0", @@ -107,6 +107,30 @@ target-version = [ "py311" ] +[tool.bumpversion] +current_version = "0.2.0" +commit = true +tag = true +tag_name = "{new_version}" +allow_dirty = false +serialize = ["{major}.{minor}.{patch}"] +parse = "(?P\\d+)\\.(?P\\d+)\\.(?P\\d+)" + +[[tool.bumpversion.files]] +filename = "figanos/__init__.py" +search = "__version__ = \"{current_version}\"" +replace = "__version__ = \"{new_version}\"" + +[[tool.bumpversion.files]] +filename = "tests/test_figanos.py" +search = "__version__ = \"{current_version}\"" +replace = "__version__ = \"{new_version}\"" + +[[tool.bumpversion.files]] +filename = ".cruft.json" +search = "\"version\": \"{current_version}\"" +replace = "\"version\": \"{new_version}\"" + [tool.coverage.run] relative_files = true include = ["figanos/*"] @@ -141,6 +165,7 @@ exclude = [ "**/__pycache__", ".coveralls.yml", ".editorconfig", + ".flake8", ".gitignore", ".pre-commit-config.yaml", ".readthedocs.yml", diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index b11845cc..00000000 --- a/setup.cfg +++ /dev/null @@ -1,50 +0,0 @@ -[bumpversion] -current_version = 0.2.0 -commit = True -tag = False - -[bumpversion:file:figanos/__init__.py] -search = __version__ = "{current_version}" -replace = __version__ = "{new_version}" - -[bumpversion:file:tests/test_figanos.py] -search = __version__ = "{current_version}" -replace = __version__ = "{new_version}" - -[bumpversion:file:.cruft.json] -search = "version": "{current_version}", -replace = "version": "{new_version}", - -[flake8] -exclude = - .eggs, - .git, - build, - docs, - tests -max-line-length = 88 -max-complexity = 12 -ignore = - AZ100, - AZ200, - AZ300, - C, - D, - E, - F, - W503 -per-file-ignores = - tests/*:E402 -rst-roles = - doc, - mod, - py:attr, - py:attribute, - py:class, - py:const, - py:data, - py:func, - py:meth, - py:mod, - py:obj, - py:ref From b2f12d3db800af2bc979db5e4a44c56af80850e4 Mon Sep 17 00:00:00 2001 From: Zeitsperre <10819524+Zeitsperre@users.noreply.github.com> Date: Wed, 22 Nov 2023 15:26:01 -0500 Subject: [PATCH 17/18] use .flake8 config --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5fb3945b..ab04253e 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ clean-test: ## remove test and coverage artifacts lint/flake8: ## check style with flake8 ruff figanos tests - flake8 --config=setup.cfg figanos tests + flake8 --config=.flake8 figanos tests lint/black: ## check style with black black --check figanos tests From 64119f1bd721c3a35cfe4d62b7dedcf42a43a96a Mon Sep 17 00:00:00 2001 From: Trevor James Smith <10819524+Zeitsperre@users.noreply.github.com> Date: Thu, 23 Nov 2023 15:01:23 -0500 Subject: [PATCH 18/18] update cookiecutter and fix packaging config --- .cruft.json | 2 +- CONTRIBUTING.rst | 2 +- Makefile | 4 ++-- docs/installation.rst | 8 +++++--- environment-dev.yml | 1 - pyproject.toml | 36 ++++++++++++++---------------------- 6 files changed, 23 insertions(+), 30 deletions(-) diff --git a/.cruft.json b/.cruft.json index 6cbcad7c..0f52c9b6 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/Ouranosinc/cookiecutter-pypackage", - "commit": "e528361615f8bb4b886206b9cd49ffda76c45b45", + "commit": "de751c55cd9a5df586e3d961535292cfb73e0397", "checkout": null, "context": { "cookiecutter": { diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index e7e56240..eecc4b12 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -63,7 +63,7 @@ Ready to contribute? Here's how to set up ``figanos`` for local development for $ mamba env create -f environment-dev.yml $ conda activate figanos - $ flit install --symlink . + $ flit install --symlink #. To ensure a consistent style, please install the pre-commit hooks to your repo:: diff --git a/Makefile b/Makefile index ab04253e..756536b3 100644 --- a/Makefile +++ b/Makefile @@ -98,7 +98,7 @@ release: dist ## package and upload a release python -m flit publish dist/* install: clean ## install the package to the active Python's site-packages - python -m flit install . + python -m flit install dev: clean ## install the package to the active Python's site-packages - python -m flit install --symlink . + python -m flit install --symlink diff --git a/docs/installation.rst b/docs/installation.rst index 0994af05..8de7b42e 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -28,12 +28,14 @@ Then you can create the environment and install the package: .. code-block:: console $ cd figanos - $ conda env create -f environment.yml + $ conda env create -f environment-dev.yml -Finally, perform an `--editable` install of figanos: +Finally, perform an `--symlink` install of figanos: .. code-block:: console - $ python -m pip install . + $ flit install --symlink + # Or + $ make dev .. _Github repo: https://github.com/Ouranosinc/figanos diff --git a/environment-dev.yml b/environment-dev.yml index c50765ba..220a2e6e 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -48,7 +48,6 @@ dependencies: - sphinx >=6.2.0 - sphinx-autoapi - sphinx-book-theme >=1.0.0 - - sphinx-click - sphinx-codeautolink - sphinx-copybutton - sphinxcontrib-napoleon diff --git a/pyproject.toml b/pyproject.toml index 4e980cff..405fdb69 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,7 +79,6 @@ docs = [ "ipython", "jupyter_client", "nbsphinx", - "sphinx-click", "sphinx-codeautolink", "sphinx-copybutton", "sphinx>=6.2.0", @@ -87,9 +86,6 @@ docs = [ "sphinxcontrib-napoleon" ] -[project.scripts] -figanos = "figanos.cli:cli" - [project.urls] "Homepage" = "https://figanos.readthedocs.io/" "Changelog" = "https://figanos.readthedocs.io/en/stable/changes.html" @@ -143,26 +139,26 @@ include = [ "CHANGES.rst", "CONTRIBUTING.rst", "LICENSE", + "Makefile", "README.rst", - "docs/**/*.gif", - "docs/**/*.jpg", - "docs/**/*.png", - "docs/**/*.rst", + "docs/*.rst", "docs/Makefile", + "docs/_static/_images/*.gif", + "docs/_static/_images/*.jpg", + "docs/_static/_images/*.png", + "docs/_static/_images/*.rst", "docs/conf.py", "docs/make.bat", - "setup.cfg", + "docs/notebooks/.ipynb", + "environment-docs.yml", + "environment-dev.yml", "tests/*.py", - "figanos/**/*.json", - "figanos/**/*.mplstyle", - "figanos/**/*.png", - "figanos/**/*.py", - "figanos/**/*.txt", - "figanos/**/*.yml" + "figanos", + "tox.ini" ] exclude = [ - "**/*.py[co]", - "**/__pycache__", + "*.py[co]", + "__pycache__", ".coveralls.yml", ".editorconfig", ".flake8", @@ -170,12 +166,8 @@ exclude = [ ".pre-commit-config.yaml", ".readthedocs.yml", ".yamllint.yaml", - "Makefile", "docs/modules.rst", - "docs/figanos*.rst", - "environment-docs.yml", - "environment-dev.yml", - "tox.ini" + "docs/figanos*.rst" ] [tool.isort]