Skip to content

Commit 8a25fa6

Browse files
authored
Support environment files and comments in setenv (#1668)
Signed-off-by: Bernat Gabor <[email protected]>
1 parent a790350 commit 8a25fa6

File tree

4 files changed

+66
-5
lines changed

4 files changed

+66
-5
lines changed

docs/changelog/1667.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Support for comments within ``setenv`` and environment files via the ``files|`` prefix. - by :user:`gaborbernat`

docs/config.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,14 @@ Complete list of settings that you can put into ``testenv*`` sections:
404404
setenv =
405405
PYTHONPATH = {env:PYTHONPATH}{:}{toxinidir}
406406
407+
.. versionadded:: 3.20
408+
409+
Support for comments. Lines starting with ``#`` are ignored.
410+
411+
Support for environment files. Lines starting with the ``file|`` contain path to a environment
412+
file to load. Rules within the environment file are the same as within the ``setenv``
413+
(same replacement and comment support).
414+
407415
.. conf:: passenv ^ SPACE-SEPARATED-GLOBNAMES
408416

409417
.. versionadded:: 2.0

src/tox/config/__init__.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,13 +1606,21 @@ def _getdict(self, value, default, sep, replace=True):
16061606
if value is None or not replace:
16071607
return default or {}
16081608

1609-
d = {}
1609+
env_values = {}
16101610
for line in value.split(sep):
16111611
if line.strip():
1612-
name, rest = line.split("=", 1)
1613-
d[name.strip()] = rest.strip()
1614-
1615-
return d
1612+
if line.startswith("#"): # comment lines are ignored
1613+
pass
1614+
elif line.startswith("file|"): # file markers contain paths to env files
1615+
file_path = line[5:].strip()
1616+
if os.path.exists(file_path):
1617+
with open(file_path, "rt") as file_handler:
1618+
content = file_handler.read()
1619+
env_values.update(self._getdict(content, "", sep, replace))
1620+
else:
1621+
name, value = line.split("=", 1)
1622+
env_values[name.strip()] = value.strip()
1623+
return env_values
16161624

16171625
def getfloat(self, name, default=None, replace=True):
16181626
s = self.getstring(name, default, replace=replace)

tests/unit/config/test_config.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import py
77
import pytest
88
from pluggy import PluginManager
9+
from six import PY2
910

1011
import tox
1112
from tox.config import (
@@ -2668,6 +2669,49 @@ def test_setenv_cross_section_mixed(self, monkeypatch, newconfig):
26682669
assert envconfig.setenv["NOT_TEST"] == "defaultvalue"
26692670
assert envconfig.setenv["y"] == "7"
26702671

2672+
def test_setenv_comment(self, newconfig):
2673+
"""Check that setenv ignores comments."""
2674+
envconfig = newconfig(
2675+
"""
2676+
[testenv]
2677+
setenv =
2678+
# MAGIC = yes
2679+
""",
2680+
).envconfigs["python"]
2681+
assert "MAGIC" not in envconfig.setenv
2682+
2683+
@pytest.mark.parametrize(
2684+
"content, has_magic",
2685+
[
2686+
(None, False),
2687+
("\n", False),
2688+
("#MAGIC = yes", False),
2689+
("MAGIC=yes", True),
2690+
("\nMAGIC = yes", True),
2691+
],
2692+
)
2693+
def test_setenv_env_file(self, newconfig, content, has_magic, tmp_path):
2694+
"""Check that setenv handles env files."""
2695+
env_path = tmp_path / ".env" if content else None
2696+
if content:
2697+
env_path.write_text(content.decode() if PY2 else content)
2698+
env_config = newconfig(
2699+
"""
2700+
[testenv]
2701+
setenv =
2702+
ALPHA = 1
2703+
file| {}
2704+
""".format(
2705+
env_path,
2706+
),
2707+
).envconfigs["python"]
2708+
envs = env_config.setenv.definitions
2709+
assert envs["ALPHA"] == "1"
2710+
if has_magic:
2711+
assert envs["MAGIC"] == "yes"
2712+
else:
2713+
assert "MAGIC" not in envs
2714+
26712715

26722716
class TestIndexServer:
26732717
def test_indexserver(self, newconfig):

0 commit comments

Comments
 (0)