diff options
author | holger krekel <holger@merlinux.eu> | 2015-04-20 21:51:46 +0200 |
---|---|---|
committer | holger krekel <holger@merlinux.eu> | 2015-04-20 21:51:46 +0200 |
commit | 5460ace40a08b880ebce23cee9d62f2d4999790f (patch) | |
tree | 34fc4948097489ba6df6834665640dd85d127ea0 | |
parent | 406d45d0ef7a5c7baab6db6621dadc5c2c6822a3 (diff) | |
download | tox-5460ace40a08b880ebce23cee9d62f2d4999790f.tar.gz |
introduce new "platform" setting for tox
(XXX) consider using environment marker syntax
-rw-r--r-- | CHANGELOG | 8 | ||||
-rw-r--r-- | doc/config.txt | 6 | ||||
-rw-r--r-- | doc/example/basic.txt | 13 | ||||
-rw-r--r-- | tests/test_config.py | 46 | ||||
-rw-r--r-- | tests/test_z_cmdline.py | 18 | ||||
-rw-r--r-- | tox/_cmdline.py | 6 | ||||
-rw-r--r-- | tox/_config.py | 18 | ||||
-rw-r--r-- | tox/_venv.py | 4 | ||||
-rw-r--r-- | tox/interpreters.py | 6 |
9 files changed, 117 insertions, 8 deletions
@@ -1,7 +1,11 @@ -dev +2.0.dev1 ----------- -- +- introduce a way to specify on which platform a testenvironment is to + execute: the new per-environment "platform" setting allows to specify + a regular expression which is matched against sys.platform. + If platform is set and doesn't match the test environment the + test environment is ignored, no setup or tests are attempted. 1.9.2 diff --git a/doc/config.txt b/doc/config.txt index b5a717f..a7702ac 100644 --- a/doc/config.txt +++ b/doc/config.txt @@ -155,6 +155,12 @@ Complete list of settings that you can put into ``testenv*`` sections: (Experimentally introduced in 1.6.1) all installer commands are executed using the ``{toxinidir}`` as the current working directory. +.. confval:: platform=REGEX + + A testenv can define a new ``platform`` setting as a regular expression. + If a non-empty expression is defined and does not match against the + ``sys.platform`` string the test environment will be skipped. + .. confval:: setenv=MULTI-LINE-LIST .. versionadded:: 0.9 diff --git a/doc/example/basic.txt b/doc/example/basic.txt index e0dbece..b88b28c 100644 --- a/doc/example/basic.txt +++ b/doc/example/basic.txt @@ -46,6 +46,19 @@ Available "default" test environments names are:: However, you can also create your own test environment names, see some of the examples in :doc:`examples <../examples>`. +specifying a platform +----------------------------------------------- + +.. versionadded:: 2.0 + +If you want to specify which platform(s) your test environment +runs on you can set a platform regular expression like this:: + + platform = linux2|darwin + +If the expression does not match against ``sys.platform`` +the test environment will be skipped. + whitelisting non-virtualenv commands ----------------------------------------------- diff --git a/tests/test_config.py b/tests/test_config.py index f957771..758db48 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -7,6 +7,7 @@ import tox import tox._config from tox._config import * # noqa from tox._config import _split_env +from tox._venv import VirtualEnv class TestVenvConfig: @@ -18,6 +19,7 @@ class TestVenvConfig: assert config.toxworkdir.realpath() == tmpdir.join(".tox").realpath() assert config.envconfigs['py1'].basepython == sys.executable assert config.envconfigs['py1'].deps == [] + assert not config.envconfigs['py1'].platform def test_config_parsing_multienv(self, tmpdir, newconfig): config = newconfig([], """ @@ -98,6 +100,50 @@ class TestVenvConfig: assert parseini._is_same_dep('pkg_hello-world3==1.0', 'pkg_hello-world3<=2.0') assert not parseini._is_same_dep('pkg_hello-world3==1.0', 'otherpkg>=2.0') + +class TestConfigPlatform: + def test_config_parse_platform(self, newconfig): + config = newconfig([], """ + [testenv:py1] + platform = linux2 + """) + assert len(config.envconfigs) == 1 + assert config.envconfigs['py1'].platform == "linux2" + + def test_config_parse_platform_rex(self, newconfig, mocksession, monkeypatch): + config = newconfig([], """ + [testenv:py1] + platform = a123|b123 + """) + assert len(config.envconfigs) == 1 + envconfig = config.envconfigs['py1'] + venv = VirtualEnv(envconfig, session=mocksession) + assert not venv.matching_platform() + monkeypatch.setattr(sys, "platform", "a123") + assert venv.matching_platform() + monkeypatch.setattr(sys, "platform", "b123") + assert venv.matching_platform() + monkeypatch.undo() + assert not venv.matching_platform() + + + @pytest.mark.parametrize("plat", ["win", "lin", ]) + def test_config_parse_platform_with_factors(self, newconfig, plat, monkeypatch): + monkeypatch.setattr(sys, "platform", "win32") + config = newconfig([], """ + [tox] + envlist = py27-{win,lin,osx} + [testenv] + platform = + win: win32 + lin: linux2 + """) + assert len(config.envconfigs) == 3 + platform = config.envconfigs['py27-' + plat].platform + expected = {"win": "win32", "lin": "linux2"}.get(plat) + assert platform == expected + + class TestConfigPackage: def test_defaults(self, tmpdir, newconfig): config = newconfig([], "") diff --git a/tests/test_z_cmdline.py b/tests/test_z_cmdline.py index 0c145be..391bc4b 100644 --- a/tests/test_z_cmdline.py +++ b/tests/test_z_cmdline.py @@ -242,6 +242,24 @@ def test_unknown_interpreter(cmd, initproj): "*ERROR*InterpreterNotFound*xyz_unknown_interpreter*", ]) +def test_skip_platform_mismatch(cmd, initproj): + initproj("interp123-0.5", filedefs={ + 'tests': {'test_hello.py': "def test_hello(): pass"}, + 'tox.ini': ''' + [testenv] + changedir=tests + platform=x123 + ''' + }) + result = cmd.run("tox") + assert not result.ret + assert "platform mismatch" not in result.stdout.str() + result = cmd.run("tox", "-v") + assert not result.ret + result.stdout.fnmatch_lines([ + "*python*platform mismatch*" + ]) + def test_skip_unknown_interpreter(cmd, initproj): initproj("interp123-0.5", filedefs={ 'tests': {'test_hello.py': "def test_hello(): pass"}, diff --git a/tox/_cmdline.py b/tox/_cmdline.py index 14eb685..4037283 100644 --- a/tox/_cmdline.py +++ b/tox/_cmdline.py @@ -474,6 +474,9 @@ class Session: if self.config.option.sdistonly: return for venv in self.venvlist: + if not venv.matching_platform(): + venv.status = "platform mismatch" + continue # we simply omit non-matching platforms if self.setupenv(venv): if venv.envconfig.develop: self.developpkg(venv, self.config.setupdir) @@ -505,6 +508,9 @@ class Session: else: retcode = 1 self.report.error(msg) + elif status == "platform mismatch": + msg = " %s: %s" %(venv.envconfig.envname, str(status)) + self.report.verbosity1(msg) elif status and status != "skipped tests": msg = " %s: %s" %(venv.envconfig.envname, str(status)) self.report.error(msg) diff --git a/tox/_config.py b/tox/_config.py index 3d26686..b9ffc62 100644 --- a/tox/_config.py +++ b/tox/_config.py @@ -151,9 +151,11 @@ class Config(object): homedir = self.toxinidir # XXX good idea? return homedir + class VenvConfig: - def __init__(self, **kw): - self.__dict__.update(kw) + def __init__(self, envname, config): + self.envname = envname + self.config = config @property def envbindir(self): @@ -195,6 +197,8 @@ class VenvConfig: "python2.5 is not supported anymore, sorry") return info.executable + + testenvprefix = "testenv:" def get_homedir(): @@ -321,8 +325,7 @@ class parseini: return factors def _makeenvconfig(self, name, section, subs, config): - vc = VenvConfig(envname=name) - vc.config = config + vc = VenvConfig(config=config, envname=name) factors = set(name.split('-')) reader = IniReader(self._cfg, fallbacksections=["testenv"], factors=factors) @@ -381,6 +384,13 @@ class parseini: ixserver = None name = self._replace_forced_dep(name, config) vc.deps.append(DepConfig(name, ixserver)) + + platform = "" + for platform in reader.getlist(section, "platform"): + if platform.strip(): + break + vc.platform = platform + vc.distribute = reader.getbool(section, "distribute", False) vc.sitepackages = self.config.option.sitepackages or \ reader.getbool(section, "sitepackages", False) diff --git a/tox/_venv.py b/tox/_venv.py index 65eb73b..eff932d 100644 --- a/tox/_venv.py +++ b/tox/_venv.py @@ -1,5 +1,6 @@ from __future__ import with_statement import sys, os +import re import codecs import py import tox @@ -171,6 +172,9 @@ class VirtualEnv(object): def getsupportedinterpreter(self): return self.envconfig.getsupportedinterpreter() + def matching_platform(self): + return re.match(self.envconfig.platform, sys.platform) + def create(self, action=None): #if self.getcommandpath("activate").dirpath().check(): # return diff --git a/tox/interpreters.py b/tox/interpreters.py index 75318c5..241651f 100644 --- a/tox/interpreters.py +++ b/tox/interpreters.py @@ -90,11 +90,12 @@ class ExecFailed(Exception): class InterpreterInfo: runnable = True - def __init__(self, name, executable, version_info): + def __init__(self, name, executable, version_info, sysplatform): assert executable and version_info self.name = name self.executable = executable self.version_info = version_info + self.sysplatform = sysplatform def __str__(self): return "<executable at %s, version_info %s>" % ( @@ -163,7 +164,8 @@ else: def pyinfo(): import sys - return dict(version_info=tuple(sys.version_info)) + return dict(version_info=tuple(sys.version_info), + sysplatform=sys.platform) def sitepackagesdir(envdir): from distutils.sysconfig import get_python_lib |