diff options
Diffstat (limited to 'scripts')
| -rwxr-xr-x | scripts/get_maintainer.pl | 152 |
1 files changed, 96 insertions, 56 deletions
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 5132949500c1..1200d724e73b 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | use strict; | 13 | use strict; |
| 14 | 14 | ||
| 15 | my $P = $0; | 15 | my $P = $0; |
| 16 | my $V = '0.19'; | 16 | my $V = '0.20'; |
| 17 | 17 | ||
| 18 | use Getopt::Long qw(:config no_auto_abbrev); | 18 | use Getopt::Long qw(:config no_auto_abbrev); |
| 19 | 19 | ||
| @@ -258,11 +258,8 @@ if ($email) { | |||
| 258 | foreach my $chief (@penguin_chief) { | 258 | foreach my $chief (@penguin_chief) { |
| 259 | if ($chief =~ m/^(.*):(.*)/) { | 259 | if ($chief =~ m/^(.*):(.*)/) { |
| 260 | my $email_address; | 260 | my $email_address; |
| 261 | if ($email_usename) { | 261 | |
| 262 | $email_address = format_email($1, $2); | 262 | $email_address = format_email($1, $2); |
| 263 | } else { | ||
| 264 | $email_address = $2; | ||
| 265 | } | ||
| 266 | if ($email_git_penguin_chiefs) { | 263 | if ($email_git_penguin_chiefs) { |
| 267 | push(@email_to, $email_address); | 264 | push(@email_to, $email_address); |
| 268 | } else { | 265 | } else { |
| @@ -400,21 +397,57 @@ sub top_of_kernel_tree { | |||
| 400 | return 0; | 397 | return 0; |
| 401 | } | 398 | } |
| 402 | 399 | ||
| 403 | sub format_email { | 400 | sub parse_email { |
| 404 | my ($name, $email) = @_; | 401 | my ($formatted_email) = @_; |
| 402 | |||
| 403 | my $name = ""; | ||
| 404 | my $address = ""; | ||
| 405 | |||
| 406 | if ($formatted_email =~ /^([^<]+)<(.*\@.*)>$/) { | ||
| 407 | $name = $1; | ||
| 408 | $address = $2; | ||
| 409 | } elsif ($formatted_email =~ /^<(.*\@.*)>$/) { | ||
| 410 | $address = $1; | ||
| 411 | } elsif ($formatted_email =~ /^(.*\@.*)$/) { | ||
| 412 | $address = $1; | ||
| 413 | } | ||
| 405 | 414 | ||
| 406 | $name =~ s/^\s+|\s+$//g; | 415 | $name =~ s/^\s+|\s+$//g; |
| 407 | $name =~ s/^\"|\"$//g; | 416 | $name =~ s/^\"|\"$//g; |
| 408 | $email =~ s/^\s+|\s+$//g; | 417 | $address =~ s/^\s+|\s+$//g; |
| 409 | 418 | ||
| 410 | my $formatted_email = ""; | 419 | if ($name =~ /[^a-z0-9 \.\-]/i) { ##has "must quote" chars |
| 420 | $name =~ s/(?<!\\)"/\\"/g; ##escape quotes | ||
| 421 | $name = "\"$name\""; | ||
| 422 | } | ||
| 423 | |||
| 424 | return ($name, $address); | ||
| 425 | } | ||
| 426 | |||
| 427 | sub format_email { | ||
| 428 | my ($name, $address) = @_; | ||
| 429 | |||
| 430 | my $formatted_email; | ||
| 431 | |||
| 432 | $name =~ s/^\s+|\s+$//g; | ||
| 433 | $name =~ s/^\"|\"$//g; | ||
| 434 | $address =~ s/^\s+|\s+$//g; | ||
| 411 | 435 | ||
| 412 | if ($name =~ /[^a-z0-9 \.\-]/i) { ##has "must quote" chars | 436 | if ($name =~ /[^a-z0-9 \.\-]/i) { ##has "must quote" chars |
| 413 | $name =~ s/(?<!\\)"/\\"/g; ##escape quotes | 437 | $name =~ s/(?<!\\)"/\\"/g; ##escape quotes |
| 414 | $formatted_email = "\"${name}\"\ \<${email}\>"; | 438 | $name = "\"$name\""; |
| 439 | } | ||
| 440 | |||
| 441 | if ($email_usename) { | ||
| 442 | if ("$name" eq "") { | ||
| 443 | $formatted_email = "$address"; | ||
| 444 | } else { | ||
| 445 | $formatted_email = "$name <${address}>"; | ||
| 446 | } | ||
| 415 | } else { | 447 | } else { |
| 416 | $formatted_email = "${name} \<${email}\>"; | 448 | $formatted_email = $address; |
| 417 | } | 449 | } |
| 450 | |||
| 418 | return $formatted_email; | 451 | return $formatted_email; |
| 419 | } | 452 | } |
| 420 | 453 | ||
| @@ -444,19 +477,18 @@ sub add_categories { | |||
| 444 | } | 477 | } |
| 445 | } | 478 | } |
| 446 | } elsif ($ptype eq "M") { | 479 | } elsif ($ptype eq "M") { |
| 447 | my $p_used = 0; | 480 | my ($name, $address) = parse_email($pvalue); |
| 448 | if ($index >= 0) { | 481 | if ($name eq "") { |
| 449 | my $tv = $typevalue[$index - 1]; | 482 | if ($index >= 0) { |
| 450 | if ($tv =~ m/^(\C):\s*(.*)/) { | 483 | my $tv = $typevalue[$index - 1]; |
| 451 | if ($1 eq "P") { | 484 | if ($tv =~ m/^(\C):\s*(.*)/) { |
| 452 | if ($email_usename) { | 485 | if ($1 eq "P") { |
| 453 | push_email_address(format_email($2, $pvalue)); | 486 | $name = $2; |
| 454 | $p_used = 1; | ||
| 455 | } | 487 | } |
| 456 | } | 488 | } |
| 457 | } | 489 | } |
| 458 | } | 490 | } |
| 459 | if (!$p_used) { | 491 | if ($email_maintainer) { |
| 460 | push_email_addresses($pvalue); | 492 | push_email_addresses($pvalue); |
| 461 | } | 493 | } |
| 462 | } elsif ($ptype eq "T") { | 494 | } elsif ($ptype eq "T") { |
| @@ -475,26 +507,24 @@ sub add_categories { | |||
| 475 | } | 507 | } |
| 476 | } | 508 | } |
| 477 | 509 | ||
| 510 | sub email_address_inuse { | ||
| 511 | my ($test_address) = @_; | ||
| 512 | |||
| 513 | foreach my $line (@email_to) { | ||
| 514 | my ($name, $address) = parse_email($line); | ||
| 515 | |||
| 516 | return 1 if ($address eq $test_address); | ||
| 517 | } | ||
| 518 | return 0; | ||
| 519 | } | ||
| 520 | |||
| 478 | sub push_email_address { | 521 | sub push_email_address { |
| 479 | my ($email_address) = @_; | 522 | my ($line) = @_; |
| 480 | 523 | ||
| 481 | my $email_name = ""; | 524 | my ($name, $address) = parse_email($line); |
| 482 | 525 | ||
| 483 | if ($email_maintainer) { | 526 | if (!email_address_inuse($address)) { |
| 484 | if ($email_address =~ m/([^<]+)<(.*\@.*)>$/) { | 527 | push(@email_to, format_email($name, $address)); |
| 485 | $email_name = $1; | ||
| 486 | $email_address = $2; | ||
| 487 | if ($email_usename) { | ||
| 488 | push(@email_to, format_email($email_name, $email_address)); | ||
| 489 | } else { | ||
| 490 | push(@email_to, $email_address); | ||
| 491 | } | ||
| 492 | } elsif ($email_address =~ m/<(.+)>/) { | ||
| 493 | $email_address = $1; | ||
| 494 | push(@email_to, $email_address); | ||
| 495 | } else { | ||
| 496 | push(@email_to, $email_address); | ||
| 497 | } | ||
| 498 | } | 528 | } |
| 499 | } | 529 | } |
| 500 | 530 | ||
| @@ -535,6 +565,7 @@ sub recent_git_signoffs { | |||
| 535 | my $output = ""; | 565 | my $output = ""; |
| 536 | my $count = 0; | 566 | my $count = 0; |
| 537 | my @lines = (); | 567 | my @lines = (); |
| 568 | my %hash; | ||
| 538 | my $total_sign_offs; | 569 | my $total_sign_offs; |
| 539 | 570 | ||
| 540 | if (which("git") eq "") { | 571 | if (which("git") eq "") { |
| @@ -548,25 +579,31 @@ sub recent_git_signoffs { | |||
| 548 | } | 579 | } |
| 549 | 580 | ||
| 550 | $cmd = "git log --since=${email_git_since} -- ${file}"; | 581 | $cmd = "git log --since=${email_git_since} -- ${file}"; |
| 551 | $cmd .= " | grep -Ei \"^[-_ a-z]+by:.*\\\@.*\$\""; | ||
| 552 | if (!$email_git_penguin_chiefs) { | ||
| 553 | $cmd .= " | grep -Ev \"${penguin_chiefs}\""; | ||
| 554 | } | ||
| 555 | $cmd .= " | cut -f2- -d\":\""; | ||
| 556 | $cmd .= " | sort | uniq -c | sort -rn"; | ||
| 557 | 582 | ||
| 558 | $output = `${cmd}`; | 583 | $output = `${cmd}`; |
| 559 | $output =~ s/^\s*//gm; | 584 | $output =~ s/^\s*//gm; |
| 560 | 585 | ||
| 561 | @lines = split("\n", $output); | 586 | @lines = split("\n", $output); |
| 562 | 587 | ||
| 563 | $total_sign_offs = 0; | 588 | @lines = grep(/^[-_ a-z]+by:.*\@.*$/i, @lines); |
| 589 | if (!$email_git_penguin_chiefs) { | ||
| 590 | @lines = grep(!/${penguin_chiefs}/i, @lines); | ||
| 591 | } | ||
| 592 | # cut -f2- -d":" | ||
| 593 | s/.*:\s*(.+)\s*/$1/ for (@lines); | ||
| 594 | |||
| 595 | @lines = mailmap(@lines); | ||
| 596 | |||
| 597 | $total_sign_offs = @lines; | ||
| 598 | @lines = sort(@lines); | ||
| 599 | # uniq -c | ||
| 564 | foreach my $line (@lines) { | 600 | foreach my $line (@lines) { |
| 565 | if ($line =~ m/([0-9]+)\s+(.*)/) { | 601 | $hash{$line}++; |
| 566 | $total_sign_offs += $1; | 602 | } |
| 567 | } else { | 603 | # sort -rn |
| 568 | die("$P: Unexpected git output: ${line}\n"); | 604 | @lines = (); |
| 569 | } | 605 | foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { |
| 606 | push(@lines,"$hash{$line} $line"); | ||
| 570 | } | 607 | } |
| 571 | 608 | ||
| 572 | foreach my $line (@lines) { | 609 | foreach my $line (@lines) { |
| @@ -579,8 +616,8 @@ sub recent_git_signoffs { | |||
| 579 | $sign_offs * 100 / $total_sign_offs < $email_git_min_percent) { | 616 | $sign_offs * 100 / $total_sign_offs < $email_git_min_percent) { |
| 580 | last; | 617 | last; |
| 581 | } | 618 | } |
| 619 | push_email_address($line); | ||
| 582 | } | 620 | } |
| 583 | push_email_address($line); | ||
| 584 | } | 621 | } |
| 585 | } | 622 | } |
| 586 | 623 | ||
| @@ -632,15 +669,18 @@ sub git_assign_blame { | |||
| 632 | @commits = uniq(@commits); | 669 | @commits = uniq(@commits); |
| 633 | foreach my $commit (@commits) { | 670 | foreach my $commit (@commits) { |
| 634 | $cmd = "git log -1 ${commit}"; | 671 | $cmd = "git log -1 ${commit}"; |
| 635 | $cmd .= " | grep -Ei \"^[-_ a-z]+by:.*\\\@.*\$\""; | ||
| 636 | if (!$email_git_penguin_chiefs) { | ||
| 637 | $cmd .= " | grep -Ev \"${penguin_chiefs}\""; | ||
| 638 | } | ||
| 639 | $cmd .= " | cut -f2- -d\":\""; | ||
| 640 | 672 | ||
| 641 | $output = `${cmd}`; | 673 | $output = `${cmd}`; |
| 642 | $output =~ s/^\s*//gm; | 674 | $output =~ s/^\s*//gm; |
| 643 | @lines = split("\n", $output); | 675 | @lines = split("\n", $output); |
| 676 | |||
| 677 | @lines = grep(/^[-_ a-z]+by:.*\@.*$/i, @lines); | ||
| 678 | if (!$email_git_penguin_chiefs) { | ||
| 679 | @lines = grep(!/${penguin_chiefs}/i, @lines); | ||
| 680 | } | ||
| 681 | # cut -f2- -d":" | ||
| 682 | s/.*:\s*(.+)\s*/$1/ for (@lines); | ||
| 683 | |||
| 644 | $hash{$_}++ for @lines; | 684 | $hash{$_}++ for @lines; |
| 645 | $total_sign_offs += @lines; | 685 | $total_sign_offs += @lines; |
| 646 | } | 686 | } |
