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
|
"""
If setuptools is not already installed in the environment, it's not possible
to invoke setuptools' own commands. This routine will bootstrap this local
environment by creating a minimal egg-info directory and then invoking the
egg-info command to flesh out the egg-info directory.
"""
from __future__ import unicode_literals
import os
import io
import re
import contextlib
import tempfile
import shutil
import sys
import textwrap
import subprocess
minimal_egg_info = textwrap.dedent("""
[distutils.commands]
egg_info = setuptools.command.egg_info:egg_info
[distutils.setup_keywords]
include_package_data = setuptools.dist:assert_bool
install_requires = setuptools.dist:check_requirements
extras_require = setuptools.dist:check_extras
entry_points = setuptools.dist:check_entry_points
[egg_info.writers]
dependency_links.txt = setuptools.command.egg_info:overwrite_arg
entry_points.txt = setuptools.command.egg_info:write_entries
requires.txt = setuptools.command.egg_info:write_requirements
""")
def ensure_egg_info():
if os.path.exists('setuptools.egg-info'):
return
print("adding minimal entry_points")
build_egg_info()
def build_egg_info():
"""
Build a minimal egg-info, enough to invoke egg_info
"""
os.mkdir('setuptools.egg-info')
filename = 'setuptools.egg-info/entry_points.txt'
with io.open(filename, 'w', encoding='utf-8') as ep:
ep.write(minimal_egg_info)
def run_egg_info():
cmd = [sys.executable, 'setup.py', 'egg_info']
print("Regenerating egg_info")
subprocess.check_call(cmd)
print("...and again.")
subprocess.check_call(cmd)
def gen_deps():
with io.open('setup.py', encoding='utf-8') as strm:
text = strm.read()
pattern = r'install_requires=\[(.*?)\]'
match = re.search(pattern, text, flags=re.M|re.DOTALL)
reqs = eval(match.group(1).replace('\n', ''))
with io.open('requirements.txt', 'w', encoding='utf-8') as reqs_file:
reqs_file.write('\n'.join(reqs))
@contextlib.contextmanager
def install_deps():
"Just in time make the deps available"
import pip
tmpdir = tempfile.mkdtemp()
args = [
'install',
'-t', tmpdir,
'-r', 'requirements.txt',
]
pip.main(args)
os.environ['PYTHONPATH'] = tmpdir
try:
yield tmpdir
finally:
shutil.rmtree(tmpdir)
def main():
ensure_egg_info()
gen_deps()
try:
# first assume dependencies are present
run_egg_info()
except Exception:
# but if that fails, try again with dependencies just in time
with install_deps():
run_egg_info()
__name__ == '__main__' and main()
|