diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..3ea6289 --- /dev/null +++ b/.flake8 @@ -0,0 +1,10 @@ +[flake8] +exclude = docs, build, .nox +ignore = + E203 + E501 + W503 + W605 +max-line-length = 88 +max-complexity = 18 +select = B,C,E,F,W,T4,B9 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 1f31439..51350a1 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -2,6 +2,10 @@ name: Documentation on: [push, pull_request] +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + jobs: build: @@ -13,9 +17,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: conda-incubator/setup-miniconda@v2 + - uses: conda-incubator/setup-miniconda@v3 with: miniforge-version: latest python-version: 3.11 diff --git a/.github/workflows/format.yml b/.github/workflows/lint.yml similarity index 68% rename from .github/workflows/format.yml rename to .github/workflows/lint.yml index 91bab0b..d709394 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/lint.yml @@ -1,7 +1,11 @@ -name: Format +name: Lint on: [push, pull_request] +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + jobs: format: @@ -12,9 +16,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: conda-incubator/setup-miniconda@v2 + - uses: conda-incubator/setup-miniconda@v3 with: miniforge-version: latest python-version: 3.11 @@ -24,4 +28,4 @@ jobs: run: pip install nox - name: Format code - run: nox -s format -- --check --verbose --diff + run: nox -s lint diff --git a/.github/workflows/test-notebooks.yml b/.github/workflows/test-notebooks.yml new file mode 100644 index 0000000..d070385 --- /dev/null +++ b/.github/workflows/test-notebooks.yml @@ -0,0 +1,44 @@ +name: Notebooks + +on: [push, pull_request] + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + test-notebooks: + name: Check notebooks + if: + github.event_name == 'push' || github.event.pull_request.head.repo.full_name != + github.repository + + runs-on: ${{ matrix.os }} + + defaults: + run: + shell: bash -l {0} + + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ["3.12"] + + steps: + - uses: actions/checkout@v4 + + - uses: conda-incubator/setup-miniconda@v3 + with: + python-version: ${{ matrix.python-version }} + miniforge-variant: Miniforge3 + miniforge-version: latest + auto-update-conda: true + + - name: Install nox + run: pip install nox + + - name: Test Jupyter notebooks + env: + MPLBACKEND: "Agg" + run: | + nox --verbose -s test-notebooks --force-pythons="${{ matrix.python-version }}" diff --git a/.github/workflows/build-test-ci.yml b/.github/workflows/test.yml similarity index 76% rename from .github/workflows/build-test-ci.yml rename to .github/workflows/test.yml index 352d8d1..b57ccbb 100644 --- a/.github/workflows/build-test-ci.yml +++ b/.github/workflows/test.yml @@ -1,11 +1,14 @@ -name: Build/Test CI +name: Test on: [push, pull_request] -jobs: +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true - build-and-test: +jobs: + test: if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository @@ -28,18 +31,10 @@ jobs: with: miniforge-variant: Mambaforge miniforge-version: latest - environment-file: environment.yml - activate-environment: geotiff python-version: ${{ matrix.python-version }} - auto-activate-base: false - - - name: Show conda installation info - run: | - conda info - conda list - - name: Install package - run: pip install -e . + - name: Install nox + run: pip install nox - name: Test run: | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..761d87b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,98 @@ +repos: +- repo: local + hooks: + - id: unnecessary_doctest_directives + name: Check for redundant doctest directives + description: + "Check for inline doctest directives that are specified globally through pyproject.toml" + types: [python] + entry: > + (?x)( + \+IGNORE_EXCEPTION_DETAIL| + \+NORMALIZE_WHITESPACE + ) + language: pygrep + +- repo: https://github.com/psf/black + rev: 24.4.0 + hooks: + - id: black + name: black + description: "Black: The uncompromising Python code formatter" + entry: black + language: python + language_version: python3 + minimum_pre_commit_version: 2.9.2 + require_serial: true + types_or: [python, pyi] + - id: black-jupyter + name: black-jupyter + description: + "Black: The uncompromising Python code formatter (with Jupyter Notebook support)" + entry: black + language: python + minimum_pre_commit_version: 2.9.2 + require_serial: true + types_or: [python, pyi, jupyter] + additional_dependencies: [".[jupyter]"] + +- repo: https://github.com/keewis/blackdoc + rev: v0.3.9 + hooks: + - id: blackdoc + description: "Black for doctests" + additional_dependencies: ["black==24.4.0"] + - id: blackdoc-autoupdate-black + +- repo: https://github.com/pycqa/flake8 + rev: 7.0.0 + hooks: + - id: flake8 + additional_dependencies: + # - flake8-bugbear!=24.4.21 + # - flake8-comprehensions + - flake8-simplify + +- repo: https://github.com/nbQA-dev/nbQA + rev: 1.8.5 + hooks: + - id: nbqa-pyupgrade + args: ["--py310-plus"] + # - id: nbqa-isort + - id: nbqa-flake8 + args: ["--extend-ignore=E402"] + +- repo: https://github.com/kynan/nbstripout + rev: 0.7.1 + hooks: + - id: nbstripout + description: Strip output from jupyter notebooks + args: [--drop-empty-cells] + +- repo: https://github.com/asottile/pyupgrade + rev: v3.15.2 + hooks: + - id: pyupgrade + args: [--py310-plus] + +- repo: https://github.com/PyCQA/isort + rev: 5.13.2 + hooks: + - id: isort + name: isort (python) + # args: [--force-single-line-imports] + types: [python] + +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: check-builtin-literals + - id: check-added-large-files + - id: check-case-conflict + - id: check-toml + - id: check-yaml + - id: debug-statements + - id: end-of-file-fixer + - id: forbid-new-submodules + - id: mixed-line-ending + - id: trailing-whitespace diff --git a/README.md b/README.md index 2a746bd..b3ff815 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8327418.svg)](https://doi.org/10.5281/zenodo.8327418) [![PyPI](https://img.shields.io/pypi/v/bmi-geotiff)](https://pypi.org/project/bmi-geotiff) [![Conda Version](https://img.shields.io/conda/vn/conda-forge/bmi-geotiff.svg)](https://anaconda.org/conda-forge/bmi-geotiff) -[![Build/Test CI](https://github.com/csdms/bmi-geotiff/actions/workflows/build-test-ci.yml/badge.svg)](https://github.com/csdms/bmi-geotiff/actions/workflows/build-test-ci.yml) +[![Test](https://github.com/csdms/bmi-geotiff/actions/workflows/test.yml/badge.svg)](https://github.com/csdms/bmi-geotiff/actions/workflows/test.yml) [![Documentation Status](https://readthedocs.org/projects/bmi-geotiff/badge/?version=latest)](https://bmi-geotiff.readthedocs.io/en/latest/?badge=latest) # bmi-geotiff diff --git a/docs/source/conf.py b/docs/source/conf.py index 32f9434..490b498 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -28,7 +28,7 @@ version = pkg_resources.get_distribution("bmi_geotiff").version release = version this_year = datetime.date.today().year -copyright = "{}, {}".format(this_year, author) +copyright = f"{this_year}, {author}" # -- General configuration --------------------------------------------------- diff --git a/examples/bmi-geotiff.ipynb b/examples/bmi-geotiff.ipynb index 8f8ccae..a19a6ea 100644 --- a/examples/bmi-geotiff.ipynb +++ b/examples/bmi-geotiff.ipynb @@ -140,7 +140,7 @@ "metadata": {}, "outputs": [], "source": [ - "ls" + "!ls" ] }, { @@ -150,7 +150,7 @@ "metadata": {}, "outputs": [], "source": [ - "cat config.yaml" + "!cat config.yaml" ] }, { diff --git a/noxfile.py b/noxfile.py index 45dbd03..3aeeb61 100644 --- a/noxfile.py +++ b/noxfile.py @@ -49,19 +49,28 @@ def test_bmi(session: nox.Session) -> None: ) -@nox.session -def format(session: nox.Session) -> None: - """Clean lint and assert style.""" - session.install(".[dev]") +@nox.session(name="test-notebooks", python=PYTHON_VERSIONS[-1]) +def test_notebooks(session: nox.Session) -> None: + """Test the notebooks.""" + session.install(".[testing,examples]") + session.install("nbmake") - if session.posargs: - black_args = session.posargs - else: - black_args = [] + args = [ + "examples", + "--nbmake", + "--nbmake-kernel=python3", + "--nbmake-timeout=3000", + "-vvv", + ] + session.posargs - session.run("black", *black_args, *PATHS) - session.run("isort", *PATHS) - session.run("flake8", *PATHS) + session.run("pytest", *args) + + +@nox.session +def lint(session: nox.Session) -> None: + """Clean lint and assert style.""" + session.install("pre-commit") + session.run("pre-commit", "run", "--all-files") @nox.session(name="prepare-docs") diff --git a/pyproject.toml b/pyproject.toml index 0bef313..b00a349 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,9 +46,6 @@ Changelog = "https://github.com/csdms/bmi-geotiff/blob/main/CHANGES.md" [project.optional-dependencies] dev = [ - "black", - "flake8", - "isort", "nox", ] build = [ @@ -95,6 +92,7 @@ addopts = """ --durations 16 --doctest-modules -vvv + --ignore-glob=examples/*.py """ doctest_optionflags = [ "NORMALIZE_WHITESPACE", diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index f3d7d5c..0000000 --- a/setup.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[flake8] -exclude = docs -ignore = - E203 - E501 - W503 -max-line-length = 88