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
|
#!/usr/bin/env python
import re
import sys
import argparse
class PackageGraph:
def __init__(self, depends_file):
self.nodes = set()
self.adjlist = dict()
# pkgname\tdepends\tpkgbase\tpkgver
with open(depends_file) as f:
for line in f:
line = line.strip()
elem = line.strip().split()
assert len(elem) == 4
elem[1] = re.split('>|=|<', elem[1])[0]
assert elem[0] == elem[2]
if elem[0] == elem[1]:
elem[1] = '{}*'.format(elem[1])
if elem[0] not in self.adjlist:
self.adjlist[elem[0]] = set()
self.adjlist[elem[0]].add((elem[1], line))
for node in self.adjlist.keys():
self.nodes.add(node)
def traverse_and_print_without_sub_reccur(self, node_info, nodes_color, exclude_pkgs):
node = node_info[0]
if node in exclude_pkgs:
return
if node not in self.nodes:
print(node_info[1])
return
if nodes_color[node] == 2:
return
if nodes_color[node] == 1:
print("Contain a loop!", file=sys.stderr)
exit()
print(node_info[1])
nodes_color[node] = 1
for child_info in self.adjlist[node]:
self.traverse_and_print_without_sub_reccur(child_info, nodes_color, exclude_pkgs)
nodes_color[node] = 2
def traverse_and_print_without_sub(self, exclude_pkgs, start_pkgs):
'''
0: white, not visited
1: grey, being visited
2: black, already visited
'''
nodes_color = {}
for node in self.nodes:
nodes_color[node] = 0
for node in start_pkgs:
for child_info in self.adjlist[node]:
self.traverse_and_print_without_sub_reccur(child_info, nodes_color, exclude_pkgs)
def get_args():
parser = argparse.ArgumentParser(prog='aur-prunedep')
parser.add_argument("-e", "--exclude-file",
required=True,
type=str,
help='file list package name that need to filter out line by line')
parser.add_argument("-s", "--start-file",
required=True,
type=str,
help='file list package names that are root of dependency graph')
parser.add_argument("-f", "--depends-file",
required=True,
type=str,
help='output of aur depends --tables')
return parser.parse_args()
def main(args):
exclude_pkgs = set()
with open(args.exclude_file) as f:
for line in f:
line = line.strip()
exclude_pkgs.add(line)
start_pkgs = set()
with open(args.start_file) as f:
for line in f:
line = line.strip()
start_pkgs.add(line)
start_pkgs = start_pkgs - exclude_pkgs
graph = PackageGraph(args.depends_file)
graph.traverse_and_print_without_sub(exclude_pkgs, start_pkgs)
if __name__ == '__main__':
main(get_args())
|