# This configuration drives both CI and local development.
# I use this locally on Ubuntu 22.04, with the following additions
#
#   sudo add-apt-repository ppa:deadsnakes/ppa
#   sudo apt install lib{ldap2,sasl2,ssl}-dev python{2,2.7,3}{,-dev} python3.{7..13}{,-dev,-venv} python-is-python3 sshpass tox

# Py   A cntrllr  A target   coverage   Django     Jinja2     pip        psutil     pytest     tox        virtualenv
# ==== ========== ========== ========== ========== ========== ========== ========== ========== ========== ==========
# 2.4             2.3?       <= 3.7.1   <= 1.3.7              <= 1.1     <= 2.1.3              <= 1.4     <= 1.8
# 2.5                        <= 3.7.1   <= 1.4.22             <= 1.3.1   <= 2.1.3   <= 2.8.7   <= 1.6.1   <= 1.9.1
# 2.6  <= 2.6.20  <= 2.12    <= 4.5.4   <= 1.6.11  <= 2.10.3  <= 9.0.3   <= 5.9.0   <= 3.2.5   <= 2.9.1   <= 15.2.0
# 2.7  <= 2.11    <= 2.16    <= 5.5     <= 1.11.29 <= 2.11.3  <= 20                 <= 4.6.11  <= 3.28    <= 20.15²
# 3.5  <= 2.11    <= 2.15    <= 5.5     <= 2.2.28  <= 2.11.3  <= 20      <= 5.9.5   <= 6.1.0   <= 3.28    <= 20.15²
# 3.6  <= 2.11    <= 2.16    <= 6.2     <= 3.2.20  <= 3.0.3   <= 21                 <= 7.0.1   <= 3.28    <= 20.17²
# 3.7  <= 2.12    <= 2.17    <= 7.2.7   <= 3.2.20                                   <= 7.4.4   <= 4.8.0   <= 20.26.6²
# 3.8  <= 2.12    <= 2.19
# 3.9  <= 2.15
# 3.10 <= 2.17
# 3.11 <= 2.19
# 3.12            >= 2.13¹
#
# Notes
# 1. Python 3.12 on a target requires Ansible >= 6 (ansible-core >= 2.13).
#    Python 3.12 removed support for find_module(), replaced by find_spec().
#    In Ansible <= 4.x ansible.module_utils.six lacks find_spec().
#    https://github.com/ansible/ansible/commit/d6e28e68599e703c153914610152cf4492851eb3
#    In Ansible <= 5.x ansible.utils.collection_loader._AnsibleCollectionFinder
#    lacks find_spec(). https://github.com/ansible/ansible/pull/76225
#
#    Python 3.12 + get_uri requires Ansible >= 8 (ansible-core >= 2.15).
#    Python 3.12 removed deprecated httplib.HTTPSConnection() arguments.
#    https://github.com/ansible/ansible/pull/80751
#
# 2. Higher Virtualenv versions do not support this Python as *host* Python.
#    Virtualenv <= 20.21.1 supports creating virtualenvs with any *target* Python.
#    Virtualenv >= 20.22 supports creating virtualenvs with target Python >= 3.7.
#    https://virtualenv.pypa.io/en/latest/#compatibility

# Ansible            Dependency
# ================== ======================
# ansible <= 2.9
# ansible == 2.10.*  ansible-base ~= 2.10.0
# ansible == 3.*     ansible-base ~= 2.10.0
# ansible == 4.*     ansible-core ~= 2.11.0
# ansible == 5.*     ansible-core ~= 2.12.0
# ansible == 6.*     ansible-core ~= 2.13.0
# ansible == 7.x     ansible-core ~= 2.14.0
# ansible == 8.x     ansible-core ~= 2.15.0
# ansible == 9.x     ansible-core ~= 2.16.0
# ansible == 10.x    ansible-core ~= 2.17.0
# ansible == 11.x    ansible-core ~= 2.18.0
# ansible == 12.x    ansible-core ~= 2.19.0
# ansible == 13.x    ansible-core ~= 2.20.0

# See also
# - https://docs.ansible.com/ansible/devel/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix

[tox]
envlist =
    init,
    py{27,36}-m_ans-ans{2.10,3,4}
    py{311}-m_ans-ans{2.10,3-5}
    py{313}-m_ans-ans{6-9}
    py{314}-m_ans-ans{10-12}
    py{27,36,314}-m_mtg
    report,

[testenv]
basepython =
    py26: python2.6
    py27: python2.7
    py35: python3.5
    py36: python3.6
    py37: python3.7
    py38: python3.8
    py39: python3.9
    py310: python3.10
    py311: python3.11
    py312: python3.12
    py313: python3.13
    py314: python3.14
deps =
    -r{toxinidir}/tests/requirements.txt
    m_ans: -r{toxinidir}/tests/ansible/requirements.txt
    ans2.10: ansible~=2.10.0
    ans3: ansible~=3.0
    ans4: ansible~=4.0
    ans5: ansible~=5.0
    # From Ansible 6 PyPI distributions include a wheel
    ans6: ansible~=6.0
    ans7: ansible~=7.0
    ans8: ansible~=8.0
    ans9: ansible~=9.0
    ans10: ansible~=10.0
    ans11: ansible~=11.0
    ans12: ansible~=12.0
    ans13: ansible~=13.0
