forked from saltstack/salt
-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathcommitter_parser.py
More file actions
162 lines (130 loc) · 4.58 KB
/
Copy pathcommitter_parser.py
File metadata and controls
162 lines (130 loc) · 4.58 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# committer_parser.py
#
# Simple script to parse the output of 'git log' and generate some statistics.
# May leverage GitHub API in the future
#
'''
To use this commit parser script pipe git log into the stdin:
git log | committer_parser.py -c -
'''
# pylint: disable=resource-leakage
# Import python libs
from __future__ import absolute_import
from __future__ import print_function
import sys
import getopt
import re
import email.utils
import datetime
class Usage(Exception):
def __init__(self, msg): # pylint: disable=W0231
self.msg = 'committer_parser.py [-c | --contributor-detail] - |' \
' <logfilename>\n'
self.msg += ' : Parse commit log from git and print number of ' \
'commits and unique committers\n'
self.msg += ' : by month. Accepts a filename or reads from stdin.\n'
self.msg += ' : -c | --contributor-detail generates output by ' \
'contributor, by month, in a tab-separated table\n'
if msg:
self.msg += '\n'
self.msg += msg
def parse_date(datestr):
d = email.utils.parsedate(datestr)
return datetime.datetime(d[0], d[1], d[2], d[3], d[4], d[5], d[6])
def parse_gitlog(filename=None):
'''
Parse out the gitlog cli data
'''
results = {}
commits = {}
commits_by_contributor = {}
if not filename or filename == '-':
fh = sys.stdin
else:
fh = open(filename, 'r+')
try:
commitcount = 0
for line in fh.readlines():
line = line.rstrip()
if line.startswith('commit '):
new_commit = True
commitcount += 1
continue
if line.startswith('Author:'):
author = re.match(r'Author:\s+(.*)\s+<(.*)>', line)
if author:
email = author.group(2)
continue
if line.startswith('Date:'):
isodate = re.match(r'Date:\s+(.*)', line)
d = parse_date(isodate.group(1))
continue
if len(line) < 2 and new_commit:
new_commit = False
key = '{0}-{1}'.format(d.year, str(d.month).zfill(2))
if key not in results:
results[key] = []
if key not in commits:
commits[key] = 0
if email not in commits_by_contributor:
commits_by_contributor[email] = {}
if key not in commits_by_contributor[email]:
commits_by_contributor[email][key] = 1
else:
commits_by_contributor[email][key] += 1
if email not in results[key]:
results[key].append(email)
commits[key] += commitcount
commitcount = 0
finally:
fh.close()
return (results, commits, commits_by_contributor)
def counts_by_contributor(commits_by_contributor, results):
output = ''
dates = sorted(results.keys())
for d in dates:
output += '\t{0}'.format(d)
output += '\n'
for email in sorted(commits_by_contributor.keys()):
output += '\'{0}'.format(email)
for d in dates:
if d in commits_by_contributor[email]:
output += '\t{0}'.format(commits_by_contributor[email][d])
else:
output += '\t'
output += '\n'
return output
def count_results(results, commits):
result_str = ''
print('Date\tContributors\tCommits')
for k in sorted(results.keys()):
result_str += '{0}\t{1}\t{2}'.format(k, len(results[k]), commits[k])
result_str += '\n'
return result_str
def main(argv=None):
if argv is None:
argv = sys.argv
try:
try:
opts, args = getopt.getopt(argv[1:], 'hc', ['help', 'contributor-detail'])
if len(args) < 1:
raise Usage('committer_parser.py needs a filename or \'-\' to read from stdin')
except getopt.error as msg:
raise Usage(msg)
except Usage as err:
print(err.msg, file=sys.stderr)
return 2
if len(opts) > 0:
if '-h' in opts[0] or '--help' in opts[0]:
return 0
data, counts, commits_by_contributor = parse_gitlog(filename=args[0])
if len(opts) > 0:
if '-c' or '--contributor-detail':
print(counts_by_contributor(commits_by_contributor, data))
else:
print(count_results(data, counts))
if __name__ == "__main__":
sys.exit(main())