summaryrefslogtreecommitdiff
path: root/tox
diff options
context:
space:
mode:
authorholger krekel <holger@merlinux.eu>2015-12-09 13:13:32 +0100
committerholger krekel <holger@merlinux.eu>2015-12-09 13:13:32 +0100
commitaf509e26f7e2a08b6f6612873ea6983bccd2e4f9 (patch)
tree73f09b09e25801bde7256ff626c7367d75a956d0 /tox
parente0f22d570e4c242c64e41bb78b4fcfd57fcb79ca (diff)
downloadtox-af509e26f7e2a08b6f6612873ea6983bccd2e4f9.tar.gz
implement new experimental hooks for venv creation
Diffstat (limited to 'tox')
-rw-r--r--tox/_pytestplugin.py9
-rw-r--r--tox/config.py10
-rw-r--r--tox/hookspecs.py11
-rw-r--r--tox/session.py2
-rw-r--r--tox/venv.py75
5 files changed, 66 insertions, 41 deletions
diff --git a/tox/_pytestplugin.py b/tox/_pytestplugin.py
index ee85acc..f15d2ec 100644
--- a/tox/_pytestplugin.py
+++ b/tox/_pytestplugin.py
@@ -31,7 +31,7 @@ def pytest_report_header():
@pytest.fixture
def newconfig(request, tmpdir):
- def newconfig(args, source=None):
+ def newconfig(args, source=None, plugins=()):
if source is None:
source = args
args = []
@@ -40,7 +40,7 @@ def newconfig(request, tmpdir):
p.write(s)
old = tmpdir.chdir()
try:
- return parseconfig(args)
+ return parseconfig(args, plugins=plugins)
finally:
old.chdir()
return newconfig
@@ -168,9 +168,8 @@ def newmocksession(request):
mocksession = request.getfuncargvalue("mocksession")
newconfig = request.getfuncargvalue("newconfig")
- def newmocksession(args, source):
- config = newconfig(args, source)
- mocksession.config = config
+ def newmocksession(args, source, plugins=()):
+ mocksession.config = newconfig(args, source, plugins=plugins)
return mocksession
return newmocksession
diff --git a/tox/config.py b/tox/config.py
index d34a597..ad80269 100644
--- a/tox/config.py
+++ b/tox/config.py
@@ -29,13 +29,17 @@ hookimpl = pluggy.HookimplMarker("tox")
_dummy = object()
-def get_plugin_manager():
+def get_plugin_manager(plugins=()):
# initialize plugin manager
+ import tox.venv
pm = pluggy.PluginManager("tox")
pm.add_hookspecs(hookspecs)
pm.register(tox.config)
pm.register(tox.interpreters)
+ pm.register(tox.venv)
pm.load_setuptools_entrypoints("tox")
+ for plugin in plugins:
+ pm.register(plugin)
pm.check_pending()
return pm
@@ -186,7 +190,7 @@ class InstallcmdOption:
return value
-def parseconfig(args=None):
+def parseconfig(args=None, plugins=()):
"""
:param list[str] args: Optional list of arguments.
:type pkg: str
@@ -194,7 +198,7 @@ def parseconfig(args=None):
:raise SystemExit: toxinit file is not found
"""
- pm = get_plugin_manager()
+ pm = get_plugin_manager(plugins)
if args is None:
args = sys.argv[1:]
diff --git a/tox/hookspecs.py b/tox/hookspecs.py
index 103bda5..36c539c 100644
--- a/tox/hookspecs.py
+++ b/tox/hookspecs.py
@@ -30,3 +30,14 @@ def tox_get_python_executable(envconfig):
per-testenv configuration, notably the ``.envname`` and ``.basepython``
setting.
"""
+
+
+@hookspec
+def tox_testenv_create(venv, action):
+ """ [experimental] perform creation action for this venv.
+ """
+
+
+@hookspec
+def tox_testenv_install_deps(venv, action):
+ """ [experimental] perform install dependencies action for this venv. """
diff --git a/tox/session.py b/tox/session.py
index e5e654b..ffb52d6 100644
--- a/tox/session.py
+++ b/tox/session.py
@@ -313,6 +313,8 @@ class Reporter(object):
class Session:
+ """ (unstable API). the session object that ties
+ together configuration, reporting, venv creation, testing. """
def __init__(self, config, popen=subprocess.Popen, Report=Reporter):
self.config = config
diff --git a/tox/venv.py b/tox/venv.py
index bed7fb7..2e46098 100644
--- a/tox/venv.py
+++ b/tox/venv.py
@@ -5,7 +5,7 @@ import re
import codecs
import py
import tox
-from .config import DepConfig
+from .config import DepConfig, hookimpl
class CreationConfig:
@@ -58,6 +58,10 @@ class VirtualEnv(object):
self.session = session
@property
+ def hook(self):
+ return self.envconfig.config.pluginmanager.hook
+
+ @property
def path(self):
""" Path to environment base dir. """
return self.envconfig.envdir
@@ -76,7 +80,8 @@ class VirtualEnv(object):
def getcommandpath(self, name, venv=True, cwd=None):
""" return absolute path (str or localpath) for specified
- command name. If venv is True we will check if the
+ command name. If it's a localpath we will rewrite it as
+ as a relative path. If venv is True we will check if the
command is coming from the venv or is whitelisted to come
from external. """
name = str(name)
@@ -138,13 +143,14 @@ class VirtualEnv(object):
else:
action.setactivity("recreate", self.envconfig.envdir)
try:
- self.create(action)
+ self.hook.tox_testenv_create(action=action, venv=self)
+ self.just_created = True
except tox.exception.UnsupportedInterpreter:
return sys.exc_info()[1]
except tox.exception.InterpreterNotFound:
return sys.exc_info()[1]
try:
- self.install_deps(action)
+ self.hook.tox_testenv_install_deps(action=action, venv=self)
except tox.exception.InvocationError:
v = sys.exc_info()[1]
return "could not install deps %s; v = %r" % (
@@ -180,28 +186,6 @@ class VirtualEnv(object):
def matching_platform(self):
return re.match(self.envconfig.platform, sys.platform)
- def create(self, action):
- # if self.getcommandpath("activate").dirpath().check():
- # return
- config_interpreter = self.getsupportedinterpreter()
- args = [sys.executable, '-m', 'virtualenv']
- if self.envconfig.sitepackages:
- args.append('--system-site-packages')
- # add interpreter explicitly, to prevent using
- # default (virtualenv.ini)
- args.extend(['--python', str(config_interpreter)])
- # if sys.platform == "win32":
- # f, path, _ = py.std.imp.find_module("virtualenv")
- # f.close()
- # args[:1] = [str(config_interpreter), str(path)]
- # else:
- self.session.make_emptydir(self.path)
- basepath = self.path.dirpath()
- basepath.ensure(dir=1)
- args.append(self.path.basename)
- self._pcall(args, venv=False, action=action, cwd=basepath)
- self.just_created = True
-
def finish(self):
self._getliveconfig().writeconfig(self.path_config)
@@ -244,13 +228,6 @@ class VirtualEnv(object):
extraopts = ['-U', '--no-deps']
self._install([sdistpath], extraopts=extraopts, action=action)
- def install_deps(self, action):
- deps = self._getresolvedeps()
- if deps:
- depinfo = ", ".join(map(str, deps))
- action.setactivity("installdeps", "%s" % depinfo)
- self._install(deps, action=action)
-
def _installopts(self, indexserver):
l = []
if indexserver:
@@ -390,3 +367,35 @@ def getdigest(path):
if not path.check(file=1):
return "0" * 32
return path.computehash()
+
+
+@hookimpl
+def tox_testenv_create(venv, action):
+ # if self.getcommandpath("activate").dirpath().check():
+ # return
+ config_interpreter = venv.getsupportedinterpreter()
+ args = [sys.executable, '-m', 'virtualenv']
+ if venv.envconfig.sitepackages:
+ args.append('--system-site-packages')
+ # add interpreter explicitly, to prevent using
+ # default (virtualenv.ini)
+ args.extend(['--python', str(config_interpreter)])
+ # if sys.platform == "win32":
+ # f, path, _ = py.std.imp.find_module("virtualenv")
+ # f.close()
+ # args[:1] = [str(config_interpreter), str(path)]
+ # else:
+ venv.session.make_emptydir(venv.path)
+ basepath = venv.path.dirpath()
+ basepath.ensure(dir=1)
+ args.append(venv.path.basename)
+ venv._pcall(args, venv=False, action=action, cwd=basepath)
+
+
+@hookimpl
+def tox_testenv_install_deps(venv, action):
+ deps = venv._getresolvedeps()
+ if deps:
+ depinfo = ", ".join(map(str, deps))
+ action.setactivity("installdeps", "%s" % depinfo)
+ venv._install(deps, action=action)