Skip to content

Commit c9394e8

Browse files
mgedmingaborbernat
andauthored
Restore TOX_SKIP_ENV filtering (#2707)
Co-authored-by: Bernát Gábor <[email protected]> Fixes #2698
1 parent 8c0239e commit c9394e8

File tree

5 files changed

+46
-3
lines changed

5 files changed

+46
-3
lines changed

docs/changelog/2698.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
``TOX_SKIP_ENV`` environment variable now works again, and can also be set via the CLI argument ``--skip-env``
2+
for any command where ``-e`` can be set - by :user:`mgedmin`.

src/tox/session/env_select.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
import logging
4+
import re
35
from argparse import ArgumentParser
46
from collections import Counter
57
from dataclasses import dataclass
@@ -21,6 +23,9 @@
2123
from tox.session.state import State
2224

2325

26+
LOGGER = logging.getLogger(__name__)
27+
28+
2429
class CliEnv:
2530
"""CLI tox env selection"""
2631

@@ -88,6 +93,8 @@ def register_env_select_flags(
8893
add_to.add_argument("-m", dest="labels", metavar="label", help=help_msg, default=[], type=str, nargs="+")
8994
help_msg = "factors to evaluate"
9095
add_to.add_argument("-f", dest="factors", metavar="factor", help=help_msg, default=[], type=str, nargs="+")
96+
help_msg = "exclude all environments selected that match this regular expression"
97+
add_to.add_argument("--skip-env", dest="skip_env", metavar="re", help=help_msg, default="", type=str)
9198
return add_to
9299

93100

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

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

122132
def _collect_names(self) -> Iterator[tuple[Iterable[str], bool]]:
123133
""":return: sources of tox environments defined with name and if is marked as target to run"""
@@ -320,14 +330,17 @@ def iter(
320330
321331
:return: an iteration of tox environments
322332
"""
323-
ignore_envs: set[str] = set()
324333
for name, env_info in self._defined_envs.items():
325334
if only_active and not env_info.is_active:
326335
continue
327336
if not package and not isinstance(env_info.env, RunToxEnv):
328337
continue
338+
if self._filter_re is not None and self._filter_re.match(name):
339+
if name not in self._warned_about:
340+
self._warned_about.add(name)
341+
LOGGER.warning("skip environment %s, matches filter %r", name, self._filter_re.pattern)
342+
continue
329343
yield name
330-
ignore_envs.add(name)
331344

332345
def ensure_only_run_env_is_active(self) -> None:
333346
envs, active = self._defined_envs, self._env_name_to_active()

tests/config/cli/test_cli_env_var.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def test_verbose_no_test() -> None:
6262
"index_url": [],
6363
"factors": [],
6464
"labels": [],
65+
"skip_env": "",
6566
}
6667

6768

@@ -120,6 +121,7 @@ def test_env_var_exhaustive_parallel_values(
120121
"factors": [],
121122
"labels": [],
122123
"exit_and_dump_after": 0,
124+
"skip_env": "",
123125
}
124126
assert options.parsed.verbosity == 4
125127
assert options.cmd_handlers == core_handlers

tests/config/cli/test_cli_ini.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ def default_options(tmp_path: Path) -> dict[str, Any]:
9999
"factors": [],
100100
"labels": [],
101101
"exit_and_dump_after": 0,
102+
"skip_env": "",
102103
}
103104

104105

@@ -134,6 +135,7 @@ def test_ini_exhaustive_parallel_values(exhaustive_ini: Path, core_handlers: dic
134135
"factors": [],
135136
"labels": [],
136137
"exit_and_dump_after": 0,
138+
"skip_env": "",
137139
}
138140
assert options.parsed.verbosity == 4
139141
assert options.cmd_handlers == core_handlers

tests/session/test_env_select.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from tox.pytest import ToxProjectCreator
3+
from tox.pytest import MonkeyPatch, ToxProjectCreator
44

55

66
def test_label_core_can_define(tox_project: ToxProjectCreator) -> None:
@@ -70,3 +70,27 @@ def test_factor_select(tox_project: ToxProjectCreator) -> None:
7070
outcome = project.run("l", "--no-desc", "-f", "cov", "django20")
7171
outcome.assert_success()
7272
outcome.assert_out_err("py310-django20-cov\npy39-django20-cov\n", "")
73+
74+
75+
def test_tox_skip_env(tox_project: ToxProjectCreator, monkeypatch: MonkeyPatch) -> None:
76+
monkeypatch.setenv("TOX_SKIP_ENV", "m[y]py")
77+
project = tox_project({"tox.ini": "[tox]\nenv_list = py3{10,9},mypy"})
78+
outcome = project.run("l", "--no-desc", "-q")
79+
outcome.assert_success()
80+
outcome.assert_out_err("py310\npy39\n", "")
81+
82+
83+
def test_tox_skip_env_cli(tox_project: ToxProjectCreator, monkeypatch: MonkeyPatch) -> None:
84+
monkeypatch.delenv("TOX_SKIP_ENV", raising=False)
85+
project = tox_project({"tox.ini": "[tox]\nenv_list = py3{10,9},mypy"})
86+
outcome = project.run("l", "--no-desc", "-q", "--skip-env", "m[y]py")
87+
outcome.assert_success()
88+
outcome.assert_out_err("py310\npy39\n", "")
89+
90+
91+
def test_tox_skip_env_logs(tox_project: ToxProjectCreator, monkeypatch: MonkeyPatch) -> None:
92+
monkeypatch.setenv("TOX_SKIP_ENV", "m[y]py")
93+
project = tox_project({"tox.ini": "[tox]\nenv_list = py3{10,9},mypy"})
94+
outcome = project.run("l", "--no-desc")
95+
outcome.assert_success()
96+
outcome.assert_out_err("ROOT: skip environment mypy, matches filter 'm[y]py'\npy310\npy39\n", "")

0 commit comments

Comments
 (0)