Source code for formelsammlung.env_exe_runner

"""
    formelsammlung.tox_env_exe_runner
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Call tools from tox environments.

    :copyright: (c) 2020, Christian Riedel and AUTHORS
    :license: GPL-3.0-or-later, see LICENSE for details
"""  # noqa: D205,D208,D400
import subprocess  # noqa: S404
import sys

from pathlib import Path
from typing import List, Optional


IS_WIN = sys.platform == "win32"
EXE = "Scripts/{tool}.exe" if IS_WIN else "bin/{tool}"


def _check_runner_envs(venv_runner: str, envs: List[str], tool: str) -> Optional[Path]:
    """Check if executable is found in any of the envs for given env runner."""
    for env in envs:
        path = Path(f".{venv_runner}") / env / EXE.format(tool=tool)
        if path.is_file():
            return path
    return None


def _check_venv(venv: str, tool: str) -> Optional[Path]:
    """Check if executable is found in venv."""
    path = Path(venv) / EXE.format(tool=tool)
    if path.is_file():
        return path
    return None


[docs]def env_exe_runner( venv_runner: List[str], envs: List[str], tool: str, tool_args: Optional[List[str]] = None, ) -> int: """Call given ``tool`` from given `tox` or `nox` or `virtual` env considering OS. :param venv_runner: List containing: 'nox' and/or 'tox' and/or one or more 'virtual environment's :param envs: List of environments to search the ``tool`` in when 'tox' or 'nox' is in venv_runner. If neither 'tox' nor 'nox' is in ``venv_runner`` you may pass an empty list. :param tool: Name of the executable to run. :param tool_args: Arguments to give to the ``tool``. :return: Exit code 127 if no executable is found or the exit code of the called cmd. """ cmd_path = None error_msgs = [] for runner in venv_runner: if runner in ("tox", "nox"): error_msgs.append(f"- '{runner}' envs: {envs}") cmd_path = _check_runner_envs(runner, envs, tool) else: error_msgs.append(f"- virtual env: ['{runner}']") cmd_path = _check_venv(runner, tool) if cmd_path is not None: break if cmd_path is None: print(f"No '{tool}' executable found. Searched in:") for msg in error_msgs: print(msg) return 127 return subprocess.call([str(cmd_path), *(tool_args or [])]) # noqa: S603
[docs]def cli_caller() -> int: """Warp ``env_exe_runner`` to be callable by cli. Script to call executables in `tox`/`nox`/`virtual` envs considering OS. The script takes three mandatory arguments: 1. A string with comma separated runner (`tox` and/or `nox`) and/or virtual envs. 2. A string with comma separated `tox`/`nox` envs to check for the executable. The envs are checked in given order. If `tox`/`nox` are not part of the first arg you may pass a '-' as second arg. 3. The executable to call like e.g. `pylint`. All other arguments after are passed to the tool on call. :return: Exit code from ``env_exe_runner`` """ return env_exe_runner( sys.argv[1].split(","), sys.argv[2].split(","), sys.argv[3], sys.argv[4:] ) # pragma: no cover
if __name__ == "__main__": sys.exit(cli_caller())