Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore TOX_SKIP_ENV filtering #2707

Merged
merged 9 commits into from
Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/changelog/2698.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
``TOX_SKIP_ENV`` environment variable now works again, and can also be set via the CLI argument ``--skip-env``
for any command where ``-e`` can be set - by :user:`mgedmin`.
17 changes: 15 additions & 2 deletions src/tox/session/env_select.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

import logging
import re
from argparse import ArgumentParser
from collections import Counter
from dataclasses import dataclass
Expand All @@ -21,6 +23,9 @@
from tox.session.state import State


LOGGER = logging.getLogger(__name__)


class CliEnv:
"""CLI tox env selection"""

Expand Down Expand Up @@ -88,6 +93,8 @@ def register_env_select_flags(
add_to.add_argument("-m", dest="labels", metavar="label", help=help_msg, default=[], type=str, nargs="+")
help_msg = "factors to evaluate"
add_to.add_argument("-f", dest="factors", metavar="factor", help=help_msg, default=[], type=str, nargs="+")
help_msg = "exclude all environments selected that match this regular expression"
add_to.add_argument("--skip-env", dest="skip_env", metavar="re", help=help_msg, default="", type=str)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this even more than the environment variable!

return add_to


Expand All @@ -106,6 +113,7 @@ def __init__(self, state: State) -> None:
# to load the package environments of a run environments we need the run environment builder
# to load labels we need core + the run environment
self.on_empty_fallback_py = True
self._warned_about: set[str] = set() #: shared set of skipped environments that were already warned about
self._state = state
self._cli_envs: CliEnv | None = getattr(self._state.conf.options, "env", None)
self._defined_envs_: None | dict[str, _ToxEnvInfo] = None
Expand All @@ -118,6 +126,8 @@ def __init__(self, state: State) -> None:
self._provision: None | tuple[bool, str, MemoryLoader] = None

self._state.conf.core.add_config("labels", Dict[str, EnvList], {}, "core labels")
tox_env_filter_regex = getattr(state.conf.options, "skip_env", "").strip()
self._filter_re = re.compile(tox_env_filter_regex) if tox_env_filter_regex else None

def _collect_names(self) -> Iterator[tuple[Iterable[str], bool]]:
""":return: sources of tox environments defined with name and if is marked as target to run"""
Expand Down Expand Up @@ -320,14 +330,17 @@ def iter(

:return: an iteration of tox environments
"""
ignore_envs: set[str] = set()
for name, env_info in self._defined_envs.items():
if only_active and not env_info.is_active:
continue
if not package and not isinstance(env_info.env, RunToxEnv):
continue
if self._filter_re is not None and self._filter_re.match(name):
if name not in self._warned_about:
self._warned_about.add(name)
LOGGER.warning("skip environment %s, matches filter %r", name, self._filter_re.pattern)
continue
yield name
ignore_envs.add(name)

def ensure_only_run_env_is_active(self) -> None:
envs, active = self._defined_envs, self._env_name_to_active()
Expand Down
2 changes: 2 additions & 0 deletions tests/config/cli/test_cli_env_var.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def test_verbose_no_test() -> None:
"index_url": [],
"factors": [],
"labels": [],
"skip_env": "",
}


Expand Down Expand Up @@ -120,6 +121,7 @@ def test_env_var_exhaustive_parallel_values(
"factors": [],
"labels": [],
"exit_and_dump_after": 0,
"skip_env": "",
}
assert options.parsed.verbosity == 4
assert options.cmd_handlers == core_handlers
Expand Down
2 changes: 2 additions & 0 deletions tests/config/cli/test_cli_ini.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ def default_options(tmp_path: Path) -> dict[str, Any]:
"factors": [],
"labels": [],
"exit_and_dump_after": 0,
"skip_env": "",
}


Expand Down Expand Up @@ -134,6 +135,7 @@ def test_ini_exhaustive_parallel_values(exhaustive_ini: Path, core_handlers: dic
"factors": [],
"labels": [],
"exit_and_dump_after": 0,
"skip_env": "",
}
assert options.parsed.verbosity == 4
assert options.cmd_handlers == core_handlers
Expand Down
26 changes: 25 additions & 1 deletion tests/session/test_env_select.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from tox.pytest import ToxProjectCreator
from tox.pytest import MonkeyPatch, ToxProjectCreator


def test_label_core_can_define(tox_project: ToxProjectCreator) -> None:
Expand Down Expand Up @@ -70,3 +70,27 @@ def test_factor_select(tox_project: ToxProjectCreator) -> None:
outcome = project.run("l", "--no-desc", "-f", "cov", "django20")
outcome.assert_success()
outcome.assert_out_err("py310-django20-cov\npy39-django20-cov\n", "")


def test_tox_skip_env(tox_project: ToxProjectCreator, monkeypatch: MonkeyPatch) -> None:
monkeypatch.setenv("TOX_SKIP_ENV", "m[y]py")
project = tox_project({"tox.ini": "[tox]\nenv_list = py3{10,9},mypy"})
outcome = project.run("l", "--no-desc", "-q")
outcome.assert_success()
outcome.assert_out_err("py310\npy39\n", "")


def test_tox_skip_env_cli(tox_project: ToxProjectCreator, monkeypatch: MonkeyPatch) -> None:
monkeypatch.delenv("TOX_SKIP_ENV", raising=False)
project = tox_project({"tox.ini": "[tox]\nenv_list = py3{10,9},mypy"})
outcome = project.run("l", "--no-desc", "-q", "--skip-env", "m[y]py")
outcome.assert_success()
outcome.assert_out_err("py310\npy39\n", "")


def test_tox_skip_env_logs(tox_project: ToxProjectCreator, monkeypatch: MonkeyPatch) -> None:
monkeypatch.setenv("TOX_SKIP_ENV", "m[y]py")
project = tox_project({"tox.ini": "[tox]\nenv_list = py3{10,9},mypy"})
outcome = project.run("l", "--no-desc")
outcome.assert_success()
outcome.assert_out_err("ROOT: skip environment mypy, matches filter 'm[y]py'\npy310\npy39\n", "")