summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorholger krekel <holger@merlinux.eu>2012-11-23 22:32:30 +0100
committerholger krekel <holger@merlinux.eu>2012-11-23 22:32:30 +0100
commitc23f32b2905239827b12d65f11ac4a745c413b0f (patch)
tree78638e43e202793b33c12def90e1297dc3ab4326
parentcdd8f99a7b52be286de34925f4cd31990f2994fe (diff)
parente54f50beb67fdf787556d5a3a5905e6ed1686704 (diff)
downloadtox-c23f32b2905239827b12d65f11ac4a745c413b0f.tar.gz
merge
-rw-r--r--doc/index.txt3
-rw-r--r--setup.py2
-rw-r--r--tests/test_quickstart.py326
-rw-r--r--tox/_quickstart.py255
4 files changed, 585 insertions, 1 deletions
diff --git a/doc/index.txt b/doc/index.txt
index 2a4203c..e3e13eb 100644
--- a/doc/index.txt
+++ b/doc/index.txt
@@ -36,6 +36,9 @@ right next to your ``setup.py`` file::
deps=pytest # install pytest in the venvs
commands=py.test # or 'nosetests' or ...
+You can also try generating a ``tox.ini`` file automatically, by running
+``tox-quickstart`` and then answering a few simple questions.
+
To sdist-package, install and test your project against Python2.6 and Python2.7, just type::
tox
diff --git a/setup.py b/setup.py
index 6a01278..a64d111 100644
--- a/setup.py
+++ b/setup.py
@@ -55,7 +55,7 @@ def main():
author='holger krekel',
author_email='holger@merlinux.eu',
packages=['tox', ],
- entry_points={'console_scripts': 'tox=tox:cmdline'},
+ entry_points={'console_scripts': 'tox=tox:cmdline\ntox-quickstart=tox._quickstart:main'},
# we use a public tox version to test, see tox.ini's testenv
# "deps" definition for the required dependencies
tests_require=['tox'],
diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py
new file mode 100644
index 0000000..446954e
--- /dev/null
+++ b/tests/test_quickstart.py
@@ -0,0 +1,326 @@
+import tox._quickstart
+
+
+class TestToxQuickstartMain(object):
+ def mock_term_input_return_values(self, return_values):
+ for return_val in return_values:
+ yield return_val
+
+ def get_mock_term_input(self, return_values):
+ generator = self.mock_term_input_return_values(return_values)
+
+ def mock_term_input(prompt):
+ try:
+ return next(generator)
+ except NameError:
+ return generator.next()
+
+ return mock_term_input
+
+ def test_quickstart_main_choose_individual_pythons_and_pytest(self, monkeypatch, tmpdir):
+ monkeypatch.setattr(
+ tox._quickstart, 'term_input',
+ self.get_mock_term_input(['4', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'Y', 'Y', 'Y', 'N', 'py.test', 'pytest']))
+
+ tox._quickstart.main(argv=['tox-quickstart'])
+
+ expected_tox_ini = """
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py24, py25, py26, py27, py32, py33, pypy
+
+[testenv]
+commands = py.test
+deps =
+ pytest
+""".lstrip()
+ result = open('tox.ini').read()
+ assert(result == expected_tox_ini)
+
+ def test_quickstart_main_choose_individual_pythons_and_nose_adds_deps(self, monkeypatch, tmpdir):
+ monkeypatch.setattr(
+ tox._quickstart, 'term_input',
+ self.get_mock_term_input(['4', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'Y', 'Y', 'Y', 'N', 'nosetests', '']))
+
+ tox._quickstart.main(argv=['tox-quickstart'])
+
+ expected_tox_ini = """
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py24, py25, py26, py27, py32, py33, pypy
+
+[testenv]
+commands = nosetests
+deps =
+ nose
+""".lstrip()
+ result = open('tox.ini').read()
+ assert(result == expected_tox_ini)
+
+ def test_quickstart_main_choose_individual_pythons_and_trial_adds_deps(self, monkeypatch, tmpdir):
+ monkeypatch.setattr(
+ tox._quickstart, 'term_input',
+ self.get_mock_term_input(['4', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'Y', 'Y', 'Y', 'N', 'trial', '']))
+
+ tox._quickstart.main(argv=['tox-quickstart'])
+
+ expected_tox_ini = """
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py24, py25, py26, py27, py32, py33, pypy
+
+[testenv]
+commands = trial
+deps =
+ twisted
+""".lstrip()
+ result = open('tox.ini').read()
+ assert(result == expected_tox_ini)
+
+ def test_quickstart_main_choose_individual_pythons_and_pytest_adds_deps(self, monkeypatch, tmpdir):
+ monkeypatch.setattr(
+ tox._quickstart, 'term_input',
+ self.get_mock_term_input(['4', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'Y', 'Y', 'Y', 'N', 'py.test', '']))
+
+ tox._quickstart.main(argv=['tox-quickstart'])
+
+ expected_tox_ini = """
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py24, py25, py26, py27, py32, py33, pypy
+
+[testenv]
+commands = py.test
+deps =
+ pytest
+""".lstrip()
+ result = open('tox.ini').read()
+ assert(result == expected_tox_ini)
+
+ def test_quickstart_main_choose_py27_and_pytest_adds_deps(self, monkeypatch, tmpdir):
+ monkeypatch.setattr(
+ tox._quickstart, 'term_input',
+ self.get_mock_term_input(['1', 'py.test', '']))
+
+ tox._quickstart.main(argv=['tox-quickstart'])
+
+ expected_tox_ini = """
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py27
+
+[testenv]
+commands = py.test
+deps =
+ pytest
+""".lstrip()
+ result = open('tox.ini').read()
+ assert(result == expected_tox_ini)
+
+ def test_quickstart_main_choose_py27_and_py33_and_pytest_adds_deps(self, monkeypatch, tmpdir):
+ monkeypatch.setattr(
+ tox._quickstart, 'term_input',
+ self.get_mock_term_input(['2', 'py.test', '']))
+
+ tox._quickstart.main(argv=['tox-quickstart'])
+
+ expected_tox_ini = """
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py27, py33
+
+[testenv]
+commands = py.test
+deps =
+ pytest
+""".lstrip()
+ result = open('tox.ini').read()
+ assert(result == expected_tox_ini)
+
+ def test_quickstart_main_choose_all_pythons_and_pytest_adds_deps(self, monkeypatch, tmpdir):
+ monkeypatch.setattr(
+ tox._quickstart, 'term_input',
+ self.get_mock_term_input(['3', 'py.test', '']))
+
+ tox._quickstart.main(argv=['tox-quickstart'])
+
+ expected_tox_ini = """
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py24, py25, py26, py27, py30, py31, py32, py33, pypy, jython
+
+[testenv]
+commands = py.test
+deps =
+ pytest
+""".lstrip()
+ result = open('tox.ini').read()
+ assert(result == expected_tox_ini)
+
+ def test_quickstart_main_choose_individual_pythons_and_defaults(self, monkeypatch, tmpdir):
+ monkeypatch.setattr(
+ tox._quickstart, 'term_input',
+ self.get_mock_term_input(['4', '', '', '', '', '', '', '', '', '', '', '', '']))
+
+ tox._quickstart.main(argv=['tox-quickstart'])
+
+ expected_tox_ini = """
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py24, py25, py26, py27, py30, py31, py32, py33, pypy, jython
+
+[testenv]
+commands = {envpython} setup.py test
+deps =
+
+""".lstrip()
+ result = open('tox.ini').read()
+ assert(result == expected_tox_ini)
+
+
+class TestToxQuickstart(object):
+ def test_pytest(self, tmpdir):
+ d = {
+ 'py24': True,
+ 'py25': True,
+ 'py26': True,
+ 'py27': True,
+ 'py32': True,
+ 'py33': True,
+ 'pypy': True,
+ 'commands': 'py.test',
+ 'deps': 'pytest',
+ }
+ expected_tox_ini = """
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py24, py25, py26, py27, py32, py33, pypy
+
+[testenv]
+commands = py.test
+deps =
+ pytest
+""".lstrip()
+ d = tox._quickstart.process_input(d)
+ tox._quickstart.generate(d)
+ result = open('tox.ini').read()
+ # print(result)
+ assert(result == expected_tox_ini)
+
+ def test_setup_py_test(self, tmpdir):
+ d = {
+ 'py26': True,
+ 'py27': True,
+ 'commands': 'python setup.py test',
+ 'deps': '',
+ }
+ expected_tox_ini = """
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py26, py27
+
+[testenv]
+commands = python setup.py test
+deps =
+
+""".lstrip()
+ d = tox._quickstart.process_input(d)
+ tox._quickstart.generate(d)
+ result = open('tox.ini').read()
+ # print(result)
+ assert(result == expected_tox_ini)
+
+ def test_trial(self, tmpdir):
+ d = {
+ 'py27': True,
+ 'commands': 'trial',
+ 'deps': 'Twisted',
+ }
+ expected_tox_ini = """
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py27
+
+[testenv]
+commands = trial
+deps =
+ Twisted
+""".lstrip()
+ d = tox._quickstart.process_input(d)
+ tox._quickstart.generate(d)
+ result = open('tox.ini').read()
+ # print(result)
+ assert(result == expected_tox_ini)
+
+ def test_nosetests(self, tmpdir):
+ d = {
+ 'py27': True,
+ 'py32': True,
+ 'py33': True,
+ 'pypy': True,
+ 'commands': 'nosetests -v',
+ 'deps': 'nose',
+ }
+ expected_tox_ini = """
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py27, py32, py33, pypy
+
+[testenv]
+commands = nosetests -v
+deps =
+ nose
+""".lstrip()
+ d = tox._quickstart.process_input(d)
+ tox._quickstart.generate(d)
+ result = open('tox.ini').read()
+ # print(result)
+ assert(result == expected_tox_ini)
diff --git a/tox/_quickstart.py b/tox/_quickstart.py
new file mode 100644
index 0000000..f8ff64d
--- /dev/null
+++ b/tox/_quickstart.py
@@ -0,0 +1,255 @@
+# -*- coding: utf-8 -*-
+"""
+ tox._quickstart
+ ~~~~~~~~~~~~~~~~~
+
+ Command-line script to quickly setup tox.ini for a Python project
+
+ This file was heavily inspired by and uses code from ``sphinx-quickstart``
+ in the BSD-licensed `Sphinx project`_.
+
+ .. Sphinx project_: http://sphinx.pocoo.org/
+
+ License for Sphinx
+ ==================
+
+ Copyright (c) 2007-2011 by the Sphinx team (see AUTHORS file).
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""
+
+import sys
+from os import path
+from codecs import open
+
+TERM_ENCODING = getattr(sys.stdin, 'encoding', None)
+
+from tox import __version__
+
+# function to get input from terminal -- overridden by the test suite
+try:
+ # this raw_input is not converted by 2to3
+ term_input = raw_input
+except NameError:
+ term_input = input
+
+
+all_envs = ['py24', 'py25', 'py26', 'py27', 'py30', 'py31', 'py32', 'py33', 'pypy', 'jython']
+
+PROMPT_PREFIX = '> '
+
+QUICKSTART_CONF = '''\
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = %(envlist)s
+
+[testenv]
+commands = %(commands)s
+deps = %(deps)s
+'''
+
+
+class ValidationError(Exception):
+ """Raised for validation errors."""
+
+def nonempty(x):
+ if not x:
+ raise ValidationError("Please enter some text.")
+ return x
+
+def choice(*l):
+ def val(x):
+ if x not in l:
+ raise ValidationError('Please enter one of %s.' % ', '.join(l))
+ return x
+ return val
+
+def boolean(x):
+ if x.upper() not in ('Y', 'YES', 'N', 'NO'):
+ raise ValidationError("Please enter either 'y' or 'n'.")
+ return x.upper() in ('Y', 'YES')
+
+def suffix(x):
+ if not (x[0:1] == '.' and len(x) > 1):
+ raise ValidationError("Please enter a file suffix, "
+ "e.g. '.rst' or '.txt'.")
+ return x
+
+def ok(x):
+ return x
+
+
+def do_prompt(d, key, text, default=None, validator=nonempty):
+ while True:
+ if default:
+ prompt = PROMPT_PREFIX + '%s [%s]: ' % (text, default)
+ else:
+ prompt = PROMPT_PREFIX + text + ': '
+ x = term_input(prompt)
+ if default and not x:
+ x = default
+ if sys.version_info < (3, ) and not isinstance(x, unicode):
+ # for Python 2.x, try to get a Unicode string out of it
+ if x.decode('ascii', 'replace').encode('ascii', 'replace') != x:
+ if TERM_ENCODING:
+ x = x.decode(TERM_ENCODING)
+ else:
+ print('* Note: non-ASCII characters entered '
+ 'and terminal encoding unknown -- assuming '
+ 'UTF-8 or Latin-1.')
+ try:
+ x = x.decode('utf-8')
+ except UnicodeDecodeError:
+ x = x.decode('latin1')
+ try:
+ x = validator(x)
+ except ValidationError:
+ err = sys.exc_info()[1]
+ print('* ' + str(err))
+ continue
+ break
+ d[key] = x
+
+
+def ask_user(d):
+ """Ask the user for quickstart values missing from *d*.
+
+ """
+
+ print('Welcome to the Tox %s quickstart utility.' % __version__)
+ print('''
+This utility will ask you a few questions and then generate a simple tox.ini
+file to help get you started using tox.
+
+Please enter values for the following settings (just press Enter to
+accept a default value, if one is given in brackets).''')
+
+ sys.stdout.write('\n')
+
+ print('''
+What Python versions do you want to test against? Choices:
+ [1] py27
+ [2] py27, py33
+ [3] (All versions) %s
+ [4] Choose each one-by-one''' % ', '.join(all_envs))
+ do_prompt(d, 'canned_pyenvs', 'Enter the number of your choice',
+ '3', choice('1', '2', '3', '4'))
+
+ if d['canned_pyenvs'] == '1':
+ d['py27'] = True
+ elif d['canned_pyenvs'] == '2':
+ for pyenv in ('py27', 'py33'):
+ d[pyenv] = True
+ elif d['canned_pyenvs'] == '3':
+ for pyenv in all_envs:
+ d[pyenv] = True
+ elif d['canned_pyenvs'] == '4':
+ for pyenv in all_envs:
+ if pyenv not in d:
+ do_prompt(d, pyenv, 'Test your project with %s (Y/n)' % pyenv, 'Y', boolean)
+
+ print('''
+What command should be used to test your project -- examples:
+ - py.test
+ - python setup.py test
+ - nosetests package.module
+ - trial package.module''')
+ do_prompt(d, 'commands', 'Command to run to test project', '{envpython} setup.py test')
+
+ default_deps = ' '
+ if 'py.test' in d['commands']:
+ default_deps = 'pytest'
+ if 'nosetests' in d['commands']:
+ default_deps = 'nose'
+ if 'trial' in d['commands']:
+ default_deps = 'twisted'
+
+ print('''
+What dependencies does your project have?''')
+ do_prompt(d, 'deps', 'Comma-separated list of dependencies', default_deps)
+
+
+def process_input(d):
+ d['envlist'] = ', '.join([env for env in all_envs if d.get(env) is True])
+ d['deps'] = '\n' + '\n'.join([' %s' % dep.strip() for dep in d['deps'].split(',')])
+
+ return d
+
+
+def generate(d, overwrite=True, silent=False):
+ """Generate project based on values in *d*."""
+
+ conf_text = QUICKSTART_CONF % d
+
+ def write_file(fpath, mode, content):
+ if overwrite or not path.isfile(fpath):
+ print('Creating file %s.' % fpath)
+ f = open(fpath, mode, encoding='utf-8')
+ try:
+ f.write(content)
+ finally:
+ f.close()
+ else:
+ print('File %s already exists, skipping.' % fpath)
+
+ sys.stdout.write('\n')
+
+ write_file('tox.ini', 'w', conf_text)
+
+ if silent:
+ return
+ sys.stdout.write('\n')
+ print('Finished: A tox.ini file has been created. For information on this file, see http://tox.testrun.org/latest/config.html')
+ print('''
+Execute `tox` to test your project.
+''')
+
+
+def main(argv=sys.argv):
+ d = {}
+
+ if len(argv) > 3:
+ print('Usage: tox-quickstart [root]')
+ sys.exit(1)
+ elif len(argv) == 2:
+ d['path'] = argv[1]
+
+ try:
+ ask_user(d)
+ except (KeyboardInterrupt, EOFError):
+ print()
+ print('[Interrupted.]')
+ return
+
+ d = process_input(d)
+ generate(d)
+
+
+if __name__ == '__main__':
+ main()