]>
Commit | Line | Data |
---|---|---|
fa375c7f LT |
1 | #!/usr/bin/perl -w |
2 | ||
3 | use strict; | |
4e27fb06 NP |
4 | use Getopt::Std; |
5 | use File::Basename qw(basename dirname); | |
6 | ||
7 | our ($opt_h, $opt_n, $opt_s); | |
8 | getopts('hns'); | |
9 | ||
10 | $opt_h && usage(); | |
11 | ||
12 | sub usage { | |
13 | print STDERR "Usage: ${\basename $0} [-h] [-n] [-s] < <log_data>\n"; | |
14 | exit(1); | |
15 | } | |
fa375c7f | 16 | |
a24e6586 JH |
17 | my (%mailmap); |
18 | my (%email); | |
fa375c7f LT |
19 | my (%map); |
20 | my $pstate = 1; | |
21 | my $n_records = 0; | |
22 | my $n_output = 0; | |
23 | ||
fa375c7f LT |
24 | sub shortlog_entry($$) { |
25 | my ($name, $desc) = @_; | |
26 | my $key = $name; | |
27 | ||
28 | $desc =~ s#/pub/scm/linux/kernel/git/#/.../#g; | |
29 | $desc =~ s#\[PATCH\] ##g; | |
30 | ||
31 | # store description in array, in email->{desc list} map | |
32 | if (exists $map{$key}) { | |
33 | # grab ref | |
34 | my $obj = $map{$key}; | |
35 | ||
36 | # add desc to array | |
37 | push(@$obj, $desc); | |
38 | } else { | |
39 | # create new array, containing 1 item | |
40 | my @arr = ($desc); | |
41 | ||
42 | # store ref to array | |
43 | $map{$key} = \@arr; | |
44 | } | |
45 | } | |
46 | ||
47 | # sort comparison function | |
48 | sub by_name($$) { | |
49 | my ($a, $b) = @_; | |
50 | ||
51 | uc($a) cmp uc($b); | |
52 | } | |
4e27fb06 NP |
53 | sub by_nbentries($$) { |
54 | my ($a, $b) = @_; | |
55 | my $a_entries = $map{$a}; | |
56 | my $b_entries = $map{$b}; | |
57 | ||
58 | @$b_entries - @$a_entries || by_name $a, $b; | |
59 | } | |
60 | ||
61 | my $sort_method = $opt_n ? \&by_nbentries : \&by_name; | |
62 | ||
63 | sub summary_output { | |
64 | my ($obj, $num, $key); | |
65 | ||
66 | foreach $key (sort $sort_method keys %map) { | |
67 | $obj = $map{$key}; | |
68 | $num = @$obj; | |
69 | printf "%s: %u\n", $key, $num; | |
70 | $n_output += $num; | |
71 | } | |
72 | } | |
fa375c7f LT |
73 | |
74 | sub shortlog_output { | |
4e27fb06 NP |
75 | my ($obj, $num, $key, $desc); |
76 | ||
77 | foreach $key (sort $sort_method keys %map) { | |
78 | $obj = $map{$key}; | |
79 | $num = @$obj; | |
fa375c7f | 80 | |
fa375c7f | 81 | # output author |
4e27fb06 | 82 | printf "%s (%u):\n", $key, $num; |
fa375c7f LT |
83 | |
84 | # output author's 1-line summaries | |
72d7121c | 85 | foreach $desc (reverse @$obj) { |
fa375c7f LT |
86 | print " $desc\n"; |
87 | $n_output++; | |
88 | } | |
89 | ||
90 | # blank line separating author from next author | |
91 | print "\n"; | |
92 | } | |
93 | } | |
94 | ||
95 | sub changelog_input { | |
96 | my ($author, $desc); | |
97 | ||
98 | while (<>) { | |
99 | # get author and email | |
100 | if ($pstate == 1) { | |
101 | my ($email); | |
102 | ||
a24e6586 JH |
103 | next unless /^[Aa]uthor:?\s*(.*?)\s*<(.*)>/; |
104 | ||
fa375c7f | 105 | $n_records++; |
a24e6586 | 106 | |
fa375c7f LT |
107 | $author = $1; |
108 | $email = $2; | |
109 | $desc = undef; | |
110 | ||
fa375c7f LT |
111 | # cset author fixups |
112 | if (exists $mailmap{$email}) { | |
113 | $author = $mailmap{$email}; | |
114 | } elsif (exists $mailmap{$author}) { | |
115 | $author = $mailmap{$author}; | |
a24e6586 | 116 | } elsif (!$author) { |
fa375c7f LT |
117 | $author = $email; |
118 | } | |
a24e6586 | 119 | $email{$author}{$email}++; |
fa375c7f LT |
120 | $pstate++; |
121 | } | |
a24e6586 | 122 | |
fa375c7f LT |
123 | # skip to blank line |
124 | elsif ($pstate == 2) { | |
125 | next unless /^\s*$/; | |
126 | $pstate++; | |
127 | } | |
a24e6586 | 128 | |
fa375c7f LT |
129 | # skip to non-blank line |
130 | elsif ($pstate == 3) { | |
a24e6586 | 131 | next unless /^\s*?(.*)/; |
fa375c7f LT |
132 | |
133 | # skip lines that are obviously not | |
134 | # a 1-line cset description | |
135 | next if /^\s*From: /; | |
136 | ||
137 | chomp; | |
138 | $desc = $1; | |
a24e6586 | 139 | |
fa375c7f | 140 | &shortlog_entry($author, $desc); |
a24e6586 | 141 | |
fa375c7f LT |
142 | $pstate = 1; |
143 | } | |
144 | ||
145 | else { | |
146 | die "invalid parse state $pstate"; | |
147 | } | |
148 | } | |
149 | } | |
150 | ||
a24e6586 JH |
151 | sub read_mailmap { |
152 | my ($fh, $mailmap) = @_; | |
153 | while (<$fh>) { | |
154 | chomp; | |
155 | if (/^([^#].*?)\s*<(.*)>/) { | |
156 | $mailmap->{$2} = $1; | |
157 | } | |
158 | } | |
159 | } | |
160 | ||
161 | sub setup_mailmap { | |
162 | read_mailmap(\*DATA, \%mailmap); | |
163 | if (-f '.mailmap') { | |
164 | my $fh = undef; | |
165 | open $fh, '<', '.mailmap'; | |
166 | read_mailmap($fh, \%mailmap); | |
167 | close $fh; | |
168 | } | |
169 | } | |
170 | ||
fa375c7f LT |
171 | sub finalize { |
172 | #print "\n$n_records records parsed.\n"; | |
173 | ||
174 | if ($n_records != $n_output) { | |
175 | die "parse error: input records != output records\n"; | |
176 | } | |
a24e6586 JH |
177 | if (0) { |
178 | for my $author (sort keys %email) { | |
179 | my $e = $email{$author}; | |
180 | for my $email (sort keys %$e) { | |
181 | print STDERR "$author <$email>\n"; | |
182 | } | |
183 | } | |
184 | } | |
fa375c7f LT |
185 | } |
186 | ||
a24e6586 | 187 | &setup_mailmap; |
fa375c7f | 188 | &changelog_input; |
4e27fb06 | 189 | $opt_s ? &summary_output : &shortlog_output; |
fa375c7f LT |
190 | &finalize; |
191 | exit(0); | |
192 | ||
a24e6586 JH |
193 | |
194 | __DATA__ | |
195 | # | |
196 | # Even with git, we don't always have name translations. | |
197 | # So have an email->real name table to translate the | |
198 | # (hopefully few) missing names | |
199 | # | |
200 | Adrian Bunk <bunk@stusta.de> | |
201 | Andreas Herrmann <aherrman@de.ibm.com> | |
202 | Andrew Morton <akpm@osdl.org> | |
203 | Andrew Vasquez <andrew.vasquez@qlogic.com> | |
204 | Christoph Hellwig <hch@lst.de> | |
205 | Corey Minyard <minyard@acm.org> | |
206 | David Woodhouse <dwmw2@shinybook.infradead.org> | |
207 | Domen Puncer <domen@coderock.org> | |
208 | Douglas Gilbert <dougg@torque.net> | |
209 | Ed L Cashin <ecashin@coraid.com> | |
210 | Evgeniy Polyakov <johnpol@2ka.mipt.ru> | |
211 | Felix Moeller <felix@derklecks.de> | |
212 | Frank Zago <fzago@systemfabricworks.com> | |
213 | Greg Kroah-Hartman <gregkh@suse.de> | |
214 | James Bottomley <jejb@mulgrave.(none)> | |
215 | James Bottomley <jejb@titanic.il.steeleye.com> | |
216 | Jeff Garzik <jgarzik@pretzel.yyz.us> | |
217 | Jens Axboe <axboe@suse.de> | |
218 | Kay Sievers <kay.sievers@vrfy.org> | |
219 | Mitesh shah <mshah@teja.com> | |
220 | Morten Welinder <terra@gnome.org> | |
221 | Morten Welinder <welinder@anemone.rentec.com> | |
222 | Morten Welinder <welinder@darter.rentec.com> | |
223 | Morten Welinder <welinder@troll.com> | |
224 | Nguyen Anh Quynh <aquynh@gmail.com> | |
225 | Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> | |
226 | Peter A Jonsson <pj@ludd.ltu.se> | |
227 | Ralf Wildenhues <Ralf.Wildenhues@gmx.de> | |
228 | Rudolf Marek <R.Marek@sh.cvut.cz> | |
229 | Rui Saraiva <rmps@joel.ist.utl.pt> | |
230 | Sachin P Sant <ssant@in.ibm.com> | |
231 | Santtu Hyrkk\e,Av\e(B <santtu.hyrkko@gmail.com> | |
232 | Simon Kelley <simon@thekelleys.org.uk> | |
233 | Tejun Heo <htejun@gmail.com> | |
234 | Tony Luck <tony.luck@intel.com> |