Skip to content

Commit

Permalink
Evaluate factor conditions for command keys
Browse files Browse the repository at this point in the history
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 in
`command` keys.

This has been fixed now.

Closes #2002
  • Loading branch information
jugmac00 committed Apr 13, 2021
1 parent 5118401 commit 6dbff12
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 11 deletions.
1 change: 1 addition & 0 deletions docs/changelog/2002.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Evaluate factor conditions for ``command`` keys - by :user:`jugmac00`.
7 changes: 4 additions & 3 deletions src/tox/config/loader/ini/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ def __init__(self, section: str, parser: ConfigParser, overrides: List[Override]

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("\\#", "#"))
Expand All @@ -43,7 +43,8 @@ def load_raw(self, key: str, conf: Optional["Config"], env_name: Optional[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(
Expand Down
2 changes: 1 addition & 1 deletion src/tox/config/loader/ini/factor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
9 changes: 9 additions & 0 deletions tests/config/conftest.py
Original file line number Diff line number Diff line change
@@ -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("")
22 changes: 22 additions & 0 deletions tests/config/loader/ini/test_ini_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

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:
Expand Down Expand Up @@ -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
7 changes: 0 additions & 7 deletions tests/config/test_main.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
import pytest

from tests.conftest import ToxIniCreator
from tox.config.loader.api import Override
from tox.config.loader.memory import MemoryLoader
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
Expand Down

0 comments on commit 6dbff12

Please sign in to comment.