9 new commits in tox: https://bitbucket.org/hpk42/tox/commits/14d597656e37/ Changeset: 14d597656e37 User: mordred Date: 2013-07-10 22:22:16 Summary: Add option to skip sdist step.
First change in a sequence to allow for customization of operational steps. The sdist creation is current unconditional, which for some projects makes running tests unreasonably slow. For instance, OpenStack would prefer to just have python setup.py develop run - but we'd like to put in the support in a flexible way that will allow people to express the pipeline needs of their project. Affected #: 4 files diff -r 63d37ba9cc8babe926e45f9e8294841148b0451b -r 14d597656e378d1abd515bf90076704824b0f9fe doc/config.txt --- a/doc/config.txt +++ b/doc/config.txt @@ -21,6 +21,7 @@ distdir=path # defaults to {toxworkdir}/dist distshare=path # defaults to {homedir}/.tox/distshare envlist=ENVLIST # defaults to the list of all environments + skipsdist=BOOL # defaults to false ``tox`` autodetects if it is running in a Jenkins_ context diff -r 63d37ba9cc8babe926e45f9e8294841148b0451b -r 14d597656e378d1abd515bf90076704824b0f9fe tests/test_z_cmdline.py --- a/tests/test_z_cmdline.py +++ b/tests/test_z_cmdline.py @@ -252,6 +252,23 @@ "*ERROR*unknown*environment*qpwoei*", ]) +def test_skip_sdist(cmd, initproj): + initproj("pkg123-0.7", filedefs={ + 'tests': {'test_hello.py': "def test_hello(): pass"}, + 'setup.py': """ + syntax error + """ + , + 'tox.ini': ''' + [tox] + skipsdist=True + [testenv] + commands=echo done + ''' + }) + result = cmd.run("tox", ) + assert result.ret == 0 + def test_sdist_fails(cmd, initproj): initproj("pkg123-0.7", filedefs={ 'tests': {'test_hello.py': "def test_hello(): pass"}, diff -r 63d37ba9cc8babe926e45f9e8294841148b0451b -r 14d597656e378d1abd515bf90076704824b0f9fe tox/_cmdline.py --- a/tox/_cmdline.py +++ b/tox/_cmdline.py @@ -362,19 +362,24 @@ return sdist_path def subcommand_test(self): - sdist_path = self.sdist() - if not sdist_path: - return 2 + if self.config.skipsdist: + self.report.info("skipping sdist step") + sdist_path = None + else: + sdist_path = self.sdist() + if not sdist_path: + return 2 if self.config.option.sdistonly: return for venv in self.venvlist: if self.setupenv(venv): - self.installpkg(venv, sdist_path) - self.runtestenv(venv, sdist_path) + if not self.config.skipsdist: + self.installpkg(venv, sdist_path) + self.runtestenv(venv) retcode = self._summary() return retcode - def runtestenv(self, venv, sdist_path, redirect=False): + def runtestenv(self, venv, redirect=False): if not self.config.option.notest: if venv.status: return @@ -408,6 +413,7 @@ self.report.keyvalue("toxworkdir: ", self.config.toxworkdir) self.report.keyvalue("setupdir: ", self.config.setupdir) self.report.keyvalue("distshare: ", self.config.distshare) + self.report.keyvalue("skipsdist: ", self.config.skipsdist) self.report.tw.line() for envconfig in self.config.envconfigs.values(): self.report.line("[testenv:%s]" % envconfig.envname, bold=True) diff -r 63d37ba9cc8babe926e45f9e8294841148b0451b -r 14d597656e378d1abd515bf90076704824b0f9fe tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -194,6 +194,7 @@ homedir=config.homedir) config.toxworkdir = reader.getpath(toxsection, "toxworkdir", "{toxinidir}/.tox") + config.skipsdist = reader.getbool(toxsection, "skipsdist", False) config.minversion = reader.getdefault(toxsection, "minversion", None) # determine indexserver dictionary https://bitbucket.org/hpk42/tox/commits/517fca71add7/ Changeset: 517fca71add7 User: mordred Date: 2013-07-10 22:44:42 Summary: Make sure that the venv is finalized. Skipping sdist causes the config to not be saved, which causes recreation next time. Affected #: 2 files diff -r 14d597656e378d1abd515bf90076704824b0f9fe -r 517fca71add7ed6d191ce04206109c6eceabc58d tox/_cmdline.py --- a/tox/_cmdline.py +++ b/tox/_cmdline.py @@ -327,6 +327,12 @@ return False return True + def finishvenv(self, venv): + action = self.newaction(venv, "finishvenv") + with action: + venv.finish() + return True + def installpkg(self, venv, sdist_path): action = self.newaction(venv, "installpkg", sdist_path) with action: @@ -375,6 +381,8 @@ if self.setupenv(venv): if not self.config.skipsdist: self.installpkg(venv, sdist_path) + else: + self.finishvenv(venv) self.runtestenv(venv) retcode = self._summary() return retcode diff -r 14d597656e378d1abd515bf90076704824b0f9fe -r 517fca71add7ed6d191ce04206109c6eceabc58d tox/_venv.py --- a/tox/_venv.py +++ b/tox/_venv.py @@ -197,11 +197,14 @@ self._pcall(args, venv=False, action=action, cwd=basepath) self.just_created = True + def finish(self): + self._getliveconfig().writeconfig(self.path_config) + def installpkg(self, sdistpath, action): assert action is not None if getattr(self, 'just_created', False): action.setactivity("inst", sdistpath) - self._getliveconfig().writeconfig(self.path_config) + self.finish() extraopts = [] else: action.setactivity("inst-nodeps", sdistpath) https://bitbucket.org/hpk42/tox/commits/5464e3062afa/ Changeset: 5464e3062afa User: mordred Date: 2013-07-10 23:41:45 Summary: Add support for installing via setup.py develop. Affected #: 4 files diff -r 517fca71add7ed6d191ce04206109c6eceabc58d -r 5464e3062afa62ef2731fcc63902041adaffa56f doc/config.txt --- a/doc/config.txt +++ b/doc/config.txt @@ -22,6 +22,7 @@ distshare=path # defaults to {homedir}/.tox/distshare envlist=ENVLIST # defaults to the list of all environments skipsdist=BOOL # defaults to false + usedevelop=BOOL # use python setup.py develop, defaults to false ``tox`` autodetects if it is running in a Jenkins_ context diff -r 517fca71add7ed6d191ce04206109c6eceabc58d -r 5464e3062afa62ef2731fcc63902041adaffa56f tox/_cmdline.py --- a/tox/_cmdline.py +++ b/tox/_cmdline.py @@ -333,6 +333,16 @@ venv.finish() return True + def developpkg(self, venv, setupdir): + action = self.newaction(venv, "developpkg", setupdir) + with action: + try: + venv.developpkg(setupdir, action) + return True + except tox.exception.InvocationError: + venv.status = sys.exc_info()[1] + return False + def installpkg(self, venv, sdist_path): action = self.newaction(venv, "installpkg", sdist_path) with action: @@ -379,10 +389,12 @@ return for venv in self.venvlist: if self.setupenv(venv): - if not self.config.skipsdist: + if self.config.skipsdist: + if self.config.usedevelop: + self.developpkg(venv, self.config.setupdir) + self.finishvenv(venv) + else: self.installpkg(venv, sdist_path) - else: - self.finishvenv(venv) self.runtestenv(venv) retcode = self._summary() return retcode @@ -422,6 +434,7 @@ self.report.keyvalue("setupdir: ", self.config.setupdir) self.report.keyvalue("distshare: ", self.config.distshare) self.report.keyvalue("skipsdist: ", self.config.skipsdist) + self.report.keyvalue("usedevelop: ", self.config.usedevelop) self.report.tw.line() for envconfig in self.config.envconfigs.values(): self.report.line("[testenv:%s]" % envconfig.envname, bold=True) diff -r 517fca71add7ed6d191ce04206109c6eceabc58d -r 5464e3062afa62ef2731fcc63902041adaffa56f tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -194,7 +194,9 @@ homedir=config.homedir) config.toxworkdir = reader.getpath(toxsection, "toxworkdir", "{toxinidir}/.tox") - config.skipsdist = reader.getbool(toxsection, "skipsdist", False) + config.usedevelop = reader.getbool(toxsection, "usedevelop", False) + config.skipsdist = reader.getbool( + toxsection, "skipsdist", config.usedevelop) config.minversion = reader.getdefault(toxsection, "minversion", None) # determine indexserver dictionary diff -r 517fca71add7ed6d191ce04206109c6eceabc58d -r 5464e3062afa62ef2731fcc63902041adaffa56f tox/_venv.py --- a/tox/_venv.py +++ b/tox/_venv.py @@ -1,4 +1,5 @@ from __future__ import with_statement +import subprocess import sys, os, re import py import tox @@ -200,6 +201,29 @@ def finish(self): self._getliveconfig().writeconfig(self.path_config) + def _needs_reinstall(self, setupdir, action): + setup_py = setupdir.join('setup.py') + setup_cfg = setupdir.join('setup.cfg') + args = [str(self.getconfigexecutable()), str(setup_py), '--name'] + output = subprocess.Popen(args, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out = output.communicate() + name = out[0].strip().decode('utf-8') + egg_info = setupdir.join('.'.join((name, 'egg-info'))) + for conf_file in (setup_py, setup_cfg): + if (conf_file.check() + and conf_file.mtime() > egg_info.mtime()): + return True + return False + + def developpkg(self, setupdir, action): + assert action is not None + self.finish() + if not self._needs_reinstall(setupdir, action): + return + extraopts = ['--no-deps'] + self._install(['-e', setupdir], extraopts=extraopts, action=action) + def installpkg(self, sdistpath, action): assert action is not None if getattr(self, 'just_created', False): https://bitbucket.org/hpk42/tox/commits/94ec2412ae39/ Changeset: 94ec2412ae39 User: mordred Date: 2013-07-11 17:29:51 Summary: Address code review comments Use action.popen instead of subprocess.popen. Allow skipsdist=False and usedevelop=True to coexist. Affected #: 2 files diff -r 5464e3062afa62ef2731fcc63902041adaffa56f -r 94ec2412ae399eb7a75031a412c42e94dc572896 tox/_cmdline.py --- a/tox/_cmdline.py +++ b/tox/_cmdline.py @@ -73,7 +73,7 @@ f.flush() return f - def popen(self, args, cwd=None, env=None, redirect=True): + def popen(self, args, cwd=None, env=None, redirect=True, returnout=False): logged_command = "%s$ %s" %(cwd, " ".join(map(str, args))) f = outpath = None if redirect: @@ -82,6 +82,8 @@ self.id, self.msg, args, env)) f.flush() self.popen_outpath = outpath = py.path.local(f.name) + elif returnout: + f = subprocess.PIPE if cwd is None: # XXX cwd = self.session.config.cwd cwd = py.path.local() @@ -389,9 +391,9 @@ return for venv in self.venvlist: if self.setupenv(venv): - if self.config.skipsdist: - if self.config.usedevelop: - self.developpkg(venv, self.config.setupdir) + if self.config.usedevelop: + self.developpkg(venv, self.config.setupdir) + elif self.config.skipsdist: self.finishvenv(venv) else: self.installpkg(venv, sdist_path) diff -r 5464e3062afa62ef2731fcc63902041adaffa56f -r 94ec2412ae399eb7a75031a412c42e94dc572896 tox/_venv.py --- a/tox/_venv.py +++ b/tox/_venv.py @@ -1,5 +1,4 @@ from __future__ import with_statement -import subprocess import sys, os, re import py import tox @@ -205,10 +204,9 @@ setup_py = setupdir.join('setup.py') setup_cfg = setupdir.join('setup.cfg') args = [str(self.getconfigexecutable()), str(setup_py), '--name'] - output = subprocess.Popen(args, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - out = output.communicate() - name = out[0].strip().decode('utf-8') + output = action.popen(args, cwd=setupdir, redirect=False, + returnout=True) + name = output.strip().decode('utf-8') egg_info = setupdir.join('.'.join((name, 'egg-info'))) for conf_file in (setup_py, setup_cfg): if (conf_file.check() https://bitbucket.org/hpk42/tox/commits/fea763e691c0/ Changeset: fea763e691c0 User: mordred Date: 2013-07-11 17:36:21 Summary: Add test to use usedevelop While we're at it, fix the error that adding the test found. Affected #: 2 files diff -r 94ec2412ae399eb7a75031a412c42e94dc572896 -r fea763e691c022b6eb2de49e26d5d78462ad8614 tests/test_z_cmdline.py --- a/tests/test_z_cmdline.py +++ b/tests/test_z_cmdline.py @@ -359,6 +359,59 @@ ]) +def test_test_develop(cmd, initproj): + initproj("example123-0.5", filedefs={ + 'tests': {'test_hello.py': """ + def test_hello(pytestconfig): + pass + """, + }, + 'tox.ini': ''' + [tox] + usedevelop=True + [testenv] + changedir=tests + commands= + py.test --basetemp={envtmpdir} --junitxml=junit-{envname}.xml [] + deps=pytest + ''' + }) + result = cmd.run("tox") + assert not result.ret + result.stdout.fnmatch_lines([ + "*junit-python.xml*", + "*1 passed*", + ]) + result = cmd.run("tox", "-epython", ) + assert not result.ret + result.stdout.fnmatch_lines([ + "*1 passed*", + "*summary*", + "*python: commands succeeded" + ]) + # see that things work with a different CWD + old = cmd.tmpdir.chdir() + result = cmd.run("tox", "-c", "example123/tox.ini") + assert not result.ret + result.stdout.fnmatch_lines([ + "*1 passed*", + "*summary*", + "*python: commands succeeded" + ]) + old.chdir() + # see that tests can also fail and retcode is correct + testfile = py.path.local("tests").join("test_hello.py") + assert testfile.check() + testfile.write("def test_fail(): assert 0") + result = cmd.run("tox", ) + assert result.ret + result.stdout.fnmatch_lines([ + "*1 failed*", + "*summary*", + "*python: *failed*", + ]) + + def test_test_piphelp(initproj, cmd): initproj("example123", filedefs={'tox.ini': """ # content of: tox.ini diff -r 94ec2412ae399eb7a75031a412c42e94dc572896 -r fea763e691c022b6eb2de49e26d5d78462ad8614 tox/_venv.py --- a/tox/_venv.py +++ b/tox/_venv.py @@ -209,8 +209,8 @@ name = output.strip().decode('utf-8') egg_info = setupdir.join('.'.join((name, 'egg-info'))) for conf_file in (setup_py, setup_cfg): - if (conf_file.check() - and conf_file.mtime() > egg_info.mtime()): + if (not egg_info.check() or (conf_file.check() + and conf_file.mtime() > egg_info.mtime())): return True return False https://bitbucket.org/hpk42/tox/commits/6a52c1c93e08/ Changeset: 6a52c1c93e08 User: mordred Date: 2013-07-11 17:47:44 Summary: Add example documentation for usedevelop Affected #: 1 file diff -r fea763e691c022b6eb2de49e26d5d78462ad8614 -r 6a52c1c93e083f760e46f24219a91ba9f69b926f doc/example/general.txt --- a/doc/example/general.txt +++ b/doc/example/general.txt @@ -144,4 +144,37 @@ [testenv:py27] basepython=/my/path/to/python2.7 +Avoiding expensive sdist +------------------------ + +Some projects are large enough that running and sdist, followed by +an install everytime can be prohibitively costly. To solve this, +there are two different options you can add to the ``tox`` section. First, +you can simply ask tox to please not make an sdist:: + + [tox] + skipsdist=True + +If you do this, your local software package will not be installed into +the virtualenv. You should probably be ok with that, or take steps +to deal with it in your commands section:: + + [testenv] + commands = + python setup.py develop + py.test + +Running setup.py develop is a common enough model that it has its own option:: + + [tox] + usedevelop=True + +Which will set ``skipsdist`` to True and then perform the ``setup.py develop`` +step at the place where ``tox`` normally perfoms the installation of the sdist. +Specifically, it actually runs ``pip install -e .`` behind the scenes, which +itself calls ``setup.py develop``. + +There is an optimization coded in to not bother re-running the command if +``$projectname.egg-info`` is newer than ``setup.py`` or ``setup.cfg``. + .. include:: ../links.txt https://bitbucket.org/hpk42/tox/commits/ddda508fcee1/ Changeset: ddda508fcee1 User: mordred Date: 2013-07-16 16:56:23 Summary: Add command line option for develop Affected #: 3 files diff -r 6a52c1c93e083f760e46f24219a91ba9f69b926f -r ddda508fcee1c7f91d465b5420a25b6b2b9554ef tests/test_z_cmdline.py --- a/tests/test_z_cmdline.py +++ b/tests/test_z_cmdline.py @@ -359,7 +359,14 @@ ]) -def test_test_develop(cmd, initproj): +def test_develop(initproj, cmd): + initproj("example123", filedefs={'tox.ini': """ + """}) + result = cmd.run("tox", "-v", "--develop") + assert not result.ret + assert "sdist-make" not in result.stdout.str() + +def test_test_usedevelop(cmd, initproj): initproj("example123-0.5", filedefs={ 'tests': {'test_hello.py': """ def test_hello(pytestconfig): @@ -376,12 +383,13 @@ deps=pytest ''' }) - result = cmd.run("tox") + result = cmd.run("tox", "-v") assert not result.ret result.stdout.fnmatch_lines([ "*junit-python.xml*", "*1 passed*", ]) + assert "sdist-make" not in result.stdout.str() result = cmd.run("tox", "-epython", ) assert not result.ret result.stdout.fnmatch_lines([ diff -r 6a52c1c93e083f760e46f24219a91ba9f69b926f -r ddda508fcee1c7f91d465b5420a25b6b2b9554ef tox/_cmdline.py --- a/tox/_cmdline.py +++ b/tox/_cmdline.py @@ -391,7 +391,7 @@ return for venv in self.venvlist: if self.setupenv(venv): - if self.config.usedevelop: + if self.config.usedevelop or self.config.option.develop: self.developpkg(venv, self.config.setupdir) elif self.config.skipsdist: self.finishvenv(venv) diff -r 6a52c1c93e083f760e46f24219a91ba9f69b926f -r ddda508fcee1c7f91d465b5420a25b6b2b9554ef tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -90,6 +90,8 @@ help="skip invoking test commands.") parser.add_argument("--sdistonly", action="store_true", dest="sdistonly", help="only perform the sdist packaging activity.") + parser.add_argument("--develop", action="store_true", dest="develop", + help="install package in the venv using setup.py develop") parser.add_argument("--installpkg", action="store", default=None, help="use specified package for installation into venv") parser.add_argument('-i', action="append", @@ -195,8 +197,9 @@ config.toxworkdir = reader.getpath(toxsection, "toxworkdir", "{toxinidir}/.tox") config.usedevelop = reader.getbool(toxsection, "usedevelop", False) - config.skipsdist = reader.getbool( - toxsection, "skipsdist", config.usedevelop) + config.skipsdist = reader.getbool(toxsection, "skipsdist", + config.usedevelop + or config.option.develop) config.minversion = reader.getdefault(toxsection, "minversion", None) # determine indexserver dictionary https://bitbucket.org/hpk42/tox/commits/dc7637581d8a/ Changeset: dc7637581d8a User: mordred Date: 2013-07-16 16:58:20 Summary: Add documentation for the --develop option Affected #: 1 file diff -r ddda508fcee1c7f91d465b5420a25b6b2b9554ef -r dc7637581d8ad1a3793f9b894ffb0a8f758524ed doc/example/general.txt --- a/doc/example/general.txt +++ b/doc/example/general.txt @@ -169,7 +169,8 @@ [tox] usedevelop=True -Which will set ``skipsdist`` to True and then perform the ``setup.py develop`` +And a corresponding command line option ``--develop``, which will set +``skipsdist`` to True and then perform the ``setup.py develop`` step at the place where ``tox`` normally perfoms the installation of the sdist. Specifically, it actually runs ``pip install -e .`` behind the scenes, which itself calls ``setup.py develop``. https://bitbucket.org/hpk42/tox/commits/bfc4a27950dc/ Changeset: bfc4a27950dc User: hpk42 Date: 2013-07-16 17:01:38 Summary: Merged in mordred/configurable-hooks (pull request #49) Make software installation more configurable Affected #: 6 files diff -r 2567d6b26c8995df6cacee337d90f34418057293 -r bfc4a27950dce50e8d49ede674ca73fdaecdf981 doc/config.txt --- a/doc/config.txt +++ b/doc/config.txt @@ -21,6 +21,8 @@ distdir=path # defaults to {toxworkdir}/dist distshare=path # defaults to {homedir}/.tox/distshare envlist=ENVLIST # defaults to the list of all environments + skipsdist=BOOL # defaults to false + usedevelop=BOOL # use python setup.py develop, defaults to false ``tox`` autodetects if it is running in a Jenkins_ context diff -r 2567d6b26c8995df6cacee337d90f34418057293 -r bfc4a27950dce50e8d49ede674ca73fdaecdf981 doc/example/general.txt --- a/doc/example/general.txt +++ b/doc/example/general.txt @@ -144,4 +144,38 @@ [testenv:py27] basepython=/my/path/to/python2.7 +Avoiding expensive sdist +------------------------ + +Some projects are large enough that running and sdist, followed by +an install everytime can be prohibitively costly. To solve this, +there are two different options you can add to the ``tox`` section. First, +you can simply ask tox to please not make an sdist:: + + [tox] + skipsdist=True + +If you do this, your local software package will not be installed into +the virtualenv. You should probably be ok with that, or take steps +to deal with it in your commands section:: + + [testenv] + commands = + python setup.py develop + py.test + +Running setup.py develop is a common enough model that it has its own option:: + + [tox] + usedevelop=True + +And a corresponding command line option ``--develop``, which will set +``skipsdist`` to True and then perform the ``setup.py develop`` +step at the place where ``tox`` normally perfoms the installation of the sdist. +Specifically, it actually runs ``pip install -e .`` behind the scenes, which +itself calls ``setup.py develop``. + +There is an optimization coded in to not bother re-running the command if +``$projectname.egg-info`` is newer than ``setup.py`` or ``setup.cfg``. + .. include:: ../links.txt diff -r 2567d6b26c8995df6cacee337d90f34418057293 -r bfc4a27950dce50e8d49ede674ca73fdaecdf981 tests/test_z_cmdline.py --- a/tests/test_z_cmdline.py +++ b/tests/test_z_cmdline.py @@ -252,6 +252,23 @@ "*ERROR*unknown*environment*qpwoei*", ]) +def test_skip_sdist(cmd, initproj): + initproj("pkg123-0.7", filedefs={ + 'tests': {'test_hello.py': "def test_hello(): pass"}, + 'setup.py': """ + syntax error + """ + , + 'tox.ini': ''' + [tox] + skipsdist=True + [testenv] + commands=echo done + ''' + }) + result = cmd.run("tox", ) + assert result.ret == 0 + def test_sdist_fails(cmd, initproj): initproj("pkg123-0.7", filedefs={ 'tests': {'test_hello.py': "def test_hello(): pass"}, @@ -342,6 +359,67 @@ ]) +def test_develop(initproj, cmd): + initproj("example123", filedefs={'tox.ini': """ + """}) + result = cmd.run("tox", "-v", "--develop") + assert not result.ret + assert "sdist-make" not in result.stdout.str() + +def test_test_usedevelop(cmd, initproj): + initproj("example123-0.5", filedefs={ + 'tests': {'test_hello.py': """ + def test_hello(pytestconfig): + pass + """, + }, + 'tox.ini': ''' + [tox] + usedevelop=True + [testenv] + changedir=tests + commands= + py.test --basetemp={envtmpdir} --junitxml=junit-{envname}.xml [] + deps=pytest + ''' + }) + result = cmd.run("tox", "-v") + assert not result.ret + result.stdout.fnmatch_lines([ + "*junit-python.xml*", + "*1 passed*", + ]) + assert "sdist-make" not in result.stdout.str() + result = cmd.run("tox", "-epython", ) + assert not result.ret + result.stdout.fnmatch_lines([ + "*1 passed*", + "*summary*", + "*python: commands succeeded" + ]) + # see that things work with a different CWD + old = cmd.tmpdir.chdir() + result = cmd.run("tox", "-c", "example123/tox.ini") + assert not result.ret + result.stdout.fnmatch_lines([ + "*1 passed*", + "*summary*", + "*python: commands succeeded" + ]) + old.chdir() + # see that tests can also fail and retcode is correct + testfile = py.path.local("tests").join("test_hello.py") + assert testfile.check() + testfile.write("def test_fail(): assert 0") + result = cmd.run("tox", ) + assert result.ret + result.stdout.fnmatch_lines([ + "*1 failed*", + "*summary*", + "*python: *failed*", + ]) + + def test_test_piphelp(initproj, cmd): initproj("example123", filedefs={'tox.ini': """ # content of: tox.ini diff -r 2567d6b26c8995df6cacee337d90f34418057293 -r bfc4a27950dce50e8d49ede674ca73fdaecdf981 tox/_cmdline.py --- a/tox/_cmdline.py +++ b/tox/_cmdline.py @@ -73,7 +73,7 @@ f.flush() return f - def popen(self, args, cwd=None, env=None, redirect=True): + def popen(self, args, cwd=None, env=None, redirect=True, returnout=False): logged_command = "%s$ %s" %(cwd, " ".join(map(str, args))) f = outpath = None if redirect: @@ -82,6 +82,8 @@ self.id, self.msg, args, env)) f.flush() self.popen_outpath = outpath = py.path.local(f.name) + elif returnout: + f = subprocess.PIPE if cwd is None: # XXX cwd = self.session.config.cwd cwd = py.path.local() @@ -327,6 +329,22 @@ return False return True + def finishvenv(self, venv): + action = self.newaction(venv, "finishvenv") + with action: + venv.finish() + return True + + def developpkg(self, venv, setupdir): + action = self.newaction(venv, "developpkg", setupdir) + with action: + try: + venv.developpkg(setupdir, action) + return True + except tox.exception.InvocationError: + venv.status = sys.exc_info()[1] + return False + def installpkg(self, venv, sdist_path): action = self.newaction(venv, "installpkg", sdist_path) with action: @@ -362,19 +380,28 @@ return sdist_path def subcommand_test(self): - sdist_path = self.sdist() - if not sdist_path: - return 2 + if self.config.skipsdist: + self.report.info("skipping sdist step") + sdist_path = None + else: + sdist_path = self.sdist() + if not sdist_path: + return 2 if self.config.option.sdistonly: return for venv in self.venvlist: if self.setupenv(venv): - self.installpkg(venv, sdist_path) - self.runtestenv(venv, sdist_path) + if self.config.usedevelop or self.config.option.develop: + self.developpkg(venv, self.config.setupdir) + elif self.config.skipsdist: + self.finishvenv(venv) + else: + self.installpkg(venv, sdist_path) + self.runtestenv(venv) retcode = self._summary() return retcode - def runtestenv(self, venv, sdist_path, redirect=False): + def runtestenv(self, venv, redirect=False): if not self.config.option.notest: if venv.status: return @@ -408,6 +435,8 @@ self.report.keyvalue("toxworkdir: ", self.config.toxworkdir) self.report.keyvalue("setupdir: ", self.config.setupdir) self.report.keyvalue("distshare: ", self.config.distshare) + self.report.keyvalue("skipsdist: ", self.config.skipsdist) + self.report.keyvalue("usedevelop: ", self.config.usedevelop) self.report.tw.line() for envconfig in self.config.envconfigs.values(): self.report.line("[testenv:%s]" % envconfig.envname, bold=True) diff -r 2567d6b26c8995df6cacee337d90f34418057293 -r bfc4a27950dce50e8d49ede674ca73fdaecdf981 tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -90,6 +90,8 @@ help="skip invoking test commands.") parser.add_argument("--sdistonly", action="store_true", dest="sdistonly", help="only perform the sdist packaging activity.") + parser.add_argument("--develop", action="store_true", dest="develop", + help="install package in the venv using setup.py develop") parser.add_argument("--installpkg", action="store", default=None, help="use specified package for installation into venv") parser.add_argument('-i', action="append", @@ -194,6 +196,10 @@ homedir=config.homedir) config.toxworkdir = reader.getpath(toxsection, "toxworkdir", "{toxinidir}/.tox") + config.usedevelop = reader.getbool(toxsection, "usedevelop", False) + config.skipsdist = reader.getbool(toxsection, "skipsdist", + config.usedevelop + or config.option.develop) config.minversion = reader.getdefault(toxsection, "minversion", None) # determine indexserver dictionary diff -r 2567d6b26c8995df6cacee337d90f34418057293 -r bfc4a27950dce50e8d49ede674ca73fdaecdf981 tox/_venv.py --- a/tox/_venv.py +++ b/tox/_venv.py @@ -197,11 +197,36 @@ self._pcall(args, venv=False, action=action, cwd=basepath) self.just_created = True + def finish(self): + self._getliveconfig().writeconfig(self.path_config) + + def _needs_reinstall(self, setupdir, action): + setup_py = setupdir.join('setup.py') + setup_cfg = setupdir.join('setup.cfg') + args = [str(self.getconfigexecutable()), str(setup_py), '--name'] + output = action.popen(args, cwd=setupdir, redirect=False, + returnout=True) + name = output.strip().decode('utf-8') + egg_info = setupdir.join('.'.join((name, 'egg-info'))) + for conf_file in (setup_py, setup_cfg): + if (not egg_info.check() or (conf_file.check() + and conf_file.mtime() > egg_info.mtime())): + return True + return False + + def developpkg(self, setupdir, action): + assert action is not None + self.finish() + if not self._needs_reinstall(setupdir, action): + return + extraopts = ['--no-deps'] + self._install(['-e', setupdir], extraopts=extraopts, action=action) + def installpkg(self, sdistpath, action): assert action is not None if getattr(self, 'just_created', False): action.setactivity("inst", sdistpath) - self._getliveconfig().writeconfig(self.path_config) + self.finish() extraopts = [] else: action.setactivity("inst-nodeps", sdistpath) Repository URL: https://bitbucket.org/hpk42/tox/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. _______________________________________________ pytest-commit mailing list pytest-commit@python.org http://mail.python.org/mailman/listinfo/pytest-commit