Commit dace8e300d6820c2842de750d12b498a743bcfe5
Committed by
Linus Torvalds
1 parent
bcde44ed7d
Exists in
master
and in
20 other branches
scripts/get_maintainer.pl: add interactive mode
This is a first version of an interactive mode for scripts/get_maintainer.pl. It allows the user to interact with the script. Each cc candidate can be selected and deselected and a shortlog of authored commits can be displayed for each candidate. The menu is displayed via STDERR, the end result is outputted to STDOUT. This unusual mechanism allows using get_maintainer.pl in interactive mode via git send-email --cc-cmd. Signed-off-by: Joe Perches <joe@perches.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 141 additions and 5 deletions Side-by-side Diff
scripts/get_maintainer.pl
... | ... | @@ -33,6 +33,7 @@ |
33 | 33 | my $email_git_min_percent = 5; |
34 | 34 | my $email_git_since = "1-year-ago"; |
35 | 35 | my $email_hg_since = "-365"; |
36 | +my $interactive = 0; | |
36 | 37 | my $email_remove_duplicates = 1; |
37 | 38 | my $output_multiline = 1; |
38 | 39 | my $output_separator = ", "; |
... | ... | @@ -52,6 +53,8 @@ |
52 | 53 | |
53 | 54 | my $exit = 0; |
54 | 55 | |
56 | +my %shortlog_buffer; | |
57 | + | |
55 | 58 | my @penguin_chief = (); |
56 | 59 | push(@penguin_chief, "Linus Torvalds:torvalds\@linux-foundation.org"); |
57 | 60 | #Andrew wants in on most everything - 2009/01/14 |
... | ... | @@ -93,7 +96,8 @@ |
93 | 96 | "blame_range_cmd" => "git blame -l -L \$diff_start,+\$diff_length \$file", |
94 | 97 | "blame_file_cmd" => "git blame -l \$file", |
95 | 98 | "commit_pattern" => "^commit [0-9a-f]{40,40}", |
96 | - "blame_commit_pattern" => "^([0-9a-f]+) " | |
99 | + "blame_commit_pattern" => "^([0-9a-f]+) ", | |
100 | + "shortlog_cmd" => "git log --no-color --oneline --since=\$email_git_since --author=\"\$email\" -- \$file" | |
97 | 101 | ); |
98 | 102 | |
99 | 103 | my %VCS_cmds_hg = ( |
... | ... | @@ -107,7 +111,8 @@ |
107 | 111 | "blame_range_cmd" => "", # not supported |
108 | 112 | "blame_file_cmd" => "hg blame -c \$file", |
109 | 113 | "commit_pattern" => "^commit [0-9a-f]{40,40}", |
110 | - "blame_commit_pattern" => "^([0-9a-f]+):" | |
114 | + "blame_commit_pattern" => "^([0-9a-f]+):", | |
115 | + "shortlog_cmd" => "ht log --date=\$email_hg_since" | |
111 | 116 | ); |
112 | 117 | |
113 | 118 | my $conf = which_conf(".get_maintainer.conf"); |
... | ... | @@ -148,6 +153,7 @@ |
148 | 153 | 'git-min-percent=i' => \$email_git_min_percent, |
149 | 154 | 'git-since=s' => \$email_git_since, |
150 | 155 | 'hg-since=s' => \$email_hg_since, |
156 | + 'i|interactive!' => \$interactive, | |
151 | 157 | 'remove-duplicates!' => \$email_remove_duplicates, |
152 | 158 | 'm!' => \$email_maintainer, |
153 | 159 | 'n!' => \$email_usename, |
... | ... | @@ -225,6 +231,8 @@ |
225 | 231 | $signaturePattern = "(.+?)[Bb][Yy]:"; |
226 | 232 | } |
227 | 233 | |
234 | + | |
235 | + | |
228 | 236 | ## Read MAINTAINERS for type/value pairs |
229 | 237 | |
230 | 238 | my @typevalue = (); |
231 | 239 | |
... | ... | @@ -450,10 +458,13 @@ |
450 | 458 | ($email_git || ($email_git_fallback && !$exact_pattern_match))) { |
451 | 459 | vcs_file_signoffs($file); |
452 | 460 | } |
453 | - | |
454 | 461 | if ($email && $email_git_blame) { |
455 | 462 | vcs_file_blame($file); |
456 | 463 | } |
464 | + if ($email && $interactive){ | |
465 | + vcs_file_shortlogs($file); | |
466 | + | |
467 | + } | |
457 | 468 | } |
458 | 469 | |
459 | 470 | if ($keywords) { |
460 | 471 | |
... | ... | @@ -486,9 +497,13 @@ |
486 | 497 | } |
487 | 498 | } |
488 | 499 | |
500 | + | |
489 | 501 | if ($email || $email_list) { |
490 | 502 | my @to = (); |
491 | 503 | if ($email) { |
504 | + if ($interactive) { | |
505 | + @email_to = @{vcs_interactive_menu(\@email_to)}; | |
506 | + } | |
492 | 507 | @to = (@to, @email_to); |
493 | 508 | } |
494 | 509 | if ($email_list) { |
... | ... | @@ -501,7 +516,6 @@ |
501 | 516 | @scm = uniq(@scm); |
502 | 517 | output(@scm); |
503 | 518 | } |
504 | - | |
505 | 519 | if ($status) { |
506 | 520 | @status = uniq(@status); |
507 | 521 | output(@status); |
... | ... | @@ -556,6 +570,7 @@ |
556 | 570 | --git-blame => use git blame to find modified commits for patch or file |
557 | 571 | --git-since => git history to use (default: $email_git_since) |
558 | 572 | --hg-since => hg history to use (default: $email_hg_since) |
573 | + --interactive => display a menu (mostly useful if used with the --git option) | |
559 | 574 | --m => include maintainer(s) if any |
560 | 575 | --n => include name 'Full Name <addr\@domain.tld>' |
561 | 576 | --l => include list(s) if any |
... | ... | @@ -1156,6 +1171,127 @@ |
1156 | 1171 | return 0; |
1157 | 1172 | } |
1158 | 1173 | |
1174 | +sub vcs_interactive_menu { | |
1175 | + my $list_ref = shift; | |
1176 | + my @list = @$list_ref; | |
1177 | + | |
1178 | + return if (!vcs_exists()); | |
1179 | + | |
1180 | + my %selected; | |
1181 | + my %shortlog; | |
1182 | + my $input; | |
1183 | + my $count = 0; | |
1184 | + | |
1185 | + #select maintainers by default | |
1186 | + foreach my $entry (@list){ | |
1187 | + my $role = $entry->[1]; | |
1188 | + $selected{$count} = ($role =~ /maintainer:|supporter:/); | |
1189 | + $count++; | |
1190 | + } | |
1191 | + | |
1192 | + #menu loop | |
1193 | + do { | |
1194 | + my $count = 0; | |
1195 | + foreach my $entry (@list){ | |
1196 | + my $email = $entry->[0]; | |
1197 | + my $role = $entry->[1]; | |
1198 | + if ($selected{$count}){ | |
1199 | + print STDERR "* "; | |
1200 | + } else { | |
1201 | + print STDERR " "; | |
1202 | + } | |
1203 | + print STDERR "$count: $email,\t\t $role"; | |
1204 | + print STDERR "\n"; | |
1205 | + if ($shortlog{$count}){ | |
1206 | + my $entries_ref = vcs_get_shortlog($email); | |
1207 | + foreach my $entry_ref (@{$entries_ref}){ | |
1208 | + my $filename = @{$entry_ref}[0]; | |
1209 | + my @shortlog = @{@{$entry_ref}[1]}; | |
1210 | + print STDERR "\tshortlog for $filename (authored commits: " . @shortlog . ").\n"; | |
1211 | + foreach my $commit (@shortlog){ | |
1212 | + print STDERR "\t $commit\n"; | |
1213 | + } | |
1214 | + print STDERR "\n"; | |
1215 | + } | |
1216 | + } | |
1217 | + $count++; | |
1218 | + } | |
1219 | + print STDERR "\n"; | |
1220 | + print STDERR "Choose whom to cc by entering a commaseperated list of numbers and hitting enter.\n"; | |
1221 | + print STDERR "To show a short list of commits, precede the number by a '?',\n"; | |
1222 | + print STDERR "A blank line indicates that you are satisfied with your choice.\n"; | |
1223 | + $input = <STDIN>; | |
1224 | + chomp($input); | |
1225 | + | |
1226 | + my @wish = split(/[, ]+/,$input); | |
1227 | + foreach my $nr (@wish){ | |
1228 | + my $logtoggle = 0; | |
1229 | + if ($nr =~ /\?/){ | |
1230 | + $nr =~ s/\?//; | |
1231 | + $logtoggle = 1; | |
1232 | + } | |
1233 | + | |
1234 | + #skip out of bounds numbers | |
1235 | + next unless ($nr <= $count && $nr >= 0); | |
1236 | + | |
1237 | + if ($logtoggle){ | |
1238 | + $shortlog{$nr} = !$shortlog{$nr}; | |
1239 | + } else { | |
1240 | + $selected{$nr} = !$selected{$nr}; | |
1241 | + | |
1242 | + #switch shortlog on if an entry get's selected | |
1243 | + if ($selected{$nr}){ | |
1244 | + $shortlog{$nr}=1; | |
1245 | + } | |
1246 | + } | |
1247 | + }; | |
1248 | + } while(length($input) > 0); | |
1249 | + | |
1250 | + #drop not selected entries | |
1251 | + $count = 0; | |
1252 | + my @new_emailto; | |
1253 | + foreach my $entry (@list){ | |
1254 | + if ($selected{$count}){ | |
1255 | + push(@new_emailto,$list[$count]); | |
1256 | + print STDERR "$count: "; | |
1257 | + print STDERR $email_to[$count]->[0]; | |
1258 | + print STDERR ",\t\t "; | |
1259 | + print STDERR $email_to[$count]->[1]; | |
1260 | + print STDERR "\n"; | |
1261 | + } | |
1262 | + $count++; | |
1263 | + } | |
1264 | + return \@new_emailto; | |
1265 | +} | |
1266 | + | |
1267 | +sub vcs_get_shortlog { | |
1268 | + my $arg = shift; | |
1269 | + my ($name, $address) = parse_email($arg); | |
1270 | + return $shortlog_buffer{$address}; | |
1271 | +} | |
1272 | + | |
1273 | +sub vcs_file_shortlogs { | |
1274 | + my ($file) = @_; | |
1275 | + print STDERR "shortlog processing $file:"; | |
1276 | + foreach my $entry (@email_to){ | |
1277 | + my ($name, $address) = parse_email($entry->[0]); | |
1278 | + print STDERR "."; | |
1279 | + my $commits_ref = vcs_email_shortlog($address, $file); | |
1280 | + push(@{$shortlog_buffer{$address}}, [ $file, $commits_ref ]); | |
1281 | + } | |
1282 | + print STDERR "\n"; | |
1283 | +} | |
1284 | + | |
1285 | +sub vcs_email_shortlog { | |
1286 | + my $email = shift; | |
1287 | + my ($file) = @_; | |
1288 | + | |
1289 | + my $cmd = $VCS_cmds{"shortlog_cmd"}; | |
1290 | + $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables | |
1291 | + my @lines = &{$VCS_cmds{"execute_cmd"}}($cmd); | |
1292 | + return \@lines; | |
1293 | +} | |
1294 | + | |
1159 | 1295 | sub vcs_assign { |
1160 | 1296 | my ($role, $divisor, @lines) = @_; |
1161 | 1297 | |
... | ... | @@ -1236,7 +1372,7 @@ |
1236 | 1372 | my @commit_signers = (); |
1237 | 1373 | |
1238 | 1374 | my $cmd = $VCS_cmds{"find_commit_signers_cmd"}; |
1239 | - $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd | |
1375 | + $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd | |
1240 | 1376 | |
1241 | 1377 | ($commit_count, @commit_signers) = vcs_find_signers($cmd); |
1242 | 1378 |