diff options
author | Sachi King <nakato@nakato.io> | 2016-02-29 15:45:11 +1100 |
---|---|---|
committer | Sachi King <nakato@nakato.io> | 2016-02-29 15:45:11 +1100 |
commit | 26370885293487883eb60cbedcff76a0c6dc938e (patch) | |
tree | 120683355989037c70b42b608c47ec384fba45ef | |
parent | ab4346fba2a7f92f0a742df624c32ea3ff9767fd (diff) | |
download | tox-26370885293487883eb60cbedcff76a0c6dc938e.tar.gz |
Process minversion before all else
Reading the tox.ini config file and processing it is done as one task, yet
processing the minversion is done much later, as such if there is a bug fix
in a newer version or a change that makes the tox.ini file incompatable with
older versions tox will bail with a stack trace instead of a
"Your tox is too old" message.
This moves the version check as early as it can possibly be done, the very
first value read out of tox.ini is minversion and it is immedeiatly compared
to tox.__version__.
-rw-r--r-- | tests/test_config.py | 4 | ||||
-rw-r--r-- | tox/__init__.py | 6 | ||||
-rw-r--r-- | tox/config.py | 13 | ||||
-rw-r--r-- | tox/session.py | 28 |
4 files changed, 35 insertions, 16 deletions
diff --git a/tests/test_config.py b/tests/test_config.py index 372cd4f..c54add9 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1426,8 +1426,8 @@ class TestGlobalOptions: [tox] minversion = 3.0 """ - config = newconfig([], inisource) - assert config.minversion == "3.0" + with py.test.raises(tox.exception.MinVersionError): + config = newconfig([], inisource) def test_skip_missing_interpreters_true(self, tmpdir, newconfig, monkeypatch): inisource = """ diff --git a/tox/__init__.py b/tox/__init__.py index c17341d..6991c90 100644 --- a/tox/__init__.py +++ b/tox/__init__.py @@ -23,5 +23,11 @@ class exception: """ a directory did not exist. """ class MissingDependency(Error): """ a dependency could not be found or determined. """ + class MinVersionError(Error): + """ the installed tox version is lower than requested minversion. """ + + def __init__(self, message): + self.message = message + super(exception.MinVersionError, self).__init__(message) from tox.session import main as cmdline # noqa diff --git a/tox/config.py b/tox/config.py index 67454bc..78d070a 100644 --- a/tox/config.py +++ b/tox/config.py @@ -12,6 +12,7 @@ import pluggy import tox.interpreters from tox import hookspecs +from tox._verlib import NormalizedVersion import py @@ -664,8 +665,18 @@ class parseini: reader.addsubstitutions(toxinidir=config.toxinidir, homedir=config.homedir) - config.toxworkdir = reader.getpath("toxworkdir", "{toxinidir}/.tox") + # As older versions of tox may have bugs or incompatabilities that + # prevent parsing of tox.ini this must be the first thing checked. config.minversion = reader.getstring("minversion", None) + # Parse our compatability immediately + if config.minversion: + minversion = NormalizedVersion(self.config.minversion) + toxversion = NormalizedVersion(tox.__version__) + if toxversion < minversion: + raise tox.exception.MinVersionError( + "tox version is %s, required is at least %s" % ( + toxversion, minversion)) + config.toxworkdir = reader.getpath("toxworkdir", "{toxinidir}/.tox") if not config.option.skip_missing_interpreters: config.option.skip_missing_interpreters = \ diff --git a/tox/session.py b/tox/session.py index 93ef5d8..2ff4182 100644 --- a/tox/session.py +++ b/tox/session.py @@ -40,6 +40,10 @@ def main(args=None): raise SystemExit(retcode) except KeyboardInterrupt: raise SystemExit(2) + except tox.exception.MinVersionError as e: + r = Reporter(None) + r.error(e.message) + raise SystemExit(1) def show_help(config): @@ -233,6 +237,12 @@ class Reporter(object): self._reportedlines = [] # self.cumulated_time = 0.0 + def _get_verbosity(self): + if self.session: + return self.session.config.option.verbosity + else: + return 2 + def logpopen(self, popen, env): """ log information about the action.popen() created process. """ cmd = " ".join(map(str, popen.args)) @@ -257,11 +267,11 @@ class Reporter(object): self.tw.sep("_", "summary") def info(self, msg): - if self.session.config.option.verbosity >= 2: + if self._get_verbosity() >= 2: self.logline(msg) def using(self, msg): - if self.session.config.option.verbosity >= 1: + if self._get_verbosity() >= 1: self.logline("using %s" % (msg,), bold=True) def keyboard_interrupt(self): @@ -297,15 +307,15 @@ class Reporter(object): self.tw.line("%s" % msg, **opts) def verbosity0(self, msg, **opts): - if self.session.config.option.verbosity >= 0: + if self._get_verbosity() >= 0: self.logline("%s" % msg, **opts) def verbosity1(self, msg, **opts): - if self.session.config.option.verbosity >= 1: + if self._get_verbosity() >= 1: self.logline("%s" % msg, **opts) def verbosity2(self, msg, **opts): - if self.session.config.option.verbosity >= 2: + if self._get_verbosity() >= 2: self.logline("%s" % msg, **opts) # def log(self, msg): @@ -359,14 +369,6 @@ class Session: def runcommand(self): self.report.using("tox-%s from %s" % (tox.__version__, tox.__file__)) - if self.config.minversion: - minversion = NormalizedVersion(self.config.minversion) - toxversion = NormalizedVersion(tox.__version__) - if toxversion < minversion: - self.report.error( - "tox version is %s, required is at least %s" % ( - toxversion, minversion)) - raise SystemExit(1) if self.config.option.showconfig: self.showconfig() elif self.config.option.listenvs: |