summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJürgen Gmach <juergen.gmach@googlemail.com>2021-04-13 18:04:48 +0200
committerJürgen Gmach <juergen.gmach@googlemail.com>2021-04-13 18:06:18 +0200
commit187987abc8a5095e0109387ab9d09f227e19a4d8 (patch)
tree28cb088f3c2280da208f19963a15b9744bf2db8f
parent5118401e6beb9f9b6dbe9bffa847dc99d678b1d7 (diff)
downloadtox-git-187987abc8a5095e0109387ab9d09f227e19a4d8.tar.gz
Evaluate factor conditions for `command` keys
Due to the order how the configuration got loaded, and due to a bug in the factor parser, factors were not identified and thus not evaluated for `command` keys. This has been fixed now. Closes #2002
-rw-r--r--docs/changelog/2002.bugfix.rst1
-rw-r--r--src/tox/config/loader/ini/__init__.py7
-rw-r--r--src/tox/config/loader/ini/factor.py2
-rw-r--r--tests/config/conftest.py9
-rw-r--r--tests/config/loader/ini/test_ini_loader.py22
-rw-r--r--tests/config/test_main.py7
6 files changed, 37 insertions, 11 deletions
diff --git a/docs/changelog/2002.bugfix.rst b/docs/changelog/2002.bugfix.rst
new file mode 100644
index 00000000..004c1b98
--- /dev/null
+++ b/docs/changelog/2002.bugfix.rst
@@ -0,0 +1 @@
+Evaluate factor conditions for ``command`` keys - by :user:`jugmac00`.
diff --git a/src/tox/config/loader/ini/__init__.py b/src/tox/config/loader/ini/__init__.py
index 7b4a3c3e..5822555e 100644
--- a/src/tox/config/loader/ini/__init__.py
+++ b/src/tox/config/loader/ini/__init__.py
@@ -30,10 +30,10 @@ class IniLoader(StrConvert, Loader[str]):
def load_raw(self, key: str, conf: Optional["Config"], env_name: Optional[str]) -> str:
value = self._section[key]
- collapsed_newlines = value.replace("\r", "").replace("\\\n", "") # collapse explicit new-line escape
+
# strip comments
elements: List[str] = []
- for line in collapsed_newlines.split("\n"):
+ for line in value.split("\n"):
if not line.startswith("#"):
part = _COMMENTS.sub("", line)
elements.append(part.replace("\\#", "#"))
@@ -43,7 +43,8 @@ class IniLoader(StrConvert, Loader[str]):
factor_filtered = strip_comments # we don't support factor and replace functionality there
else:
factor_filtered = filter_for_env(strip_comments, env_name) # select matching factors
- return factor_filtered
+ collapsed = factor_filtered.replace("\r", "").replace("\\\n", "") # collapse explicit new-line escape
+ return collapsed
@contextmanager
def build(
diff --git a/src/tox/config/loader/ini/factor.py b/src/tox/config/loader/ini/factor.py
index 281dbf4d..2fd11735 100644
--- a/src/tox/config/loader/ini/factor.py
+++ b/src/tox/config/loader/ini/factor.py
@@ -45,7 +45,7 @@ def explode_factor(group: List[Tuple[str, bool]]) -> str:
def expand_factors(value: str) -> Iterator[Tuple[Optional[Iterator[List[Tuple[str, bool]]]], str]]:
for line in value.split("\n"):
- match = re.match(r"^((?P<factor_expr>[\w{}.!,-]+):\s+)?(?P<content>.*?)$", line)
+ match = re.match(r"^(\s*(?P<factor_expr>[\w{}.!,-]+):\s+)?(?P<content>.*?)$", line)
if match is None: # pragma: no cover
raise RuntimeError("for a valid factor regex this cannot happen")
groups = match.groupdict()
diff --git a/tests/config/conftest.py b/tests/config/conftest.py
new file mode 100644
index 00000000..ee697f20
--- /dev/null
+++ b/tests/config/conftest.py
@@ -0,0 +1,9 @@
+import pytest
+
+from tests.conftest import ToxIniCreator
+from tox.config.main import Config
+
+
+@pytest.fixture()
+def empty_config(tox_ini_conf: ToxIniCreator) -> Config:
+ return tox_ini_conf("")
diff --git a/tests/config/loader/ini/test_ini_loader.py b/tests/config/loader/ini/test_ini_loader.py
index ac0f17df..187b723a 100644
--- a/tests/config/loader/ini/test_ini_loader.py
+++ b/tests/config/loader/ini/test_ini_loader.py
@@ -5,6 +5,7 @@ import pytest
from tox.config.loader.api import Override
from tox.config.loader.ini import IniLoader
+from tox.config.main import Config
def test_ini_loader_keys(mk_ini_conf: Callable[[str], ConfigParser]) -> None:
@@ -56,3 +57,24 @@ def test_ini_loader_strip_comments(mk_ini_conf: Callable[[str], ConfigParser], c
loader = IniLoader("tox", mk_ini_conf(f"[tox]\na={case}"), [], core_prefix="tox")
outcome = loader.load(key="a", of_type=str, conf=None, env_name=None, chain=[], kwargs={})
assert outcome == result
+
+
+@pytest.mark.parametrize(
+ ("env", "result"),
+ [
+ ("py35", "python -m coverage html -d cov"),
+ ("py36", "python -m coverage html -d cov\n--show-contexts"),
+ ],
+)
+def test_ini_loader_raw_with_factors(
+ mk_ini_conf: Callable[[str], ConfigParser], env: str, result: str, empty_config: Config
+) -> None:
+ commands = "python -m coverage html -d cov \n !py35: --show-contexts"
+ loader = IniLoader(
+ section="testenv",
+ parser=mk_ini_conf(f"[tox]\nenvlist=py35,py36\n[testenv]\ncommands={commands}"),
+ overrides=[],
+ core_prefix="tox",
+ )
+ outcome = loader.load_raw(key="commands", conf=empty_config, env_name=env)
+ assert outcome == result
diff --git a/tests/config/test_main.py b/tests/config/test_main.py
index 59f5359d..ed7b8f4e 100644
--- a/tests/config/test_main.py
+++ b/tests/config/test_main.py
@@ -1,5 +1,3 @@
-import pytest
-
from tests.conftest import ToxIniCreator
from tox.config.loader.api import Override
from tox.config.loader.memory import MemoryLoader
@@ -7,11 +5,6 @@ from tox.config.main import Config
from tox.config.sets import ConfigSet
-@pytest.fixture()
-def empty_config(tox_ini_conf: ToxIniCreator) -> Config:
- return tox_ini_conf("")
-
-
def test_empty_config_repr(empty_config: Config) -> None:
text = repr(empty_config)
assert str(empty_config.core["tox_root"]) in text