install_command =
    python -m pip --no-python-version-warning --disable-pip-version-check install {opts} {packages}
commands_pre =
    mode_debops_common: {toxinidir}/.ci/debops_common_install.py
commands =
    m_ans: {toxinidir}/.ci/ansible_tests.py
    mode_debops_common: {toxinidir}/.ci/debops_common_tests.py
    m_lcl: {toxinidir}/.ci/localhost_ansible_tests.py
    m_mtg: {toxinidir}/.ci/mitogen_tests.py
passenv =
    ANSIBLE_*
    HOME
    MITOGEN_*
setenv =
    ANSIBLE_ROLES_PATH = {toxinidir}/tests/image_prep/roles
    # See also azure-pipelines.yml
    ANSIBLE_STRATEGY = mitogen_linear
    NOCOVERAGE_ERASE = 1
    NOCOVERAGE_REPORT = 1
    PIP_CONSTRAINT={toxinidir}/tests/constraints.txt
    # Superceded in Ansible >= 6 (ansible-core >= 2.13) by result_format=yaml
    # Deprecated in Ansible 12 (ansible-core 2.19)
    # Removed in Ansible 13 (ansible-core 2.20)
    ans{2.10,3,4,5}: ANSIBLE_STDOUT_CALLBACK=yaml
    # Print warning on the first occurence at each module:linenno in Mitogen. Available Python 2.7, 3.2+.
    PYTHONWARNINGS=default:::ansible_mitogen,default:::mitogen
    # Ansible 6 - 8 (ansible-core 2.13 - 2.15) require Python 2.7 or >= 3.5 on targets
    ans{6,7,8}: MITOGEN_TEST_DISTRO_SPECS=centos7 centos8 debian9 debian10 debian11 ubuntu1604 ubuntu1804 ubuntu2004
    # Ansible 9 (ansible-core 2.16) requires Python 2.7 or >= 3.6 on targets
    ans9: MITOGEN_TEST_DISTRO_SPECS=centos7 centos8 debian9 debian10 debian11 ubuntu1804 ubuntu2004
    # Ansible 10 (ansible-core 2.17) requires Python >= 3.7 on targets
    ans10: MITOGEN_TEST_DISTRO_SPECS=debian10-py3 debian11-py3 ubuntu2004-py3
    # Ansible 11 (ansible-core 2.18) requires Python >= 3.8 on targets
    ans11: MITOGEN_TEST_DISTRO_SPECS=debian11-py3 ubuntu2004-py3
    ans12: MITOGEN_TEST_DISTRO_SPECS=debian11-py3 ubuntu2004-py3
    # Ansible 13 (ansible-core 2.20) requires Python >= 3.9 on targets
    ans13: MITOGEN_TEST_DISTRO_SPECS=debian11-py3
    distros_centos: MITOGEN_TEST_DISTRO_SPECS=centos6 centos7 centos8
    distros_centos5: MITOGEN_TEST_DISTRO_SPECS=centos5
    distros_centos6: MITOGEN_TEST_DISTRO_SPECS=centos6
    distros_centos7: MITOGEN_TEST_DISTRO_SPECS=centos7
    distros_centos8: MITOGEN_TEST_DISTRO_SPECS=centos8
    distros_debian: MITOGEN_TEST_DISTRO_SPECS=debian9 debian10 debian11
    distros_debian9: MITOGEN_TEST_DISTRO_SPECS=debian9
    distros_debian10: MITOGEN_TEST_DISTRO_SPECS=debian10
    distros_debian11: MITOGEN_TEST_DISTRO_SPECS=debian11
    distros_ubuntu: MITOGEN_TEST_DISTRO_SPECS=ubuntu1604 ubuntu1804 ubuntu2004
    distros_ubuntu1604: MITOGEN_TEST_DISTRO_SPECS=ubuntu1604
    distros_ubuntu1804: MITOGEN_TEST_DISTRO_SPECS=ubuntu1804
    distros_ubuntu2004: MITOGEN_TEST_DISTRO_SPECS=ubuntu2004
    m_ans: MODE=ansible
    m_ans: ANSIBLE_SKIP_TAGS=resource_intensive
    m_ans: ANSIBLE_CALLBACK_WHITELIST=profile_tasks
    m_ans: ANSIBLE_CALLBACKS_ENABLED=profile_tasks
    mode_debops_common: MODE=debops_common
    m_lcl: ANSIBLE_SKIP_TAGS=issue_776,resource_intensive
    m_mtg: MODE=mitogen
    s_lin: ANSIBLE_STRATEGY=linear
allowlist_externals =
    # Added: Tox 3.18: Tox 4.0+
    *_install.py
    *_tests.py
    docker
    docker-credential-secretservice
    echo
    gpg2
    pass
whitelist_externals =
    # Deprecated: Tox 3.18+; Removed: Tox 4.0
    *_install.py
    *_tests.py
    docker
    docker-credential-secretservice
    echo
    gpg2
    pass

[testenv:init]
basepython = python3
commands =
    coverage erase
deps =
    coverage==4.5.4

[testenv:report]
basepython = python3
commands =
    coverage html
    echo "coverage report is at file://{toxinidir}/htmlcov/index.html"
deps =
    coverage==4.5.4
whitelist_externals =
    echo

[testenv:docs]
basepython = python3.8
changedir = docs
commands =
    sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html
deps =
    -r docs/requirements.txt
