git ssb

1+

Daan Patchwork / patchwork



Tree: bfad9d94f6fd6b6ee044e8305e9ce1f7bc1dc32b

Files: bfad9d94f6fd6b6ee044e8305e9ce1f7bc1dc32b / depeject.py

3879 bytesRaw
1#!/usr/bin/env python3
2
3from pprint import pprint
4import re
5import json
6import subprocess as sp
7from collections import defaultdict
8from graphviz import Digraph
9import pickle
10
11NEEDS_CALL = "rg --json -t js --multiline exports.needs[^\)]*\)"
12GIVES_CALL = "rg --json -t js --multiline exports.gives[^\)]*\)"
13
14PARENTHESIS_EXTRACTION_RE = re.compile(r'\(([^)]+)')
15
16def parse_ripgrep(lines):
17 for line in lines:
18 if not line.strip():
19 continue
20 line = json.loads(line)
21 if line['type'] != 'match':
22 continue
23 file_name = line['data']['path']['text']
24 matched_text = line['data']['lines']['text']
25 assert len(line['data']['submatches']) == 1, json.dumps(line, indent=2)
26 yield file_name, matched_text
27
28
29JS_TEMPLATE = '''
30const nest = require('depnest')
31
32console.log(JSON.stringify(nest({obj_str})))
33'''
34
35def flatten(d):
36 for k, v in d.items():
37 if type(v) == bool:
38 assert v, d
39 yield k
40 continue
41 if type(v) == str:
42 # print(v)
43 yield k
44 continue
45 v_postfixes = flatten(v)
46 for postfix in v_postfixes:
47 yield f'{k}.{postfix}'
48
49def edges(rg_matches):
50 rg_matches = list(parse_ripgrep(rg_matches.split('\n')))
51 # print(len(rg_matches))
52 result = dict()
53 for fn, text in rg_matches:
54 # print('='*80)
55 # print(f'{fn}\n{text}')
56 # print()
57 if 'nest(' in text:
58 obj_str = text[text.find('(')+1:text.find(')')]
59 else:
60 obj_str = text[text.find('{'):text.rfind('}')+1]
61 obj_str = sp.check_output(['node', '-e', JS_TEMPLATE.format(obj_str=obj_str)])
62 obj_str = obj_str.decode()
63 obj = json.loads(obj_str)
64 # print(json.dumps(obj, indent=2))
65 # print()
66 # print('\n'.join(list(flatten(obj))))
67 result[fn] = list(flatten(obj))
68 return result
69
70if __name__ == '__main__':
71 gives_rg = sp.check_output(GIVES_CALL.split()).decode()
72 gives = edges(gives_rg)
73
74 needs_rg = sp.check_output(NEEDS_CALL.split()).decode()
75 needs = edges(needs_rg)
76
77 # for every method: which files provide this method?
78 providers = defaultdict(list)
79 for filename, methods in gives.items():
80 for method in methods:
81 providers[method].append(filename)
82 providers = dict(providers)
83
84 pprint(providers)
85
86 # for every file: which other files does this depend on, and for which method?
87 dependencies = defaultdict(list)
88 # for every file: which other files depend on this, and for which method?
89 dependents = defaultdict(list)
90 for filename, methods in needs.items():
91 for method in methods:
92 method_providers = providers.get(method, ['UNKNOWN'])
93 dependencies[filename] += [(mp, method) for mp in method_providers]
94 for mp in method_providers:
95 dependents[mp].append((filename, method))
96 dependencies = dict(dependencies)
97
98 # for p in providers.keys():
99 # _ = dependents[p]
100 dependents = dict(dependents)
101 print('='*80)
102 pprint(dependencies)
103 print('='*80)
104 pprint(dependents)
105 print('='*80)
106
107 sortedProviders = list(sorted(dependents.keys(), key=lambda k: len(dependents[k])))
108 counts = {k: len(dependents[k]) for k in sortedProviders}
109
110 max_count = len(str(max(*counts.values())))
111 max_len = len(max(*counts.keys(), key=len))
112 print(max_count, max_len)
113
114 print('-'*80)
115 for k in sortedProviders:
116 print(f'{counts[k]:{max_count}}\t{k:{max_len}}')
117
118 with open('results.pickle', 'wb') as f:
119 pickle.dump({
120 'gives': gives,
121 'needs': needs,
122 'counts': counts,
123 'providers': providers,
124 'dependents': dependents,
125 'dependencies': dependencies,
126 }, f)
127
128 # dot = Digraph(comment='Dependencies')
129 #
130 # for filename in dependencies.keys():
131 # dot.node(filename)
132 #
133 # for filename, deps in dependencies.items():
134 # for dep, api in deps:
135 # dot.edge(filename, dep, label=api)
136 #
137 # print(dot.source)
138 #
139 # with open('dependencies.dot', 'w') as f:
140 # f.write(dot.source)
141 #
142
143

Built with git-ssb-web