summaryrefslogtreecommitdiffstats
path: root/aur-prunedep
blob: 38e6d8ac2e9373922f22ed25976b9bf4c1b93ca7 (plain) (blame)
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())