forked from aws/aws-cdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dependencies.py
82 lines (60 loc) · 1.88 KB
/
dependencies.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
#!/usr/bin/env python3
import json
import sys
import collections
import os
from os import path
def full_dependency_graph():
"""Return a map of { package -> [package] }."""
graph = collections.defaultdict(set)
for filename in package_jsons():
with open(filename) as f:
package_json = json.load(f)
for key in ['devDependencies', 'dependencies']:
if key in package_json:
graph[package_json['name']].update(package_json[key].keys())
return graph
def local_dependency_graph():
"""Retain only the dependencies that are also in the repo."""
graph = full_dependency_graph()
for deps in graph.values():
deps.intersection_update(graph.keys())
return graph
def package_jsons():
"""Return a list of all package.json files in this project."""
rootdir = path.dirname(path.dirname(path.realpath(__file__)))
for root, dirs, files in os.walk(rootdir):
if 'node_modules' in dirs:
dirs.remove('node_modules')
if 'package.json' in files:
yield path.join(root, 'package.json')
def find(xs, x):
for i, value in enumerate(xs):
if x == value:
return i
return None
def print_graph(graph):
for package, deps in graph.items():
for dep in deps:
print('%s -> %s' % (package, dep))
checked = set()
# Do a check for cycles for each package. This is slow but it works,
# and it has the advantage that it can give good diagnostics.
def check_for_cycles(package, path):
i = find(path, package)
if i is not None:
cycle = path[i:] + [package]
print('Cycle: %s' % ' => '.join(cycle))
return
if package in checked:
return
checked.add(package)
deps = graph.get(package, [])
for dep in deps:
check_for_cycles(dep, path + [package])
for package in graph.keys():
check_for_cycles(package, [])
def main():
print_graph(local_dependency_graph())
if __name__ == '__main__':
main()