From 18eaae9e54363465631b5c8bab1aa702998939f5 Mon Sep 17 00:00:00 2001 From: Julian Krause Date: Thu, 22 Jan 2015 14:52:53 -0800 Subject: Fix issue11: Add a skip_install option on a per-environment level. --- doc/config.txt | 10 ++++++++++ tox/_cmdline.py | 2 +- tox/_config.py | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/config.txt b/doc/config.txt index 6ffd02b..a29c5fd 100644 --- a/doc/config.txt +++ b/doc/config.txt @@ -252,6 +252,16 @@ Complete list of settings that you can put into ``testenv*`` sections: **default**: ``False`` +.. confval:: skip_install=BOOL + + .. versionadded:: 1.9 + + Do not install the current package. This can be used when you need the + virtualenv management but do not want to install the current package + into that environment. + + **default**: ``False`` + Substitutions ------------- diff --git a/tox/_cmdline.py b/tox/_cmdline.py index 0df2f17..bab803e 100644 --- a/tox/_cmdline.py +++ b/tox/_cmdline.py @@ -448,7 +448,7 @@ class Session: if self.setupenv(venv): if venv.envconfig.develop: self.developpkg(venv, self.config.setupdir) - elif self.config.skipsdist: + elif self.config.skipsdist or venv.envconfig.skip_install: self.finishvenv(venv) else: self.installpkg(venv, sdist_path) diff --git a/tox/_config.py b/tox/_config.py index 41f02ec..5f89ec4 100644 --- a/tox/_config.py +++ b/tox/_config.py @@ -395,6 +395,8 @@ class parseini: vc.pip_pre = config.option.pre or reader.getbool( section, "pip_pre", False) + vc.skip_install = reader.getbool(section, "skip_install", False) + return vc def _getenvdata(self, reader, toxsection): -- cgit v1.2.1 From 1c6153be18ae650fd5b869f8fe5502ccc28c8ece Mon Sep 17 00:00:00 2001 From: Florian Schulze Date: Thu, 29 Jan 2015 13:59:26 +0100 Subject: Add ``--result-tee`` option to echo output captured for the json result to stdout. --- tox/_cmdline.py | 29 +++++++++++++++++++++++++---- tox/_config.py | 3 +++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/tox/_cmdline.py b/tox/_cmdline.py index 24e47ba..9e8ff9f 100644 --- a/tox/_cmdline.py +++ b/tox/_cmdline.py @@ -11,6 +11,7 @@ import py import os import sys import subprocess +import time from tox._verlib import NormalizedVersion, IrrationalVersionError from tox._venv import VirtualEnv from tox._config import parseconfig @@ -80,20 +81,24 @@ class Action(object): def popen(self, args, cwd=None, env=None, redirect=True, returnout=False): logged_command = "%s$ %s" %(cwd, " ".join(map(str, args))) - f = outpath = None + stdout = outpath = None resultjson = self.session.config.option.resultjson + resulttee = self.session.config.option.resulttee if resultjson or redirect: f = self._initlogpath(self.id) f.write("actionid=%s\nmsg=%s\ncmdargs=%r\nenv=%s\n" %( self.id, self.msg, args, env)) f.flush() self.popen_outpath = outpath = py.path.local(f.name) + stdout = f elif returnout: - f = subprocess.PIPE + stdout = subprocess.PIPE + if resultjson and resulttee: + stdout = subprocess.PIPE if cwd is None: # XXX cwd = self.session.config.cwd cwd = py.path.local() - popen = self._popen(args, cwd, env=env, stdout=f, stderr=STDOUT) + popen = self._popen(args, cwd, env=env, stdout=stdout, stderr=STDOUT) popen.outpath = outpath popen.args = [str(x) for x in args] popen.cwd = cwd @@ -102,7 +107,23 @@ class Action(object): try: self.report.logpopen(popen, env=env) try: - out, err = popen.communicate() + if resultjson and resulttee: + assert popen.stderr is None # prevent deadlock + out = None + last_time = time.time() + while 1: + data = popen.stdout.read(1) + if data: + sys.stdout.write(data) + if '\n' in data or (time.time() - last_time) > 5: + sys.stdout.flush() + last_time = time.time() + f.write(data) + elif popen.poll() is not None: + popen.stdout.close() + break + else: + out, err = popen.communicate() except KeyboardInterrupt: self.report.keyboard_interrupt() popen.wait() diff --git a/tox/_config.py b/tox/_config.py index d692b6f..0529820 100644 --- a/tox/_config.py +++ b/tox/_config.py @@ -116,6 +116,9 @@ def prepare_parse(pkgname): "all commands and results involved. This will turn off " "pass-through output from running test commands which is " "instead captured into the json result file.") + parser.add_argument("--result-tee", action="store_true", + dest="resulttee", + help="echo output of --result-json to stdout while it is captured.") parser.add_argument("args", nargs="*", help="additional arguments available to command positional substitution") return parser -- cgit v1.2.1 From 075767c6a4ec234960269a420b48bf31d5c407f9 Mon Sep 17 00:00:00 2001 From: Florian Schulze Date: Thu, 5 Feb 2015 14:21:44 +0100 Subject: Always tee the output to stdout when --report-json is used. --- tox/_cmdline.py | 16 ++++++++++------ tox/_config.py | 3 --- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tox/_cmdline.py b/tox/_cmdline.py index 1c25f48..c9e1aa9 100644 --- a/tox/_cmdline.py +++ b/tox/_cmdline.py @@ -80,21 +80,20 @@ class Action(object): return f def popen(self, args, cwd=None, env=None, redirect=True, returnout=False): - logged_command = "%s$ %s" %(cwd, " ".join(map(str, args))) stdout = outpath = None resultjson = self.session.config.option.resultjson - resulttee = self.session.config.option.resulttee if resultjson or redirect: f = self._initlogpath(self.id) f.write("actionid=%s\nmsg=%s\ncmdargs=%r\nenv=%s\n" %( self.id, self.msg, args, env)) f.flush() self.popen_outpath = outpath = py.path.local(f.name) - stdout = f + if resultjson: + stdout = subprocess.PIPE + else: + stdout = f elif returnout: stdout = subprocess.PIPE - if resultjson and resulttee: - stdout = subprocess.PIPE if cwd is None: # XXX cwd = self.session.config.cwd cwd = py.path.local() @@ -113,15 +112,20 @@ class Action(object): try: self.report.logpopen(popen, env=env) try: - if resultjson and resulttee: + if resultjson and not redirect: assert popen.stderr is None # prevent deadlock out = None last_time = time.time() while 1: + # we have to read one byte at a time, otherwise there + # might be no output for a long time with slow tests data = popen.stdout.read(1) if data: sys.stdout.write(data) if '\n' in data or (time.time() - last_time) > 5: + # we flush on newlines or after 5 seconds to + # provide quick enough feedback to the user + # when printing a dot per test sys.stdout.flush() last_time = time.time() f.write(data) diff --git a/tox/_config.py b/tox/_config.py index 6a1f2c6..41f02ec 100644 --- a/tox/_config.py +++ b/tox/_config.py @@ -117,9 +117,6 @@ def prepare_parse(pkgname): "all commands and results involved. This will turn off " "pass-through output from running test commands which is " "instead captured into the json result file.") - parser.add_argument("--result-tee", action="store_true", - dest="resulttee", - help="echo output of --result-json to stdout while it is captured.") # We choose 1 to 4294967295 because it is the range of PYTHONHASHSEED. parser.add_argument("--hashseed", action="store", metavar="SEED", default=None, -- cgit v1.2.1 From 4d1676485aa7be57f137ca97c6c0e197589ae1b9 Mon Sep 17 00:00:00 2001 From: Florian Schulze Date: Thu, 5 Feb 2015 14:24:39 +0100 Subject: Add changelog entry. --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 55ab8ae..249eb8e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,7 @@ - refine determination if we run from Jenkins, thanks Borge Lanes. +- echo output to stdout when ``--report-json`` is used 1.8.1 ----------- -- cgit v1.2.1 From aa7c071cfde63f9d1da4c0409d77305f970e6924 Mon Sep 17 00:00:00 2001 From: Mark Hirota Date: Mon, 9 Feb 2015 16:30:00 -0800 Subject: Fix issue #124 --- CHANGELOG | 3 +++ CONTRIBUTORS | 1 + tox/_cmdline.py | 4 ++-- tox/_venv.py | 17 ++++++++++++++--- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 249eb8e..1b19722 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,9 @@ - echo output to stdout when ``--report-json`` is used +- fix issue124: ignore command exit codes; when a command has a "-" prefix, + tox will ignore the exit code of that command + 1.8.1 ----------- diff --git a/CONTRIBUTORS b/CONTRIBUTORS index ef8576d..1f1a6ad 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -29,3 +29,4 @@ Morgan Fainberg Marc Schlaich Clark Boylan Eugene Yunak +Mark Hirota diff --git a/tox/_cmdline.py b/tox/_cmdline.py index c9e1aa9..d7010da 100644 --- a/tox/_cmdline.py +++ b/tox/_cmdline.py @@ -79,7 +79,7 @@ class Action(object): f.flush() return f - def popen(self, args, cwd=None, env=None, redirect=True, returnout=False): + def popen(self, args, cwd=None, env=None, redirect=True, returnout=False, ignore_ret=False): stdout = outpath = None resultjson = self.session.config.option.resultjson if resultjson or redirect: @@ -141,7 +141,7 @@ class Action(object): ret = popen.wait() finally: self._popenlist.remove(popen) - if ret: + if ret and not ignore_ret: invoked = " ".join(map(str, popen.args)) if outpath: self.report.error("invocation failed (exit code %d), logfile: %s" % diff --git a/tox/_venv.py b/tox/_venv.py index 937a881..6bcb88a 100644 --- a/tox/_venv.py +++ b/tox/_venv.py @@ -345,8 +345,19 @@ class VirtualEnv(object): message = "commands[%s] | %s" % (i, ' '.join( [str(x) for x in argv])) action.setactivity("runtests", message) + # check to see if we need to ignore the return code + # if so, we need to alter the command line arguments + if argv[0].startswith("-"): + ignore_ret = True + if argv[0] == "-": + del argv[0] + else: + argv[0] = argv[0].lstrip("-") + else: + ignore_ret = False + try: - self._pcall(argv, cwd=cwd, action=action, redirect=redirect) + self._pcall(argv, cwd=cwd, action=action, redirect=redirect, ignore_ret=ignore_ret) except tox.exception.InvocationError: val = sys.exc_info()[1] self.session.report.error(str(val)) @@ -357,7 +368,7 @@ class VirtualEnv(object): raise def _pcall(self, args, venv=True, cwd=None, extraenv={}, - action=None, redirect=True): + action=None, redirect=True, ignore_ret=False): for name in ("VIRTUALENV_PYTHON", "PYTHONDONTWRITEBYTECODE"): try: del os.environ[name] @@ -369,7 +380,7 @@ class VirtualEnv(object): try: args[0] = self.getcommandpath(args[0], venv, cwd) env = self._getenv(extraenv) - return action.popen(args, cwd=cwd, env=env, redirect=redirect) + return action.popen(args, cwd=cwd, env=env, redirect=redirect, ignore_ret=ignore_ret) finally: os.environ['PATH'] = old -- cgit v1.2.1 From 655ecc51e9804d98814841f15fdbadae290c97d5 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Wed, 11 Feb 2015 14:41:32 +0100 Subject: fix issue11: add a ``skip_install`` per-testenv setting which prevents the installation of a package. Thanks Julian Krause. --- CHANGELOG | 3 +++ CONTRIBUTORS | 1 + 2 files changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 249eb8e..862c640 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,9 @@ - echo output to stdout when ``--report-json`` is used +- fix issue11: add a ``skip_install`` per-testenv setting which + prevents the installation of a package. Thanks Julian Krause. + 1.8.1 ----------- diff --git a/CONTRIBUTORS b/CONTRIBUTORS index ef8576d..09cd835 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -24,6 +24,7 @@ Matt Good Mattieu Agopian Asmund Grammeltwedt Ionel Maries Cristian +Julian Krause Alexandre Conrad Morgan Fainberg Marc Schlaich -- cgit v1.2.1 From bbb20864027197f81b901850cac6787e47c08803 Mon Sep 17 00:00:00 2001 From: Mark Hirota Date: Wed, 11 Feb 2015 11:11:54 -0800 Subject: Update doc files for issue #124 fix --- doc/config.txt | 2 ++ doc/example/basic.txt | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/doc/config.txt b/doc/config.txt index 6ffd02b..b2d9024 100644 --- a/doc/config.txt +++ b/doc/config.txt @@ -86,6 +86,8 @@ Complete list of settings that you can put into ``testenv*`` sections: will be appended (and may contain another ``\`` character ...). For eventually performing a call to ``subprocess.Popen(args, ...)`` ``args`` are determined by splitting the whole command by whitespace. + Similar to ``make`` recipe lines, any command with a leading ``-`` + will ignore the exit code. .. confval:: install_command=ARGV diff --git a/doc/example/basic.txt b/doc/example/basic.txt index 49baeee..916990e 100644 --- a/doc/example/basic.txt +++ b/doc/example/basic.txt @@ -244,3 +244,19 @@ using the ``--tox-args`` or ``-a`` command-line options. For example:: python setup.py test -a "-epy27" is equivalent to running ``tox -epy27``. + +Ignoring a command exit code +---------------------------- + +In some cases, you may want to ignore a command exit code. For example:: + + [testenv:py27] + commands = coverage erase + {envbindir}/python setup.py develop + coverage run -p setup.py test + coverage combine + - coverage html + {envbindir}/flake8 loads + +By using the ``-`` prefix, similar to a ``make`` recipe line, you can ignore +the exit code for that command. -- cgit v1.2.1 From 0f3bde02f072c7b0277ec932543086ea8d4fdf4d Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Mon, 16 Feb 2015 10:23:31 -0500 Subject: Add support for 'py35' -> 'python3.5'. --- tox/_config.py | 2 +- tox/_quickstart.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tox/_config.py b/tox/_config.py index 5f89ec4..55f70bf 100644 --- a/tox/_config.py +++ b/tox/_config.py @@ -18,7 +18,7 @@ iswin32 = sys.platform == "win32" default_factors = {'jython': 'jython', 'pypy': 'pypy', 'pypy3': 'pypy3', 'py': sys.executable} -for version in '24,25,26,27,30,31,32,33,34'.split(','): +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): diff --git a/tox/_quickstart.py b/tox/_quickstart.py index 098eb61..e7c4f03 100644 --- a/tox/_quickstart.py +++ b/tox/_quickstart.py @@ -56,7 +56,7 @@ except NameError: term_input = input -all_envs = ['py26', 'py27', 'py32', 'py33', 'py34', 'pypy', 'jython'] +all_envs = ['py26', 'py27', 'py32', 'py33', 'py34', 'py35', 'pypy', 'jython'] PROMPT_PREFIX = '> ' -- cgit v1.2.1