forked from logandk/serverless-wsgi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrequirements.py
101 lines (82 loc) · 3.15 KB
/
requirements.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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
This module loads a `requirements.txt` and uses `virtualenv`/`pip` to
install the required Python packages into the specified directory.
Inspired by: https://github.com/awslabs/chalice
Author: Logan Raarup <[email protected]>
"""
import os
import platform
import shutil
import subprocess
import sys
try:
import virtualenv
except ImportError: # pragma: no cover
sys.exit('Unable to load virtualenv, please install')
def package(req_files, target_dir):
venv_dir = os.path.join(target_dir, '.venv')
tmp_dir = os.path.join(target_dir, '.tmp')
for req_file in req_files:
if not os.path.isfile(req_file):
sys.exit('No requirements file found in: {}'.format(req_file))
if os.path.exists(target_dir):
if not os.path.isdir(target_dir):
sys.exit('Existing non-directory found at: {}'.format(target_dir))
else:
os.mkdir(target_dir)
if os.path.exists(venv_dir):
shutil.rmtree(venv_dir)
if os.path.exists(tmp_dir):
shutil.rmtree(tmp_dir)
original = sys.argv
sys.argv = ['', venv_dir, '--quiet', '-p', sys.executable]
try:
virtualenv.main()
finally:
sys.argv = original
if platform.system() == 'Windows':
pip_exe = os.path.join(venv_dir, 'Scripts', 'pip.exe')
deps_dir = os.path.join(venv_dir, 'Lib', 'site-packages')
else:
pip_exe = os.path.join(venv_dir, 'bin', 'pip')
lib_path = os.path.join(venv_dir, 'lib')
libs_dir_path_items = os.listdir(lib_path)
directories = [d for d in libs_dir_path_items
if os.path.isdir(os.path.join(lib_path, d))]
if len(directories) > 0:
python_dir = directories[0]
else:
sys.exit('No python directory')
deps_dir = os.path.join(venv_dir, 'lib', python_dir, 'site-packages')
if not os.path.isfile(pip_exe):
sys.exit('Pip not found in: {}'.format(pip_exe))
for req_file in req_files:
p = subprocess.Popen([pip_exe, 'install', '-r', req_file],
stdout=subprocess.PIPE)
p.communicate()
if p.returncode != 0:
sys.exit("Failed to install requirements from: {}".format(
req_file))
if not os.path.isdir(deps_dir):
sys.exit('Installed packages not found in: {}'.format(deps_dir))
blacklist = [
'pip', 'pip-*', 'wheel', 'wheel-*', 'setuptools',
'setuptools-*', 'easy_install.*', '__pycache__']
shutil.copytree(deps_dir, tmp_dir, symlinks=False,
ignore=shutil.ignore_patterns(*blacklist))
for f in os.listdir(tmp_dir):
target = os.path.join(target_dir, f)
if os.path.isdir(target):
shutil.rmtree(target)
elif os.path.exists(target):
os.remove(target)
shutil.move(os.path.join(tmp_dir, f), target_dir)
shutil.rmtree(venv_dir)
shutil.rmtree(tmp_dir)
if __name__ == '__main__': # pragma: no cover
if len(sys.argv) < 3:
sys.exit('Usage: {} REQ_FILE... TARGET_DIR'.format(
os.path.basename(sys.argv[0])))
package(sys.argv[1:-1], sys.argv[-1])