This repository was archived by the owner on Mar 1, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathtox_pip_extensions.py
154 lines (117 loc) · 4.59 KB
/
tox_pip_extensions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
import collections
import contextlib
import six
from tox import hookimpl
TOX_KEY = 'tox_pip_extensions_ext_'
PIP_CUSTOM_PLATFORM = 'pip_custom_platform'
VENV_UPDATE = 'venv_update'
INSTALL_DEPS = {
PIP_CUSTOM_PLATFORM: str('pip-custom-platform>=0.3.1'),
VENV_UPDATE: str('venv-update>=2.1.3'),
}
_INSTALL = ('install', '{opts}', '{packages}')
_PCP = ('pip-custom-platform',) + _INSTALL
_VU = ('pip-faster',) + _INSTALL
_PCP_VU = ('pymonkey', 'pip-custom-platform', '--') + _VU
VANILLA_PIP_INSTALL_CMD = ('pip',) + _INSTALL
INSTALL_CMD = {
(PIP_CUSTOM_PLATFORM, VENV_UPDATE): _PCP_VU,
(PIP_CUSTOM_PLATFORM,): _PCP,
(VENV_UPDATE,): _VU,
}
Config = collections.namedtuple('Config', ('extensions', 'bootstrap_deps'))
def _assert_true_value(k, v):
if v.lower() in {'true', '1'}:
return True
else:
raise ValueError('Expected "true" but got {} = {!r}'.format(k, v))
@hookimpl
def tox_configure(config):
cfg = six.moves.configparser.ConfigParser()
cfg.read(config.option.configfile)
configured = tuple(sorted(
k[len(TOX_KEY):]
for k, v in cfg.items('tox')
if k.startswith(TOX_KEY) and _assert_true_value(k, v)
))
if configured:
bootstrap = config.toxinidir.join('requirements-bootstrap.txt')
if bootstrap.exists():
bootstrap_deps = (str('-r{}').format(bootstrap),)
else:
bootstrap_deps = [INSTALL_DEPS[ext] for ext in configured]
# venv-update has more restrictive dependencies, list it first
bootstrap_deps = tuple(reversed(bootstrap_deps))
install_cmd = INSTALL_CMD[configured] + bootstrap_deps
for k, cfg in config.envconfigs.items():
if tuple(cfg.install_command) != VANILLA_PIP_INSTALL_CMD:
print('!' * 79)
print(
'tox-pip-extension(s) ({}) used but testenv ({}) sets '
'install_command!'.format(', '.join(configured), k),
)
print('!' * 79)
exit(1)
cfg.install_command[:] = install_cmd
else:
bootstrap_deps = None
config.pip_extensions = Config(configured, bootstrap_deps)
def _install(venv, action, step, deps):
if deps:
action.setactivity(step, ','.join(map(str, deps)))
venv._install(deps, action=action)
@contextlib.contextmanager
def _install_cmd(envconfig, install_command):
orig = envconfig.install_command[:]
envconfig.install_command[:] = install_command
try:
yield
finally:
envconfig.install_command[:] = orig
def _install_bootstrap(venv, action, bootstrap_deps):
with _install_cmd(venv.envconfig, VANILLA_PIP_INSTALL_CMD):
_install(venv, action, 'bootstrap', bootstrap_deps)
@hookimpl(tryfirst=True)
def tox_testenv_install_deps(venv, action):
config = venv.session.config
extensions, bootstrap_deps = config.pip_extensions
# If there's nothing special for us to do, defer to other plugins
if not extensions:
return None
_install_bootstrap(venv, action, bootstrap_deps)
_install(venv, action, 'installdeps', venv._getresolvedeps())
# Indicate to the plugin framework that we have handled installation
return True
@hookimpl
def tox_runtest_pre(venv):
config = venv.session.config
extensions, bootstrap_deps = config.pip_extensions
# If there's nothing special for us to do, defer to other plugins
if not extensions:
return None
action = venv.session.newaction(venv, 'tox-pip-extensions')
_install_bootstrap(venv, action, bootstrap_deps)
install_command = list(venv.envconfig.install_command)
if 'venv_update' in extensions:
install_command.append('--prune')
def _extras(opt):
if venv.envconfig.extras:
return opt + '[{}]'.format(','.join(venv.envconfig.extras))
else:
return opt
if venv.envconfig.usedevelop:
install_command.append(_extras('-e{}'.format(config.toxinidir)))
elif not config.skipsdist and not venv.envconfig.skip_install:
install_command.append(_extras(venv.session.get_installpkg_path()))
with _install_cmd(venv.envconfig, install_command):
_install(venv, action, 'installdeps', venv._getresolvedeps())
# Show what we installed
output = venv._pcall(
venv.envconfig.list_dependencies_command,
cwd=config.toxinidir,
action=action,
).split('\n\n')[-1]
action.setactivity('installed', ','.join(output.splitlines()))