diff --git a/docs/changelog/1464.bugfix.rst b/docs/changelog/1464.bugfix.rst new file mode 100644 index 0000000000..ab8bafe2df --- /dev/null +++ b/docs/changelog/1464.bugfix.rst @@ -0,0 +1 @@ +Fix ``platform`` support for ``install_command``. - by :user:`jayvdb` diff --git a/src/tox/config/__init__.py b/src/tox/config/__init__.py index 23f4e90a69..43f52e0fae 100644 --- a/src/tox/config/__init__.py +++ b/src/tox/config/__init__.py @@ -1673,6 +1673,13 @@ def getargv(self, name, default="", replace=True): def getargv_install_command(self, name, default="", replace=True): s = self.getstring(name, default, replace=False) + if not s: + # This occurs when factors are used, and a testenv doesnt have + # a factorised value for install_command, most commonly occurring + # if setting platform is also used. + # An empty value causes error install_command must contain '{packages}'. + s = default + if "{packages}" in s: s = s.replace("{packages}", r"\{packages\}") if "{opts}" in s: diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py index 994ccff595..3886db8a38 100644 --- a/tests/unit/config/test_config.py +++ b/tests/unit/config/test_config.py @@ -248,6 +248,97 @@ def test_config_parse_platform_with_factors(self, newconfig, plat): expected = {"win": "win32", "lin": "linux2", "osx": ""}.get(plat) assert platform == expected + def test_platform_install_command(self, newconfig, mocksession, monkeypatch): + # Expanded from docs/example/platform.html + config = newconfig( + [], + """ + [tox] + envlist = py{27,36}-{mylinux,mymacos,mywindows} + + [testenv] + platform = + mylinux: linux + mymacos: darwin + mywindows: win32 + + deps = + mylinux,mymacos: py==1.4.32 + mywindows: py==1.4.30 + + install_command = + mylinux: python -m pip install {packages} distro + mywindows: python -m pip install {packages} pywin32 + + commands= + mylinux: echo Linus + mymacos: echo Steve + mywindows: echo Bill + """, + ) + mocksession.config = config + assert len(config.envconfigs) == 6 + + monkeypatch.setattr(sys, "platform", "linux") + + venv = mocksession.getvenv("py27-mylinux") + assert venv.envconfig._reader.factors == {"py27", "mylinux"} + assert venv.matching_platform() + assert str(venv.envconfig.deps[0]) == "py==1.4.32" + assert venv.envconfig.install_command == [ + "python", + "-m", + "pip", + "install", + "{packages}", + "distro", + ] + assert venv.envconfig.commands[0] == ["echo", "Linus"] + + venv = mocksession.getvenv("py27-mymacos") + assert venv.envconfig._reader.factors == {"py27", "mymacos"} + assert not venv.matching_platform() + assert str(venv.envconfig.deps[0]) == "py==1.4.32" + assert venv.envconfig.install_command == [ + "python", + "-m", + "pip", + "install", + "{opts}", + "{packages}", + ] + assert venv.envconfig.commands[0] == ["echo", "Steve"] + + venv = mocksession.getvenv("py27-mywindows") + assert venv.envconfig._reader.factors == {"py27", "mywindows"} + assert not venv.matching_platform() + assert str(venv.envconfig.deps[0]) == "py==1.4.30" + assert venv.envconfig.install_command == [ + "python", + "-m", + "pip", + "install", + "{packages}", + "pywin32", + ] + assert venv.envconfig.commands[0] == ["echo", "Bill"] + + monkeypatch.undo() + + monkeypatch.setattr(sys, "platform", "darwin") + + venv = mocksession.getvenv("py27-mymacos") + assert venv.envconfig.install_command == [ + "python", + "-m", + "pip", + "install", + "{opts}", + "{packages}", + ] + + monkeypatch.undo() + class TestConfigPackage: def test_defaults(self, tmpdir, newconfig):