-
Notifications
You must be signed in to change notification settings - Fork 8
/
get-prefix
executable file
·82 lines (75 loc) · 2.42 KB
/
get-prefix
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
# Copyright 2016 Kees Cook <keescook@chromium.org>
# License: GPLv2+
#
# Figure out the top 5 most common prefixes used for a given set of files,
# within the last 64 commits touching those files, with the first argument
# being the fall-back when nothing is better.
#
# e.g.
# $ get-prefix unknown kernel/seccomp.c
# seccomp:
# signal:
# ptrace, seccomp:
# syscalls:
# syscall_get_arch:
#
import sys, re, fnmatch, subprocess, operator
debug = False
# Update the copy in split-on-maintainer...
def get_prefixes(area, paths):
# "--follow" is very slow, but sometime needed:
#ret = subprocess.run(['git', 'log', '-n', '64', '--no-merges', '--oneline', '--follow', '--'] + paths,
ret = subprocess.run(['git', 'log', '-n', '64', '--no-merges', '--oneline', '--'] + paths,
stdout=subprocess.PIPE, check=False)
commits = str(ret.stdout, 'utf-8').strip().splitlines()
prefixes = dict()
for commit in commits:
title = commit.split(' ', 1)[1].strip()
# Drop old-style []s
if '[PATCH]' in title:
title = title.replace('[PATCH]','').strip()
if '[' in title:
prefix = title.partition(']')[0].replace('[','').replace(']','')
title = title.replace('[%s]' % (prefix), '').strip()
if not title.startswith(':'):
prefix += ': '
title = prefix.lower() + title
if title.startswith('Revert "'):
continue
if ':' in title:
prefix = title.rpartition(':')[0]
# Ignore useless prefixes.
if not prefix in ['net', 'treewide']:
prefixes.setdefault(prefix, 0.0)
# Count # of files in commit.
sha = commit.split(' ', 1)[0].strip()
wc = subprocess.run(['git', 'show', '--format=', '--name-status', sha],
stdout=subprocess.PIPE, check=False)
files = str(wc.stdout, 'utf-8').strip().splitlines()
divisor = len(files)
if divisor == 0:
divisor = 1
divisor = float(divisor)
prefixes[prefix] += 1.0 / divisor
best = 0.0
prefix = None
likely = sorted(prefixes.items(), key=operator.itemgetter(1), reverse=True)
count = len(likely)
if count == 0:
print("%s:" % area)
return
if count > 5 and not debug:
count = 5
for i in range(count):
if debug:
print("%f %s:" % (likely[i][1], likely[i][0]))
else:
print("%s:" % (likely[i][0]))
if len(sys.argv) > 1:
get_prefixes(sys.argv[1], sys.argv[2:])
else:
ret = subprocess.run(['diffstat', '-lp1'],
stdout=subprocess.PIPE, check=False)
paths = str(ret.stdout, 'utf-8').strip().splitlines()
get_prefixes("unknown", paths)