[tox]
minversion = 2.0
skipsdist = True
envlist = docs,linters,functional


[testenv]
usedevelop = True
install_command =
    pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
deps =
    -r{toxinidir}/test-requirements.txt
commands =
    /usr/bin/find . -type f -name "*.pyc" -delete
passenv =
    HOME
    http_proxy
    HTTP_PROXY
    https_proxy
    HTTPS_PROXY
    no_proxy
    NO_PROXY
whitelist_externals =
    bash
    git
    rm
    wget
setenv =
    VIRTUAL_ENV={envdir}


[testenv:docs]
commands=
    bash -c "rm -rf doc/build"
    doc8 doc
    python setup.py build_sphinx


[doc8]
# Settings for doc8:
extensions = .rst


[testenv:releasenotes]
# NOTE(sdague): this target does not use constraints because
# upstream infra does not yet support it. Once that's fixed, we can
# drop the install_command.
install_command =
    pip install -U --force-reinstall {opts} {packages}
commands =
    sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html


# environment used by the -infra templated docs job
[testenv:venv]
# NOTE(jaegerandi): this target does not use constraints because
# upstream infra does not yet support it. Once that's fixed, we can
# drop the install_command.
install_command =
    pip install -U --force-reinstall {opts} {packages}
commands =
    {posargs}


[testenv:pep8]
commands =
    # Run hacking/flake8 check for all python files
    bash -c "grep --recursive --binary-files=without-match \
        --files-with-match '^.!.*python$' \
        --exclude-dir .eggs \
        --exclude-dir .git \
        --exclude-dir .tox \
        --exclude-dir *.egg-info \
        --exclude-dir doc \
        {toxinidir} | xargs flake8 --verbose"


[flake8]
# Ignores the following rules due to how ansible modules work in general
#     F403 'from ansible.module_utils.basic import *' used;
#          unable to detect undefined names
#     H303 No wildcard (*) import.
ignore=F403,H303


[testenv:bashate]
commands =
    # Run bashate check for all bash scripts
    # Ignores the following rules:
    #     E003: Indent not multiple of 4 (we prefer to use multiples of 2)
    #     E006: Line longer than 79 columns (as many scripts use jinja
    #           templating, this is very difficult)
    #     E040: Syntax error determined using `bash -n` (as many scripts
    #           use jinja templating, this will often fail and the syntax
    #           error will be discovered in execution anyway)
    bash -c "grep --recursive --binary-files=without-match \
        --files-with-match '^.!.*\(ba\)\?sh$' \
        --exclude-dir .tox \
        --exclude-dir .git \
        {toxinidir} | xargs bashate --error . --verbose --ignore=E003,E006,E040"


[testenv:ansible]
deps =
    {[testenv]deps}
    ansible==1.9.4
    ansible-lint>=2.7.0,<3.0.0
setenv =
    {[testenv]setenv}
    ANSIBLE_HOST_KEY_CHECKING = False
    ANSIBLE_SSH_CONTROL_PATH = /tmp/%%h-%%r
    # TODO (odyssey4me) These are only here as they are non-standard folder
    # names for Ansible 1.9.x. We are using the standard folder names for
    # Ansible v2.x. We can remove this when we move to Ansible 2.x.
    ANSIBLE_ACTION_PLUGINS = {homedir}/.ansible/plugins/action
    ANSIBLE_CALLBACK_PLUGINS = {homedir}/.ansible/plugins/callback
    ANSIBLE_FILTER_PLUGINS = {homedir}/.ansible/plugins/filter
    ANSIBLE_LOOKUP_PLUGINS = {homedir}/.ansible/plugins/lookup
    # This is required as the default is the current path or a path specified
    # in ansible.cfg
    ANSIBLE_LIBRARY = {homedir}/.ansible/plugins/library
    # This is required as the default is '/etc/ansible/roles' or a path
    # specified in ansible.cfg
    ANSIBLE_ROLES_PATH = {homedir}/.ansible/roles:{toxinidir}/..
commands =
    rm -rf {homedir}/.ansible/plugins
    git clone https://git.openstack.org/openstack/openstack-ansible-plugins \
              {homedir}/.ansible/plugins
    rm -rf {homedir}/.ansible/roles
    ansible-galaxy install \
                   --role-file={toxinidir}/tests/ansible-role-requirements.yml \
                   --force


[testenv:ansible-syntax]
deps =
    {[testenv:ansible]deps}
setenv =
    {[testenv:ansible]setenv}
commands =
    {[testenv:ansible]commands}
    ansible-playbook -i {toxinidir}/tests/inventory \
                     --syntax-check \
                     --list-tasks \
                     -e "rolename={toxinidir}" \
                     {toxinidir}/tests/test.yml


[testenv:ansible-lint]
deps =
    {[testenv:ansible]deps}
commands =
    {[testenv:ansible]commands}
    ansible-lint {toxinidir}


[testenv:functional]
# NOTE(odyssey4me): this target does not use constraints because
# it doesn't work in OpenStack-CI yet. Once that's fixed, we can
# drop the install_command.
install_command =
    pip install -U --force-reinstall {opts} {packages}
deps =
    {[testenv:ansible]deps}
setenv =
    {[testenv:ansible]setenv}
commands =
    {[testenv:ansible]commands}
    ansible-playbook -i {toxinidir}/tests/inventory \
                     -e "rolename={toxinidir}" \
                     -e "install_test_packages=True" \
                     {toxinidir}/tests/test.yml -vvvv


[testenv:linters]
deps =
    {[testenv:ansible]deps}
setenv =
    {[testenv:ansible]setenv}
commands =
    {[testenv:pep8]commands}
    {[testenv:bashate]commands}
    {[testenv:ansible-lint]commands}
    {[testenv:ansible-syntax]commands}
    {[testenv:docs]commands}