Added format_email and parse_email routines to reduce inline use. Added email_address_inuse to eliminate multiple maintainer entries for the same email address, the first name encountered is used. Used internal perl equivalents of shell cmd use of grep|cut|sort|uniq
Unified · Split
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | use strict; |
| 14 | 14 | |
| 15 | 15 | my $P = $0; |
| 16 | −my $V = '0.19'; | |
| 16 | +my $V = '0.20'; | |
| 17 | 17 | |
| 18 | 18 | use Getopt::Long qw(:config no_auto_abbrev); |
| 19 | 19 | |
| @@ -258,11 +258,8 @@ if ($email) { · 238 unmodified lines | ||
| 258 | 258 | foreach my $chief (@penguin_chief) { |
| 259 | 259 | if ($chief =~ m/^(.*):(.*)/) { |
| 260 | 260 | my $email_address; |
| 261 | − if ($email_usename) { | |
| 262 | − $email_address = format_email($1, $2); | |
| 263 | − } else { | |
| 264 | − $email_address = $2; | |
| 265 | − } | |
| 261 | + | |
| 262 | + $email_address = format_email($1, $2); | |
| 266 | 263 | if ($email_git_penguin_chiefs) { |
| 267 | 264 | push(@email_to, $email_address); |
| 268 | 265 | } else { |
| @@ -400,21 +397,57 @@ sub top_of_kernel_tree { · 131 unmodified lines | ||
| 400 | 397 | return 0; |
| 401 | 398 | } |
| 402 | 399 | |
| 403 | −sub format_email { | |
| 404 | − my ($name, $email) = @_; | |
| 400 | +sub parse_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 | 415 | $name =~ s/^\s+|\s+$//g; |
| 407 | 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 | 436 | if ($name =~ /[^a-z0-9 \.\-]/i) { ##has "must quote" chars |
| 413 | 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 | 447 | } else { |
| 416 | − $formatted_email = "${name} \<${email}\>"; | |
| 448 | + $formatted_email = $address; | |
| 417 | 449 | } |
| 450 | + | |
| 418 | 451 | return $formatted_email; |
| 419 | 452 | } |
| 420 | 453 | |
| @@ -444,19 +477,18 @@ sub add_categories { · 23 unmodified lines | ||
| 444 | 477 | } |
| 445 | 478 | } |
| 446 | 479 | } elsif ($ptype eq "M") { |
| 447 | − my $p_used = 0; | |
| 448 | − if ($index >= 0) { | |
| 449 | − my $tv = $typevalue[$index - 1]; | |
| 450 | − if ($tv =~ m/^(\C):\s*(.*)/) { | |
| 451 | − if ($1 eq "P") { | |
| 452 | − if ($email_usename) { | |
| 453 | − push_email_address(format_email($2, $pvalue)); | |
| 454 | − $p_used = 1; | |
| 480 | + my ($name, $address) = parse_email($pvalue); | |
| 481 | + if ($name eq "") { | |
| 482 | + if ($index >= 0) { | |
| 483 | + my $tv = $typevalue[$index - 1]; | |
| 484 | + if ($tv =~ m/^(\C):\s*(.*)/) { | |
| 485 | + if ($1 eq "P") { | |
| 486 | + $name = $2; | |
| 455 | 487 | } |
| 456 | 488 | } |
| 457 | 489 | } |
| 458 | 490 | } |
| 459 | − if (!$p_used) { | |
| 491 | + if ($email_maintainer) { | |
| 460 | 492 | push_email_addresses($pvalue); |
| 461 | 493 | } |
| 462 | 494 | } elsif ($ptype eq "T") { |
| @@ -475,26 +507,24 @@ sub add_categories { · 12 unmodified lines | ||
| 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 | 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) { | |
| 484 | − if ($email_address =~ m/([^<]+)<(.*\@.*)>$/) { | |
| 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 | − } | |
| 526 | + if (!email_address_inuse($address)) { | |
| 527 | + push(@email_to, format_email($name, $address)); | |
| 498 | 528 | } |
| 499 | 529 | } |
| 500 | 530 | |
| @@ -535,6 +565,7 @@ sub recent_git_signoffs { · 34 unmodified lines | ||
| 535 | 565 | my $output = ""; |
| 536 | 566 | my $count = 0; |
| 537 | 567 | my @lines = (); |
| 568 | + my %hash; | |
| 538 | 569 | my $total_sign_offs; |
| 539 | 570 | |
| 540 | 571 | if (which("git") eq "") { |
| @@ -548,25 +579,31 @@ sub recent_git_signoffs { · 7 unmodified lines | ||
| 548 | 579 | } |
| 549 | 580 | |
| 550 | 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 | 583 | $output = `${cmd}`; |
| 559 | 584 | $output =~ s/^\s*//gm; |
| 560 | 585 | |
| 561 | 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 | 600 | foreach my $line (@lines) { |
| 565 | − if ($line =~ m/([0-9]+)\s+(.*)/) { | |
| 566 | − $total_sign_offs += $1; | |
| 567 | − } else { | |
| 568 | − die("$P: Unexpected git output: ${line}\n"); | |
| 569 | − } | |
| 601 | + $hash{$line}++; | |
| 602 | + } | |
| 603 | + # sort -rn | |
| 604 | + @lines = (); | |
| 605 | + foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { | |
| 606 | + push(@lines,"$hash{$line} $line"); | |
| 570 | 607 | } |
| 571 | 608 | |
| 572 | 609 | foreach my $line (@lines) { |
| @@ -579,8 +616,8 @@ sub recent_git_signoffs { · 6 unmodified lines | ||
| 579 | 616 | $sign_offs * 100 / $total_sign_offs < $email_git_min_percent) { |
| 580 | 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 { · 45 unmodified lines | ||
| 632 | 669 | @commits = uniq(@commits); |
| 633 | 670 | foreach my $commit (@commits) { |
| 634 | 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 | 673 | $output = `${cmd}`; |
| 642 | 674 | $output =~ s/^\s*//gm; |
| 643 | 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 | 684 | $hash{$_}++ for @lines; |
| 645 | 685 | $total_sign_offs += @lines; |
| 646 | 686 | } |