[tox]
minversion = 3.16.1
envlist =
  lint
  packaging
  docs
  py{39,38}-{ansible29,ansible212}
  py310-{ansible212}
  py{310,39,38}-devel
isolated_build = true
requires =
  setuptools >= 41.4.0
  pip >= 19.3.0
skip_missing_interpreters = True
skipsdist = true

[testenv]
description =
  Run the tests with {basepython}
  devel: ansible devel branch
  ansible29: ansible 2.9
  ansible210: ansible-base 2.10
  ansible212: ansible-core 2.12
deps =
  ansible29: ansible>=2.9,<2.10
  ansible210: ansible-base>=2.10,<2.11
  ansible212: ansible-core>=2.12,<2.13
  devel: ansible-core @ git+https://github.com/ansible/ansible.git  # GPLv3+
  --editable .[test]
commands =
  ansible --version
  # We add coverage options but not making them mandatory as we do not want to force
  # pytest users to run coverage when they just want to run a single test with `pytest -k test`
  coverage run -m pytest {posargs:}
commands_pre =
  # safety measure to assure we do not accidentally run tests with broken dependencies
  {envpython} -m pip check
passenv =
  CURL_CA_BUNDLE  # https proxies, https://github.com/tox-dev/tox/issues/1437
  FORCE_COLOR
  HOME
  NO_COLOR
  PYTEST_*  # allows developer to define their own preferences
  PY_COLORS
  REQUESTS_CA_BUNDLE  # https proxies
  SSL_CERT_FILE  # https proxies
  LANG
  LC_ALL
  LC_CTYPE
setenv =
  COVERAGE_FILE = {env:COVERAGE_FILE:{toxworkdir}/.coverage.{envname}}
  PIP_DISABLE_PIP_VERSION_CHECK = 1
  PIP_CONSTRAINT = {toxinidir}/constraints.txt
  PRE_COMMIT_COLOR = always
  PYTEST_REQPASS = 75
  FORCE_COLOR = 1
allowlist_externals =
  ansible
  sh

[testenv:lint]
description = Run all linters
# locked basepython is needed because to keep constrains.txt predictable
basepython = python3.9
deps =
  pip-tools>=6.5.1
  pre-commit>=2.6.0
  setuptools>=51.1.1
skip_install = true
usedevelop = false
commands =
  {envpython} -m pre_commit run -a --show-diff-on-failure {posargs:}
passenv =
  {[testenv]passenv}
  PRE_COMMIT_HOME

[testenv:deps]
description = Bump all test depeendencies
basepython = {[testenv:lint]basepython}
envdir = {toxworkdir}/lint
deps = {[testenv:lint]deps}
skip_install = true
commands =
  {[testenv:lint]commands} --hook-stage manual

[testenv:packaging]
basepython = python3
description =
  Build package, verify metadata, install package and assert behavior when ansible is missing.
deps =
  build >= 0.5.0
  twine >= 3.4.1
skip_install = true
# Ref: https://twitter.com/di_codes/status/1044358639081975813
commands =
  # build wheel and sdist using PEP-517
  {envpython} -c 'import os.path, shutil, sys; \
  dist_dir = os.path.join("{toxinidir}", "dist"); \
  os.path.isdir(dist_dir) or sys.exit(0); \
  print("Removing \{!s\} contents...".format(dist_dir), file=sys.stderr); \
  shutil.rmtree(dist_dir)'
  {envpython} -m build \
    --outdir {toxinidir}/dist/ \
    {toxinidir}
  # Validate metadata using twine
  twine check {toxinidir}/dist/*
  # Install the wheel
  sh -c "python3 -m pip install {toxinidir}/dist/*.whl"

[testenv:py{39,38,37,36}]
description = Run the tests with {basepython} ansible-core 2.11+
deps =
  {[testenv]deps}
  ansible-core>=2.11

[testenv:docs]
description = Build docs
commands =
  python -m sphinx \
    -a -n -W \
    --keep-going \
    -b html  {tty:--color} \
    -d "{toxworkdir}/doctree" \
    docs/ "{toxworkdir}/html"
deps =
  -r docs/requirements.txt
  --editable .
passenv = *
