Commit dace8e300d6820c2842de750d12b498a743bcfe5

Authored by Florian Mickler
Committed by Linus Torvalds
1 parent bcde44ed7d

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