"""Nox sessions.""" import shutil import sys from pathlib import Path from textwrap import dedent import nox try: from nox_poetry import Session, session except ImportError: message = f"""\ Nox failed to import the 'nox-poetry' package. Please install it using the following command: {sys.executable} -m pip install nox-poetry""" raise SystemExit(dedent(message)) from None package = "socceraction" python_versions = ["3.12", "3.11", "3.10", "3.9"] nox.needs_version = ">= 2021.6.6" nox.options.sessions = ( "pre-commit", "mypy", "tests", "docs-build", ) def activate_virtualenv_in_precommit_hooks(session: Session) -> None: """Activate virtualenv in hooks installed by pre-commit. This function patches git hooks installed by pre-commit to activate the session's virtual environment. This allows pre-commit to locate hooks in that environment when invoked from git. Parameters ---------- session : Session The Session object. """ if session.bin is None: return virtualenv = session.env.get("VIRTUAL_ENV") if virtualenv is None: return hookdir = Path(".git") / "hooks" if not hookdir.is_dir(): return for hook in hookdir.iterdir(): if hook.name.endswith(".sample") or not hook.is_file(): continue text = hook.read_text() bindir = repr(session.bin)[1:-1] # strip quotes if not (Path("A") == Path("a") and bindir.lower() in text.lower() or bindir in text): continue lines = text.splitlines() if not (lines[0].startswith("#!") and "python" in lines[0].lower()): continue header = dedent( f"""\ import os os.environ["VIRTUAL_ENV"] = {virtualenv!r} os.environ["PATH"] = os.pathsep.join(( {session.bin!r}, os.environ.get("PATH", ""), )) """ ) lines.insert(1, header) hook.write_text("\n".join(lines)) @session(name="pre-commit", python="3.12") def precommit(session: Session) -> None: """Lint using pre-commit.""" args = session.posargs or [ "run", "--all-files", "--hook-stage=manual", "--show-diff-on-failure", ] session.install( "darglint", "ruff", "pep8-naming", "pre-commit", "pre-commit-hooks", "pyupgrade", ) session.run("pre-commit", *args) if args and args[0] == "install": activate_virtualenv_in_precommit_hooks(session) @session(python=python_versions) def mypy(session: Session) -> None: """Type-check using mypy.""" args = session.posargs or ["socceraction", "tests", "docs/conf.py"] session.install(".") session.install("mypy", "pytest") session.run("mypy", *args) if not session.posargs: session.run("mypy", f"--python-executable={sys.executable}", "noxfile.py") @session(python=python_versions) def tests(session: Session) -> None: """Run the test suite.""" session.install(".[statsbomb,kloppy]") session.install("coverage[toml]", "pytest", "pygments", "pytest-mock") try: session.run( "coverage", "run", "--parallel", "-m", "pytest", "-m", "not e2e", *session.posargs, ) finally: if session.interactive: session.notify("coverage", posargs=[]) @session def coverage(session: Session) -> None: """Produce the coverage report.""" args = session.posargs or ["report"] session.install("coverage[toml]") if not session.posargs and any(Path().glob(".coverage.*")): session.run("coverage", "combine") session.run("coverage", *args) @session(name="docs-build", python="3.12") def docs_build(session: Session) -> None: """Build the documentation.""" args = session.posargs or ["docs", "docs/_build"] session.install(".[kloppy]") session.install("sphinx", "furo", "sphinx-autodoc-typehints") build_dir = Path("docs", "_build") if build_dir.exists(): shutil.rmtree(build_dir) session.run("sphinx-build", *args) @session(python="3.12") def docs(session: Session) -> None: """Build and serve the documentation with live reloading on file changes.""" args = session.posargs or ["--host=0.0.0.0", "docs", "docs/_build"] session.install(".[kloppy]") session.install("sphinx", "sphinx-autobuild", "furo", "sphinx-autodoc-typehints") build_dir = Path("docs", "_build") if build_dir.exists(): shutil.rmtree(build_dir) session.run("sphinx-autobuild", *args)