summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthon van der Neut <anthon@mnt.org>2013-08-08 09:41:18 +0200
committerAnthon van der Neut <anthon@mnt.org>2013-08-08 09:41:18 +0200
commita30e658c78c5675a490b844c1acdc1c81d855a5b (patch)
treeb74513cc4cf82748f7a7e4f43b7a6e090b853f60
parent4d069b8ca180f3defd6dea9c69601cede9a636ca (diff)
downloadtox-a30e658c78c5675a490b844c1acdc1c81d855a5b.tar.gz
dash_e: fixes #109 and #111
Behaviour of -e has not changed, but can be set by passing True or False as a parameter multi_dash_e to tox/_config.py: prepare_parse() This parameter should come from a user specifyable default value for backwards compatibility. Default should preferable be True after that is implemented. _split_env() was factored out of class parseini to enable testing The issue #111: error on specifying same env twice ("tox -e py27,py27") fixed. Multiple specifications of the same environment result in multiple invocation (this could also be selectable in a configuration file)
-rw-r--r--tests/test_config.py37
-rw-r--r--tox/_config.py42
-rw-r--r--tox/_venv.py5
3 files changed, 80 insertions, 4 deletions
diff --git a/tests/test_config.py b/tests/test_config.py
index ce3044d..6870af1 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -7,6 +7,7 @@ from textwrap import dedent
import py
from tox._config import IniReader, CommandParser
from tox._config import parseconfig
+from tox._config import prepare_parse, _split_env
class TestVenvConfig:
def test_config_parsing_minimal(self, tmpdir, newconfig):
@@ -927,6 +928,42 @@ class TestCmdInvocation:
"*ERROR*tox.ini*not*found*",
])
+
+class TestArgumentParser:
+
+ def test_dash_e_silent1(self):
+ parser = prepare_parse('testpkg', None)
+ args = parser.parse_args('-e py26 -e py33'.split())
+ envlist = _split_env(args.env)
+ assert envlist == ['py33']
+
+ def test_dash_e_silent2(self):
+ parser = prepare_parse('testpkg', None)
+ args = parser.parse_args('-e py26,py33'.split())
+ envlist = _split_env(args.env)
+ assert envlist == ['py26', 'py33']
+
+ def test_dash_e_silent3(self):
+ parser = prepare_parse('testpkg', None)
+ args = parser.parse_args('-e py26,py26'.split())
+ envlist = _split_env(args.env)
+ assert envlist == ['py26', 'py26']
+
+ def test_dash_e_warn(self, capsys):
+ parser = prepare_parse('testpkg', False)
+ args = parser.parse_args('-e py26,py32 -e py33'.split())
+ envlist = _split_env(args.env)
+ out, err = capsys.readouterr()
+ assert 'WARNING: previous optional argument "-e py26' in out
+ assert envlist == ['py33']
+
+ def test_dash_e_combine(self):
+ parser = prepare_parse('testpkg', True)
+ args = parser.parse_args('-e py26,py25,py33 -e py33,py27'.split())
+ envlist = _split_env(args.env)
+ assert envlist == ['py26', 'py25', 'py33', 'py33', 'py27']
+
+
class TestCommandParser:
def test_command_parser_for_word(self):
diff --git a/tox/_config.py b/tox/_config.py
index 0d86f10..16cd288 100644
--- a/tox/_config.py
+++ b/tox/_config.py
@@ -66,7 +66,25 @@ class CountAction(argparse.Action):
else:
setattr(namespace, self.dest, 0)
-def prepare_parse(pkgname):
+class CheckSingleStoreAction(argparse.Action):
+ """issue a warning when the store action is called multiple times"""
+ def __call__(self, parser, namespace, values, option_string=None):
+ if getattr(namespace, self.dest, None) is not None:
+ py.builtin.print_(
+ 'WARNING: previous optional argument "' + option_string + " " +
+ getattr(namespace, self.dest) + '" overwritten by "' +
+ option_string + " " + values + '"')
+ setattr(namespace, self.dest, values)
+
+
+def prepare_parse(pkgname, multi_dash_e=None):
+ """setup ArgumentParser
+
+ multi_dash_e:
+ None -> silently ignore all but last -e pyXY option (old behaviour
+ False -> take last -e pyXY option, but warn on sys.stdout
+ True -> concatenate
+ """
parser = argparse.ArgumentParser(description=__doc__,)
#formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.pkgname = pkgname
@@ -83,7 +101,13 @@ def prepare_parse(pkgname):
parser.add_argument("-c", action="store", default="tox.ini",
dest="configfile",
help="use the specified config file name.")
- parser.add_argument("-e", action="store", dest="env",
+ if multi_dash_e is None:
+ dash_e_action = "store"
+ elif multi_dash_e is False:
+ dash_e_action = CheckSingleStoreAction
+ elif multi_dash_e is True:
+ dash_e_action = "append"
+ parser.add_argument("-e", action=dash_e_action, dest="env",
metavar="envlist",
help="work against specified environments (ALL selects all).")
parser.add_argument("--notest", action="store_true", dest="notest",
@@ -346,9 +370,21 @@ class parseini:
envlist = list(self.config.envconfigs)
envlist.sort()
else:
- envlist = env.split(",")
+ envlist = _split_env(env)
return envlist
+def _split_env(env):
+ """if handed a list, action="append" was used for -e """
+ envlist = []
+ if not isinstance(env, list):
+ env = [env]
+ for to_split in env:
+ for single_env in to_split.split(","):
+ # "remove True or", if not allowing multiple same runs, update tests
+ if True or single_env not in envlist:
+ envlist.append(single_env)
+ return envlist
+
class DepConfig:
def __init__(self, name, indexserver=None):
self.name = name
diff --git a/tox/_venv.py b/tox/_venv.py
index 362009a..0c87319 100644
--- a/tox/_venv.py
+++ b/tox/_venv.py
@@ -325,7 +325,10 @@ class VirtualEnv(object):
self.session.make_emptydir(self.envconfig.envtmpdir)
cwd = self.envconfig.changedir
for i, argv in enumerate(self.envconfig.commands):
- message = "commands[%s] | %s" % (i, ' '.join(argv))
+ # have to make strings as _pcall changes argv[0] to a local()
+ # happens if the same environment is invoked twice
+ message = "commands[%s] | %s" % (i, ' '.join(
+ [str(x) for x in argv]))
action.setactivity("runtests", message)
try:
self._pcall(argv, cwd=cwd, action=action, redirect=redirect)