parent
328c6708c1
commit
1c269861a6
@ -1,93 +0,0 @@
|
|||||||
# HG changeset patch
|
|
||||||
# User Clark Boylan <clark.boylan@gmail.com>
|
|
||||||
# Date 1391830704 28800
|
|
||||||
# Node ID 62fe57a8fd3f8f44be8957e59846387d2f505227
|
|
||||||
# Parent b0360a54ab368ef428c7f83601ba6b64f6fec64f
|
|
||||||
Fix command expansion and parsing.
|
|
||||||
|
|
||||||
Tox testenv commands are parsed to expand variable substitutions and
|
|
||||||
construct the argv list that will be passed to exec. Prior to this
|
|
||||||
commit this parsing ate quotes surrounding variables and treated
|
|
||||||
multiword variables as single argv items. Neither behavior was correct.
|
|
||||||
To fix this create the expanded command before handing it off to shlex
|
|
||||||
to do the tokenization of the argv list. Doing the parsing in this
|
|
||||||
order ensures it is correct.
|
|
||||||
|
|
||||||
diff --git a/tests/test_config.py b/tests/test_config.py
|
|
||||||
--- a/tests/test_config.py
|
|
||||||
+++ b/tests/test_config.py
|
|
||||||
@@ -278,7 +278,7 @@
|
|
||||||
# "reader.getargvlist('section', 'key1')")
|
|
||||||
assert reader.getargvlist('section', 'key1') == []
|
|
||||||
x = reader.getargvlist("section", "key2")
|
|
||||||
- assert x == [["cmd1", "with space", "grr"],
|
|
||||||
+ assert x == [["cmd1", "with", "space", "grr"],
|
|
||||||
["cmd2", "grr"]]
|
|
||||||
|
|
||||||
def test_argvlist_windows_escaping(self, tmpdir, newconfig):
|
|
||||||
@@ -304,7 +304,7 @@
|
|
||||||
# "reader.getargvlist('section', 'key1')")
|
|
||||||
assert reader.getargvlist('section', 'key1') == []
|
|
||||||
x = reader.getargvlist("section", "key2")
|
|
||||||
- assert x == [["cmd1", "with space", "grr"]]
|
|
||||||
+ assert x == [["cmd1", "with", "space", "grr"]]
|
|
||||||
|
|
||||||
|
|
||||||
def test_argvlist_quoting_in_command(self, tmpdir, newconfig):
|
|
||||||
diff --git a/tox/_config.py b/tox/_config.py
|
|
||||||
--- a/tox/_config.py
|
|
||||||
+++ b/tox/_config.py
|
|
||||||
@@ -527,30 +527,35 @@
|
|
||||||
def _processcommand(self, command):
|
|
||||||
posargs = getattr(self, "posargs", None)
|
|
||||||
|
|
||||||
- # special treat posargs which might contain multiple arguments
|
|
||||||
- # in their defaults
|
|
||||||
+ # Iterate through each word of the command substituting as
|
|
||||||
+ # appropriate to construct the new command string. This
|
|
||||||
+ # string is then broken up into exec argv components using
|
|
||||||
+ # shlex.
|
|
||||||
newcommand = ""
|
|
||||||
for word in CommandParser(command).words():
|
|
||||||
- if word.startswith("{posargs:") and word.endswith("}"):
|
|
||||||
+ if word == "{posargs}" or word == "[]":
|
|
||||||
if posargs:
|
|
||||||
- word = "{posargs}"
|
|
||||||
+ newcommand += " ".join(posargs)
|
|
||||||
+ continue
|
|
||||||
+ elif word.startswith("{posargs:") and word.endswith("}"):
|
|
||||||
+ if posargs:
|
|
||||||
+ newcommand += " ".join(posargs)
|
|
||||||
+ continue
|
|
||||||
else:
|
|
||||||
word = word[9:-1]
|
|
||||||
- newcommand += word
|
|
||||||
+ new_arg = ""
|
|
||||||
+ new_word = self._replace(word)
|
|
||||||
+ new_word = self._replace(new_word)
|
|
||||||
+ new_arg += new_word
|
|
||||||
+ newcommand += new_arg
|
|
||||||
|
|
||||||
- # now we can properly parse the command
|
|
||||||
- argv = []
|
|
||||||
- for arg in shlex.split(newcommand):
|
|
||||||
- if arg in ('[]', "{posargs}"):
|
|
||||||
- if posargs:
|
|
||||||
- argv.extend(posargs)
|
|
||||||
- continue
|
|
||||||
- new_arg = ""
|
|
||||||
- for word in CommandParser(arg).words():
|
|
||||||
- new_word = self._replace(word)
|
|
||||||
- new_word = self._replace(new_word)
|
|
||||||
- new_arg += new_word
|
|
||||||
- argv.append(new_arg)
|
|
||||||
+ # Construct shlex object that will not escape any values,
|
|
||||||
+ # use all values as is in argv.
|
|
||||||
+ shlexer = shlex.shlex(newcommand, posix=True)
|
|
||||||
+ shlexer.whitespace_split = True
|
|
||||||
+ shlexer.escape = ''
|
|
||||||
+ shlexer.commenters = ''
|
|
||||||
+ argv = list(shlexer)
|
|
||||||
return argv
|
|
||||||
|
|
||||||
def getargv(self, section, name, default=None, replace=True):
|
|
Loading…
Reference in new issue