[tox]
envlist =
    lint
    {py311,py312,py313}-test
    combine-test-reports
isolated_build = True

[gh-actions]
python =
    3.11: py311-test
    3.12: py312-test
    3.13: py313-test

[testenv:lint]
description = Run static checkers.
basepython = py311
extras = lint
commands =
    # Check import ordering
    isort . --check
    # Check formatting
    black . --check
    # Check type hinting
    mypy .
    # Lint source code
    ruff check .
    pylint . {posargs}
    # Check that function argument names are consistent between function signatures and docstrings
    pylint --load-plugins pylint.extensions.docparams src {posargs}


[testenv:{py311,py312,py313}-test]
description = Run doc tests and unit tests.
package = wheel
extras = test
setenv =
    PY_IGNORE_IMPORTMISMATCH=1
    COVERAGE_FILE = reports{/}.coverage.{envname}
commands =
    # Run tests and doctests from .py files
    pytest --junitxml=reports/pytest.xml.{envname} {posargs} src/ tests/


[testenv:combine-test-reports]
description = Combine test and coverage data from multiple test runs.
skip_install = true
setenv =
    COVERAGE_FILE = reports/.coverage
depends = {py311,py312,py313}-test
deps =
    junitparser
    coverage[toml]
commands =
    junitparser merge --glob reports/pytest.xml.* reports/pytest.xml
    coverage combine --keep
    coverage html
    coverage xml


[testenv:docs]
description = Test and build the docs.
setenv =
    DOCSDIR = {toxinidir}/docs
    BUILDDIR = {toxinidir}/docs/build
    DEST_DIR = src/vdoc/docs
extras = doc
commands =
    # Remove build directory
    python -c 'import shutil; shutil.rmtree("{env:BUILDDIR}", ignore_errors=True);'
    # Delete all files generated by sphinx-apidoc
    python -c 'import glob, os; [os.remove(f) for f in glob.glob("docs/vdoc*")];'
    # Create dummy files to prevent warnings
    python -c 'import pathlib; pathlib.Path("{env:DOCSDIR}").joinpath("vdoc.rst").write_text("");'
    python -c 'import pathlib; pathlib.Path("{env:DOCSDIR}").joinpath("license_compliance.rst").write_text("");'
    # Check .rst files
    doc8 {env:DOCSDIR}
    # Run doctests (only from .rst files in docs folder, doctests in .py files are covered by pytest)
    sphinx-build -b doctest -W -d "{env:BUILDDIR}/doctrees" "{env:DOCSDIR}" "{env:BUILDDIR}/doctest" {posargs}
    # Autogenerate docs from code
    sphinx-apidoc -f --no-toc -o docs/ src/vdoc
    # Dump OSS license information into the docs directory
    python {env:DOCSDIR}/_scripts/generate_license_information.py
    # Build the docs
    sphinx-build -b html -d "{env:BUILDDIR}/doctrees" "{env:DOCSDIR}" "{env:DEST_DIR}" {posargs}


[testenv:build]
description = Build the package.
extras = build
depends =
    build-ui
    docs

commands =
    # Clean up build directories
    python -c 'from shutil import rmtree; rmtree("build", True); rmtree("dist", True)'
    # Build the package
    python -m build .

[testenv:build-ui]
description = Build the web UI.
allowlist_externals =
    npm
commands =
    npm run build
