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
|
#! /usr/bin/env ruby
require 'date'
require 'pp'
require 'set'
REGEX = /(\w+)\s+'(.+)'\s+(.*)/
Commit = Struct.new(:hash, :time, :author, :stats)
CommitStats = Struct.new(:files, :nr_added, :nr_deleted)
def calc_stats(diff)
changed = Set.new
added = 0
deleted = 0
diff.lines.each do |l|
case l.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
when /^\+\+\+ (\S+)/
changed << $1
when /^\+/
added = added + 1
when /^---/
# do nothing
when /^\-/
deleted = deleted + 1
end
end
CommitStats.new(changed, added, deleted)
end
def select_commits(&block)
commits = []
input = `git log --format="%h '%aI' %an"`
input.lines.each do |l|
m = REGEX.match(l)
raise "couldn't parse: ${l}" unless m
hash = m[1]
time = DateTime.iso8601(m[2])
author = m[3]
if block.call(hash, time, author)
diff = `git log -1 -p #{hash} | filterdiff -X configure`
commits << Commit.new(hash, time, author, calc_stats(diff))
end
end
commits
end
def since(date)
lambda do |hash, time, author|
time >= date
end
end
def pad(str, col)
str + (' ' * (col - str.size))
end
def code_delta(s)
s.nr_added + s.nr_deleted
end
def cmp_stats(lhs, rhs)
code_delta(rhs) <=> code_delta(lhs)
end
#-----------------------------------
commits = select_commits(&since(DateTime.now - 14))
authors = Hash.new {|hash, key| hash[key] = CommitStats.new(Set.new, 0, 0)}
commits.each do |c|
author_stats = authors[c.author]
author_stats.files.merge(c.stats.files)
author_stats.nr_added = author_stats.nr_added + c.stats.nr_added
author_stats.nr_deleted = author_stats.nr_deleted + c.stats.nr_deleted
end
puts "#{pad("Author", 20)}\tChanged files\tInsertions\tDeletions"
authors.keys.sort {|a1, a2| cmp_stats(authors[a1], authors[a2])}.each do |k|
v = authors[k]
puts "#{pad(k, 20)}\t#{v.files.size}\t\t#{v.nr_added}\t\t#{v.nr_deleted}"
end
|