File size: 6,265 Bytes
8097001
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
import os
import networkx as nx
import time
import requests
import importlib.util
from copy import deepcopy


REMOVE_DEPS_AT_END = True
UPDATE_DOCKERFILE = True
UPDATE_OTHER_FILES = True
INCLUDE_BETAS = False


def get_version(package):
    url = "https://pypi.org/project/" + package
    r = requests.get(url)
    res0 = r.text
    res = res0.split("<p class=\"release__version\">")[1:]
    version = ""
    i = 0
    while i < len(res):
        if "pre-release" not in res[i] or INCLUDE_BETAS:
            version = res[i].split("</p>")[0].strip().split(" ")[0].strip()
            break
        i = i + 1
    license0 = res0.split("<p><strong>License:</strong>")[1].split("</p>")[0].strip()
    license0 = license0.replace("(c)", "").split(" (")

    license = license0[0]
    for i in range(1, len(license0)):
        if "..." not in license0[i]:
            license += " (" + license0[i]

    time.sleep(0.1)
    return package, url, version, license


def elaborate_single_python_package(package_name, deps, include_self=False):
    os.system("pipdeptree -p "+package_name+" >deps.txt")

    F = open("deps.txt", "r")
    content = F.readlines()
    F.close()

    if REMOVE_DEPS_AT_END:
        os.remove("deps.txt")

    G = nx.DiGraph()
    i = 1
    dep_level = {}
    blocked = False
    blocked_level = -1
    while i < len(content):
        row = content[i].split("- ")
        level = round(len(row[0]) / 2)
        dep = row[1].split(" ")[0]
        if blocked and blocked_level == level:
            blocked = False
        if dep == "pm4pycvxopt":
            blocked = True
            blocked_level = level
        if not blocked:
            dep_level[level] = dep
            if level > 1:
                G.add_edge(dep_level[level - 1], dep_level[level])
            else:
                G.add_node(dep_level[level])
        i = i + 1
    edges = list(G.edges)
    while len(edges) > 0:
        left = set(x[0] for x in edges)
        right = set(x[1] for x in edges)
        diff = sorted([x for x in right if x not in left])
        for x in diff:
            if not x in deps:
                deps.append(x)
            G.remove_node(x)
        edges = list(G.edges)
    nodes = sorted(list(G.nodes))
    for x in nodes:
        if not x in deps:
            deps.append(x)

    if "cvxopt" in deps:
        del deps[deps.index("cvxopt")]

    if include_self:
        if package_name not in deps:
            deps.append(package_name)

    deps = sorted(deps, key=lambda x: x.lower())

    return deps


def get_all_third_party_dependencies(package_name, deps, packages_dictio, include_self=False):
    deps = elaborate_single_python_package(package_name, deps, include_self=include_self)
    packages = []
    for x in deps:
        if x not in packages_dictio:
            packages_dictio[x] = get_version(x)
        packages.append(packages_dictio[x])
    return deps, packages


deps = []
packages_dictio = {}
deps, packages = get_all_third_party_dependencies("pm4py", deps, packages_dictio, include_self=False)

if UPDATE_OTHER_FILES:
    F = open("../requirements_complete.txt", "w")
    for x in packages:
        """if x[0] == "numpy":
            F.write("%s<2\n" % (x[0]))
        elif x[0] == "pandas":
            F.write("%s<3\n" % (x[0]))
        else:
            F.write("%s\n" % (x[0]))"""
        F.write("%s\n" % (x[0]))
    F.close()
    F = open("../requirements_stable.txt", "w")
    for x in packages:
        F.write("%s==%s\n" % (x[0], x[2]))
    F.close()
    F = open("LICENSES_TRANSITIVE.md", "w")
    F.write("""# PM4Py Third Party Dependencies
    
    PM4Py depends on third party libraries to implement some functionality. This document describes which libraries
    PM4Py depends upon. This is a best effort attempt to describe the library's dependencies, it is subject to change as
    libraries are added/removed.
    
    | Name | URL | License | Version |
    | --------------------------- | ------------------------------------------------------------ | --------------------------- | ------------------- |
    """)
    for x in packages:
        F.write("| %s | %s | %s | %s |\n" % (x[0].strip(), x[1].strip(), x[3].strip(), x[2].strip()))
    F.close()

prev_deps = deepcopy(packages)

extra_packages = ["requests", "pyvis", "jsonschema", "workalendar", "scikit-learn", "openai"]
for ep in extra_packages:
    if importlib.util.find_spec(ep):
        deps, packages = get_all_third_party_dependencies(ep, deps, packages_dictio, include_self=True)

first_line_packages = ["deprecation", "packaging", "networkx", "graphviz", "six", "python-dateutil", "pytz", "tzdata", "intervaltree", "sortedcontainers", "wheel", "setuptools"]
second_line_packages = ["pydotplus", "pyparsing", "tqdm", "colorama", "cycler", "joblib", "threadpoolctl"]
third_line_packages = ["lxml", "numpy", "pandas", "scipy"]

first_packages_line = ""
second_packages_line = ""
third_packages_line = ""
fourth_package_line = ""
fifth_package_line = ""
sixth_package_line = ""

for x in packages:
    cont = x[0] + "==" + x[2] + " "
    if x[0] in first_line_packages:
        first_packages_line += cont
    elif x[0] in second_line_packages:
        second_packages_line += cont
    elif x[0] in third_line_packages:
        third_packages_line += cont
    elif x in prev_deps:
        fourth_package_line += cont
    elif x[0] in extra_packages:
        sixth_package_line += cont
    else:
        fifth_package_line += cont

F = open("../Dockerfile", "r")
dockerfile_contents = F.readlines()
F.close()

before_lines = []
after_lines = []
found_line = False

i = 0
while i < len(dockerfile_contents):
    if dockerfile_contents[i].startswith("RUN pip3 install") and not "-U" in dockerfile_contents[i]:
        found_line = True
    elif found_line:
        after_lines.append(dockerfile_contents[i])
    else:
        before_lines.append(dockerfile_contents[i])
    i = i + 1

stru = "".join(before_lines + ["RUN pip3 install " + x + "\n" for x in [first_packages_line, second_packages_line, third_packages_line, fourth_package_line, fifth_package_line, sixth_package_line]] + after_lines)
stru = stru.strip() + "\n"

if UPDATE_DOCKERFILE:
    F = open("../Dockerfile", "w")
    F.write(stru)
    F.close()
else:
    print(stru)