From e067b6b6e0b091f2c0f31e54eedb778e40b9d65f Mon Sep 17 00:00:00 2001 From: Frederik Hennig <frederik.hennig@fau.de> Date: Tue, 14 Jan 2025 13:49:46 +0100 Subject: [PATCH] Introduce Nox for Test Automation --- .gitlab-ci.yml | 47 ++++++++------------------ CONTRIBUTING.md | 36 ++++++++++++++++---- noxfile.py | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 13 +++++--- 4 files changed, 140 insertions(+), 44 deletions(-) create mode 100644 noxfile.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a89284a..b89453e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,44 +4,31 @@ stages: - "Documentation" - deploy +.nox-base: + image: i10git.cs.fau.de:5005/pycodegen/pycodegen/nox:alpine + tags: + - docker + linter: + extends: .nox-base stage: "Code Quality" needs: [] - except: - variables: - - $ENABLE_NIGHTLY_BUILDS - image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full script: - - flake8 src/pystencilssfg - tags: - - docker + - nox --session lint typechecker: + extends: .nox-base stage: "Code Quality" needs: [] - except: - variables: - - $ENABLE_NIGHTLY_BUILDS - image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full script: - - pip install mypy - - mypy src/pystencilssfg - tags: - - docker + - nox --session typecheck testsuite: + extends: .nox-base stage: "Tests" - image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full needs: [] - tags: - - docker - before_script: - - pip install "git+https://i10git.cs.fau.de/pycodegen/pystencils.git@v2.0-dev" - - pip install -e .[tests] script: - - pytest -v --cov=src/pystencilssfg --cov-report=term --cov-config=pyproject.toml - - coverage html - - coverage xml + - nox --session testsuite coverage: '/TOTAL.*\s+(\d+%)$/' artifacts: when: always @@ -54,23 +41,17 @@ testsuite: path: coverage.xml build-documentation: + extends: .nox-base stage: "Documentation" - image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full needs: [] - before_script: - - pip install "git+https://i10git.cs.fau.de/pycodegen/pystencils.git@v2.0-dev" - - pip install -e .[docs] script: - - cd docs - - make html - tags: - - docker + - nox --session docs artifacts: paths: - docs/build/html pages: - image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full + image: alpine:latest stage: deploy script: - ls -l diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dbcaaf1..e89a6e5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,6 +13,19 @@ As such, any submission of contributions via merge requests is considered as agr ## Developing `pystencils-sfg` +### Prequesites + +To develop pystencils-sfg, you will need at least these packages: + + - Python 3.10 + - Git + - A C++ compiler supporting at least C++20 (gcc >= 10, or clang >= 10) + - GNU Make + - CMake + - Nox + +Before continuing, make sure that the above packages are installed on your machine. + ### Fork and Clone To work within the `pystencils-sfg` source tree, first create a *fork* of this repository @@ -29,28 +42,29 @@ source .venv/bin/activate pip install -e . ``` +If you have [nox](https://nox.thea.codes/en/stable/) installed, you can also set up your virtual environment +by running `nox --session dev_env`. + ### Code Style and Type Checking To contribute, please adhere to the Python code style set by [PEP 8](https://peps.python.org/pep-0008/). -For consistency, format all your source files using the [black](https://pypi.org/project/black/) formatter. -Use flake8 to check your code style: +For consistency, format all your source files using the [black](https://pypi.org/project/black/) formatter, +and check them regularily using the `flake8` linter through Nox: ```shell -flake8 src/pystencilssfg +nox --session lint ``` Further, `pystencils-sfg` is being fully type-checked using [MyPy](https://www.mypy-lang.org/). All submitted code should contain type annotations ([PEP 484](https://peps.python.org/pep-0484/)) and must be correctly statically typed. -Before each commit, check your types by calling +Regularily check your code for type errors using ```shell -mypy src/pystencilssfg +nox --session typecheck ``` Both `flake8` and `mypy` are also run in the integration pipeline. -You can automate the code quality checks by running them via a git pre-commit hook. -Such a hook can be installed using the [`install_git_hooks.sh`](install_git_hooks.sh) script located at the project root. ### Test Your Code @@ -65,3 +79,11 @@ In [tests/generator_scripts](tests/generator_scripts), a framework is provided t for successful execution, correctness, and compilability of their output. Read the documentation within [test_generator_scripts.py](tests/generator_scripts/test_generator_scripts.py) for more information. + +Run the test suite by calling it through Nox: + +```shell +nox --session testsuite +``` + +This will also collect coverage information and produce a coverage report as a HTML site placed in the `htmlcov` folder. diff --git a/noxfile.py b/noxfile.py new file mode 100644 index 0000000..915ab84 --- /dev/null +++ b/noxfile.py @@ -0,0 +1,88 @@ +from __future__ import annotations + +from typing import Sequence +import nox + +nox.options.sessions = ["lint", "typecheck", "testsuite"] + + +def add_pystencils_git(session: nox.Session): + """Clone the pystencils 2.0 development branch and install it in the current session""" + cache_dir = session.cache_dir + + pystencils_dir = cache_dir / "pystencils" + if not pystencils_dir.exists(): + session.run_install( + "git", + "clone", + "--branch", + "v2.0-dev", + "--single-branch", + "https://i10git.cs.fau.de/pycodegen/pystencils.git", + pystencils_dir, + external=True, + ) + session.install("-e", str(pystencils_dir)) + + +def editable_install(session: nox.Session, opts: Sequence[str] = ()): + add_pystencils_git(session) + if opts: + opts_str = "[" + ",".join(opts) + "]" + else: + opts_str = "" + session.install("-e", f".{opts_str}") + + +@nox.session(python="3.10", tags=["qa", "code-quality"]) +def lint(session: nox.Session): + """Lint code using flake8""" + + session.install("flake8") + session.run("flake8", "src/pystencilssfg") + + +@nox.session(python="3.10", tags=["qa", "code-quality"]) +def typecheck(session: nox.Session): + """Run MyPy for static type checking""" + editable_install(session) + session.install("mypy") + session.run("mypy", "src/pystencilssfg") + + +@nox.session(python=["3.10"], tags=["tests"]) +def testsuite(session: nox.Session): + """Run the testsuite and measure coverage.""" + editable_install(session, ["testsuite"]) + session.run( + "pytest", + "-v", + "--cov=src/pystencilssfg", + "--cov-report=term", + "--cov-config=pyproject.toml", + ) + session.run("coverage", "html") + session.run("coverage", "xml") + + +@nox.session(python=["3.10"], tags=["docs"]) +def docs(session: nox.Session): + """Build the documentation pages""" + editable_install(session, ["docs"]) + session.chdir("docs") + session.run("make", "html", external=True) + + +@nox.session() +def dev_env(session: nox.Session): + """Set up the development environment at .venv""" + + session.install("virtualenv") + session.run("virtualenv", ".venv", "--prompt", "pystencils-sfg") + session.run( + ".venv/bin/pip", + "install", + "git+https://i10git.cs.fau.de/pycodegen/pystencils.git@v2.0-dev", + external=True, + ) + session.run(".venv/bin/pip", "install", "-e", ".[dev]", external=True) diff --git a/pyproject.toml b/pyproject.toml index b787da5..da36a11 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,10 +23,15 @@ requires = [ build-backend = "setuptools.build_meta" [project.optional-dependencies] -tests = [ - "flake8>=6.1.0", - "mypy>=1.7.0", +dev = [ + "flake8", + "mypy", "black", + "clang-format", +] +testsuite = [ + "pytest", + "pytest-cov", "pyyaml", "requests", "fasteners", @@ -60,7 +65,7 @@ omit = [ [tool.coverage.report] exclude_also = [ - "\\.\\.\\.", + "\\.\\.\\.\n", "if TYPE_CHECKING:", "@(abc\\.)?abstractmethod", ] -- GitLab