summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernát Gábor <bgabor8@bloomberg.net>2020-09-01 16:48:10 +0100
committerGitHub <noreply@github.com>2020-09-01 16:48:10 +0100
commit8a25fa6bf3e625c0b47659e1652ab55a79d4d1e8 (patch)
tree392358e52fa74e76f07b5d3dd64a14eea567c375
parenta7903508fa07068b327e15cfdbf8ea330ab78765 (diff)
downloadtox-git-8a25fa6bf3e625c0b47659e1652ab55a79d4d1e8.tar.gz
Support environment files and comments in setenv (#1668)
Signed-off-by: Bernat Gabor <bgabor8@bloomberg.net>
-rw-r--r--docs/changelog/1667.feature.rst1
-rw-r--r--docs/config.rst8
-rw-r--r--src/tox/config/__init__.py18
-rw-r--r--tests/unit/config/test_config.py44
4 files changed, 66 insertions, 5 deletions
diff --git a/docs/changelog/1667.feature.rst b/docs/changelog/1667.feature.rst
new file mode 100644
index 00000000..1a315050
--- /dev/null
+++ b/docs/changelog/1667.feature.rst
@@ -0,0 +1 @@
+Support for comments within ``setenv`` and environment files via the ``files|`` prefix. - by :user:`gaborbernat`
diff --git a/docs/config.rst b/docs/config.rst
index d5fdc2b0..d2d89b71 100644
--- a/docs/config.rst
+++ b/docs/config.rst
@@ -404,6 +404,14 @@ Complete list of settings that you can put into ``testenv*`` sections:
setenv =
PYTHONPATH = {env:PYTHONPATH}{:}{toxinidir}
+ .. versionadded:: 3.20
+
+ Support for comments. Lines starting with ``#`` are ignored.
+
+ Support for environment files. Lines starting with the ``file|`` contain path to a environment
+ file to load. Rules within the environment file are the same as within the ``setenv``
+ (same replacement and comment support).
+
.. conf:: passenv ^ SPACE-SEPARATED-GLOBNAMES
.. versionadded:: 2.0
diff --git a/src/tox/config/__init__.py b/src/tox/config/__init__.py
index b1032f8b..197d14c3 100644
--- a/src/tox/config/__init__.py
+++ b/src/tox/config/__init__.py
@@ -1606,13 +1606,21 @@ class SectionReader:
if value is None or not replace:
return default or {}
- d = {}
+ env_values = {}
for line in value.split(sep):
if line.strip():
- name, rest = line.split("=", 1)
- d[name.strip()] = rest.strip()
-
- return d
+ if line.startswith("#"): # comment lines are ignored
+ pass
+ elif line.startswith("file|"): # file markers contain paths to env files
+ file_path = line[5:].strip()
+ if os.path.exists(file_path):
+ with open(file_path, "rt") as file_handler:
+ content = file_handler.read()
+ env_values.update(self._getdict(content, "", sep, replace))
+ else:
+ name, value = line.split("=", 1)
+ env_values[name.strip()] = value.strip()
+ return env_values
def getfloat(self, name, default=None, replace=True):
s = self.getstring(name, default, replace=replace)
diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py
index e89c27a4..7eb2ffbc 100644
--- a/tests/unit/config/test_config.py
+++ b/tests/unit/config/test_config.py
@@ -6,6 +6,7 @@ from textwrap import dedent
import py
import pytest
from pluggy import PluginManager
+from six import PY2
import tox
from tox.config import (
@@ -2668,6 +2669,49 @@ class TestSetenv:
assert envconfig.setenv["NOT_TEST"] == "defaultvalue"
assert envconfig.setenv["y"] == "7"
+ def test_setenv_comment(self, newconfig):
+ """Check that setenv ignores comments."""
+ envconfig = newconfig(
+ """
+ [testenv]
+ setenv =
+ # MAGIC = yes
+ """,
+ ).envconfigs["python"]
+ assert "MAGIC" not in envconfig.setenv
+
+ @pytest.mark.parametrize(
+ "content, has_magic",
+ [
+ (None, False),
+ ("\n", False),
+ ("#MAGIC = yes", False),
+ ("MAGIC=yes", True),
+ ("\nMAGIC = yes", True),
+ ],
+ )
+ def test_setenv_env_file(self, newconfig, content, has_magic, tmp_path):
+ """Check that setenv handles env files."""
+ env_path = tmp_path / ".env" if content else None
+ if content:
+ env_path.write_text(content.decode() if PY2 else content)
+ env_config = newconfig(
+ """
+ [testenv]
+ setenv =
+ ALPHA = 1
+ file| {}
+ """.format(
+ env_path,
+ ),
+ ).envconfigs["python"]
+ envs = env_config.setenv.definitions
+ assert envs["ALPHA"] == "1"
+ if has_magic:
+ assert envs["MAGIC"] == "yes"
+ else:
+ assert "MAGIC" not in envs
+
class TestIndexServer:
def test_indexserver(self, newconfig):