-
Notifications
You must be signed in to change notification settings - Fork 5
/
gorebuild
executable file
·111 lines (92 loc) · 3.74 KB
/
gorebuild
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
#!/usr/bin/python
import os
import sys
import json
import networkx as nx
import logging
from collections import defaultdict
logging.basicConfig(format="%(message)s", level=logging.INFO)
rebuild_list = set(sys.argv[1:])
pkglist = rebuild_list.copy()
reverse_deps = defaultdict(set)
G = nx.DiGraph()
with open(os.path.join(sys.path[0], "package.db"), "r") as f:
package_db = json.load(f)
for pkg in package_db:
package_db[pkg]["depends"] = {dep.split("=")[0].split(">")[0].split("<")[0] for dep in package_db[pkg]["depends"]}
package_db[pkg]["makedepends"] = {dep.split("=")[0].split(">")[0].split("<")[0] for dep in package_db[pkg]["makedepends"]}
package_db[pkg]["checkdepends"] = {dep.split("=")[0].split(">")[0].split("<")[0] for dep in package_db[pkg]["checkdepends"]}
def cached_get_reverse_dep(pkg):
if pkg not in reverse_deps:
if not ({"go", "go-pie"} & (set(package_db[pkg]["depends"]) | set(package_db[pkg]["makedepends"]))):
print(package_db[pkg]["makedepends"])
return reverse_deps[pkg]
for _pkg in package_db:
if not ({"go", "go-pie"} & (set(package_db[_pkg]["depends"]) | set(package_db[_pkg]["makedepends"]))):
continue
if pkg in package_db[_pkg]["depends"] or pkg in package_db[_pkg]["makedepends"]:
reverse_deps[pkg].add(_pkg)
return reverse_deps[pkg]
# Expand reverse dependencies
while len(pkglist) != len(reverse_deps):
for pkg in list(pkglist):
if pkg not in reverse_deps:
pkglist |= cached_get_reverse_dep(pkg)
G.add_nodes_from(reverse_deps.keys())
for dep, pkgs in reverse_deps.items():
for pkg in pkgs:
G.add_edge(dep, pkg)
# Remove source only packages
for dep, pkgs in reverse_deps.items():
if package_db[dep]["arch"] == "any":
G.remove_node(dep)
while True:
try:
cycle = nx.find_cycle(G)
cycle_pkgs = set()
cycle_pkgs_flatten = set()
for edge in cycle:
cycle_pkgs |= set(edge)
for pkg in edge:
if " " not in pkg:
cycle_pkgs_flatten.add(pkg)
else:
cycle_pkgs_flatten |= set(pkg.split())
logging.info("Found circular dependency: " + "<->".join(cycle_pkgs_flatten))
new_pkg = " ".join(cycle_pkgs_flatten)
package_db[new_pkg] = dict(depends=set())
for pkg in cycle_pkgs:
package_db[new_pkg]["depends"] |= package_db[pkg]["depends"]
for _pkg in package_db:
if pkg in package_db[_pkg]["depends"]:
package_db[_pkg]["depends"].add(new_pkg)
for edge in list(G.edges):
if edge[0] in cycle_pkgs:
G.add_edge(new_pkg, edge[1])
if edge[1] in cycle_pkgs:
G.add_edge(edge[0], new_pkg)
G.remove_nodes_from(cycle_pkgs)
except nx.exception.NetworkXNoCycle:
break
for pkg in nx.lexicographical_topological_sort(G):
if " " not in pkg:
print(pkg, end=' ')
else:
NG = nx.DiGraph()
NG.add_nodes_from(pkg.split())
for dep, pkgs in reverse_deps.items():
for _pkg in pkgs:
if _pkg in pkg and dep in pkg:
NG.add_edge(dep, _pkg)
while True:
try:
cycle = nx.find_cycle(NG)
for edge in cycle:
if edge[0] not in package_db[edge[1]]["depends"]:
logging.info("Removing soft dep to solve circular dependency: " + "<-".join(edge))
NG.remove_edge(*edge)
break
except nx.exception.NetworkXNoCycle:
break
print(" ".join(nx.lexicographical_topological_sort(NG)), end=' ')
print()