diff options
author | Vladimir Vitvitskiy <vladimir.vitvitskiy@hp.com> | 2015-04-21 21:47:13 +0300 |
---|---|---|
committer | Vladimir Vitvitskiy <vladimir.vitvitskiy@hp.com> | 2015-04-21 21:47:13 +0300 |
commit | da1db21b56a15dabb8e1f6505f5eb3c808013047 (patch) | |
tree | 125718c5812f45fdc0caef2bcb52eedec5ac487e /tox | |
parent | 8b4f65e405e9881cfcaf3014b1abbdc832c6da7b (diff) | |
download | tox-da1db21b56a15dabb8e1f6505f5eb3c808013047.tar.gz |
fix issue #120: section subs in commands doesn't work
Problem
-----------
Section substitution for `commands` doesn't work correctly.
Acceptance
----------------
When section substitution is specified as a single form of `commands` declaration
it is replaced with parsed list of commands.
When section substation happens as part of the other command line declaration - preserve original behaviour.
Changes
------------
- fixes for the issue
- some PEP8 violations are fixed
- tests for the substation in `commands` are grouped
Diffstat (limited to 'tox')
-rw-r--r-- | tox/_config.py | 59 |
1 files changed, 48 insertions, 11 deletions
diff --git a/tox/_config.py b/tox/_config.py index 80d61bb..9d054a0 100644 --- a/tox/_config.py +++ b/tox/_config.py @@ -22,7 +22,14 @@ default_factors = {'jython': 'jython', 'pypy': 'pypy', 'pypy3': 'pypy3', for version in '24,25,26,27,30,31,32,33,34,35'.split(','): default_factors['py' + version] = 'python%s.%s' % tuple(version) + def parseconfig(args=None, pkg=None): + """ + :param list[str] args: Optional list of arguments. + :type pkg: str + :rtype: :class:`Config` + :raise SystemExit: toxinit file is not found + """ if args is None: args = sys.argv[1:] parser = prepare_parse(pkg) @@ -509,16 +516,23 @@ class DepConfig: def __str__(self): if self.indexserver: if self.indexserver.name == "default": - return self.name - return ":%s:%s" %(self.indexserver.name, self.name) + return self.name + return ":%s:%s" % (self.indexserver.name, self.name) return str(self.name) __repr__ = __str__ + class IndexServerConfig: def __init__(self, name, url=None): self.name = name self.url = url + +#: Check value matches substitution form +#: of referencing value from other section. E.g. {[base]commands} +is_section_substitution = re.compile("{\[[^{}\s]+\]\S+?}").match + + RE_ITEM_REF = re.compile( r''' (?<!\\)[{] @@ -570,13 +584,31 @@ class IniReader: return value def getargvlist(self, section, name): - s = self.getdefault(section, name, '', replace=False) - #if s is None: - # raise tox.exception.ConfigError( - # "no command list %r defined in section [%s]" %(name, section)) - commandlist = [] + """Get arguments for every parsed command. + + :param str section: Section name in the configuration. + :param str name: Key name in a section. + :rtype: list[list[str]] + :raise :class:`tox.exception.ConfigError`: + line-continuation ends nowhere while resolving for specified section + """ + content = self.getdefault(section, name, '', replace=False) + return self._parse_commands(section, name, content) + + def _parse_commands(self, section, name, content): + """Parse commands from key content in specified section. + + :param str section: Section name in the configuration. + :param str name: Key name in a section. + :param str content: Content stored by key. + + :rtype: list[list[str]] + :raise :class:`tox.exception.ConfigError`: + line-continuation ends nowhere while resolving for specified section + """ + commands = [] current_command = "" - for line in s.split("\n"): + for line in content.splitlines(): line = line.rstrip() i = line.find("#") if i != -1: @@ -587,14 +619,19 @@ class IniReader: current_command += " " + line[:-1] continue current_command += line - commandlist.append(self._processcommand(current_command)) + + if is_section_substitution(current_command): + replaced = self._replace(current_command) + commands.extend(self._parse_commands(section, name, replaced)) + else: + commands.append(self._processcommand(current_command)) current_command = "" else: if current_command: raise tox.exception.ConfigError( - "line-continuation for [%s] %s ends nowhere" % + "line-continuation ends nowhere while resolving for [%s] %s" % (section, name)) - return commandlist + return commands def _processcommand(self, command): posargs = getattr(self, "posargs", None) |