-
Notifications
You must be signed in to change notification settings - Fork 0
/
freezer.py
125 lines (90 loc) · 3.45 KB
/
freezer.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
"""
A script to collect every installed dependencies versions from "pip freeze" but
only those ones explicitely required in package configuration.
It will create a "frozen.txt" file which can help users to find an exact list of
dependencies versions which have been tested.
This require a recent install of setuptools (>=39.1.0).
You must call this script with the same Python interpreter used in your virtual
environment.
"""
import subprocess
import sys
import pkg_resources
def flatten_requirement(requirement):
"""
Return only the package name from a requirement.
Arguments:
requirement (pkg_resources.Requirement): A requirement object.
Returns:
string: Package name.
"""
return requirement.key
def extract_pkg_version(package_name):
"""
Get package version from installed distribution or configuration file if not
installed
Arguments:
package_name (string): Package name to search and extract informations.
Returns:
string: Version name.
"""
return pkg_resources.get_distribution(package_name).version
def extract_pkg_requirements(package_name):
"""
Get all required dependency names from every requirement sections.
Arguments:
package_name (string): Package name to search and extract informations.
Returns:
list: A list of all required package names.
"""
distrib = pkg_resources.get_distribution(package_name)
requirements = set([])
for r in distrib.requires():
requirements.add(flatten_requirement(r))
for item in distrib.extras:
for r in distrib.requires(extras=(item,)):
requirements.add(flatten_requirement(r))
return list(requirements)
def get_install_dependencies(requirements=None, ignore=[]):
"""
Use "pip freeze" command to get installed dependencies and possibly filtered
them from a list of names.
This does not support installed dependencies from a VCS or in editable mode.
Keyword Arguments:
requirements (list): List of package names to retain from installed
dependencies. If not given, all installed dependencies are retained.
ignore (list): List of package names to ignore from installed
dependencies.
Returns:
list: List of installed dependencies with their version. Either all or
only those ones from given ``names``.
"""
reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
# Filter from requirement names (if any) and ignored ones
deps = []
for item in reqs.splitlines():
pkg = item.decode('utf-8')
name = pkg.split("==")[0].lower()
if (
(requirements is None or name in requirements) and
name not in ignore
):
deps.append(pkg)
return deps
def write_frozen_requirements(package_name, filename="frozen.txt"):
"""
Write a file of frozen requirement versions for current version of a
package.
"""
version = extract_pkg_version(package_name)
requirements = extract_pkg_requirements(package_name)
installed = get_install_dependencies(requirements)
lines = [
"# Frozen requirement versions from '{}' installation".format(version)
] + installed
with open(filename, "w") as fp:
fp.write("\n".join(lines))
return filename
if __name__ == "__main__":
filename = write_frozen_requirements("diskette")
print("Created file for frozen dependencies:", filename)