scripts/get_maintainer.pl: update to current version

Update the script to version 0.26 (as of Linux v4.14-rc1)
Keep our "penguin_chief".
Keep our top_of_kernel_tree.

The negative forms of the command line parameters are described
when using --help.

New options are

 --git-blame-signatures => when used with --git-blame,
                           also include all commit signers
 --r => include reviewer(s) if any
 --letters => print all matching 'letter' types
              from all matching sections

File .get_maintainer.ignore can be used to specify
email addressees that shall be ignored.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
master
Heinrich Schuchardt 7 years ago committed by Tom Rini
parent 9b46ce8cfc
commit 59ab72d7bc
  1. 202
      scripts/get_maintainer.pl

@ -1,4 +1,4 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
# (c) 2007, Joe Perches <joe@perches.com>
# created from checkpatch.pl
#
@ -10,18 +10,22 @@
#
# Licensed under the terms of the GNU GPL License version 2
use warnings;
use strict;
my $P = $0;
my $V = '0.26';
use Getopt::Long qw(:config no_auto_abbrev);
use Cwd;
use File::Find;
my $cur_path = fastgetcwd() . '/';
my $lk_path = "./";
my $email = 1;
my $email_usename = 1;
my $email_maintainer = 1;
my $email_reviewer = 1;
my $email_list = 1;
my $email_subscriber_list = 0;
my $email_git_penguin_chiefs = 0;
@ -42,10 +46,12 @@ my $output_multiline = 1;
my $output_separator = ", ";
my $output_roles = 0;
my $output_rolestats = 1;
my $output_section_maxlen = 50;
my $scm = 0;
my $web = 0;
my $subsystem = 0;
my $status = 0;
my $letters = "";
my $keywords = 1;
my $sections = 0;
my $file_emails = 0;
@ -53,6 +59,7 @@ my $from_filename = 0;
my $pattern_depth = 0;
my $version = 0;
my $help = 0;
my $find_maintainer_files = 0;
my $vcs_used = 0;
@ -128,6 +135,7 @@ my %VCS_cmds_git = (
"author_pattern" => "^GitAuthor: (.*)",
"subject_pattern" => "^GitSubject: (.*)",
"stat_pattern" => "^(\\d+)\\t(\\d+)\\t\$file\$",
"file_exists_cmd" => "git ls-files \$file",
);
my %VCS_cmds_hg = (
@ -156,6 +164,7 @@ my %VCS_cmds_hg = (
"author_pattern" => "^HgAuthor: (.*)",
"subject_pattern" => "^HgSubject: (.*)",
"stat_pattern" => "^(\\d+)\t(\\d+)\t\$file\$",
"file_exists_cmd" => "hg files \$file",
);
my $conf = which_conf(".get_maintainer.conf");
@ -184,6 +193,27 @@ if (-f $conf) {
unshift(@ARGV, @conf_args) if @conf_args;
}
my @ignore_emails = ();
my $ignore_file = which_conf(".get_maintainer.ignore");
if (-f $ignore_file) {
open(my $ignore, '<', "$ignore_file")
or warn "$P: Can't find a readable .get_maintainer.ignore file $!\n";
while (<$ignore>) {
my $line = $_;
$line =~ s/\s*\n?$//;
$line =~ s/^\s*//;
$line =~ s/\s+$//;
$line =~ s/#.*$//;
next if ($line =~ m/^\s*$/);
if (rfc822_valid($line)) {
push(@ignore_emails, $line);
}
}
close($ignore);
}
if (!GetOptions(
'email!' => \$email,
'git!' => \$email_git,
@ -201,6 +231,7 @@ if (!GetOptions(
'remove-duplicates!' => \$email_remove_duplicates,
'mailmap!' => \$email_use_mailmap,
'm!' => \$email_maintainer,
'r!' => \$email_reviewer,
'n!' => \$email_usename,
'l!' => \$email_list,
's!' => \$email_subscriber_list,
@ -212,11 +243,13 @@ if (!GetOptions(
'status!' => \$status,
'scm!' => \$scm,
'web!' => \$web,
'letters=s' => \$letters,
'pattern-depth=i' => \$pattern_depth,
'k|keywords!' => \$keywords,
'sections!' => \$sections,
'fe|file-emails!' => \$file_emails,
'f|file' => \$from_filename,
'find-maintainer-files' => \$find_maintainer_files,
'v|version' => \$version,
'h|help|usage' => \$help,
)) {
@ -242,7 +275,8 @@ $output_multiline = 0 if ($output_separator ne ", ");
$output_rolestats = 1 if ($interactive);
$output_roles = 1 if ($output_rolestats);
if ($sections) {
if ($sections || $letters ne "") {
$sections = 1;
$email = 0;
$email_list = 0;
$scm = 0;
@ -259,42 +293,28 @@ if ($sections) {
}
if ($email &&
($email_maintainer + $email_list + $email_subscriber_list +
($email_maintainer + $email_reviewer +
$email_list + $email_subscriber_list +
$email_git + $email_git_penguin_chiefs + $email_git_blame) == 0) {
die "$P: Please select at least 1 email option\n";
}
if (!top_of_kernel_tree($lk_path)) {
die "$P: The current directory does not appear to be "
. "a linux kernel source tree.\n";
. "a U-Boot source tree.\n";
}
## Read MAINTAINERS for type/value pairs
my @typevalue = ();
my %keyword_hash;
my @mfiles = ();
my @maint_files = ();
push(@maint_files, "${lk_path}MAINTAINERS");
sub maint_wanted {
return unless $_ =~ /^MAINTAINERS/;
push(@maint_files, "$File::Find::name");
}
File::Find::find(\&maint_wanted, "${lk_path}board");
foreach my $maint_file (@maint_files) {
my $maint;
open ($maint, '<', "$maint_file")
or die "$P: Can't open $maint_file: $!\n";
read_maintainers($maint);
close($maint);
}
sub read_maintainers {
my ($maint) = @_;
sub read_maintainer_file {
my ($file) = @_;
open (my $maint, '<', "$file")
or die "$P: Can't open MAINTAINERS file '$file': $!\n";
while (<$maint>) {
my $line = $_;
@ -315,13 +335,47 @@ sub read_maintainers {
$keyword_hash{@typevalue} = $value;
}
push(@typevalue, "$type:$value");
} elsif (!/^(\s)*$/) {
} elsif (!(/^\s*$/ || /^\s*\#/)) {
$line =~ s/\n$//g;
push(@typevalue, $line);
}
}
close($maint);
}
sub find_is_maintainer_file {
my ($file) = $_;
return if ($file !~ m@/MAINTAINERS$@);
$file = $File::Find::name;
return if (! -f $file);
push(@mfiles, $file);
}
sub find_ignore_git {
return grep { $_ !~ /^\.git$/; } @_;
}
if (-d "${lk_path}MAINTAINERS") {
opendir(DIR, "${lk_path}MAINTAINERS") or die $!;
my @files = readdir(DIR);
closedir(DIR);
foreach my $file (@files) {
push(@mfiles, "${lk_path}MAINTAINERS/$file") if ($file !~ /^\./);
}
}
if ($find_maintainer_files) {
find( { wanted => \&find_is_maintainer_file,
preprocess => \&find_ignore_git,
no_chdir => 1,
}, "${lk_path}");
} else {
push(@mfiles, "${lk_path}MAINTAINERS") if -f "${lk_path}MAINTAINERS";
}
foreach my $file (@mfiles) {
read_maintainer_file("$file");
}
#
# Read mail address map
@ -421,7 +475,9 @@ foreach my $file (@ARGV) {
die "$P: file '${file}' not found\n";
}
}
if ($from_filename) {
if ($from_filename || ($file ne "&STDIN" && vcs_file_exists($file))) {
$file =~ s/^\Q${cur_path}\E//; #strip any absolute path
$file =~ s/^\Q${lk_path}\E//; #or the path to the lk tree
push(@files, $file);
if ($file ne "MAINTAINERS" && -f $file && ($keywords || $file_emails)) {
open(my $f, '<', $file)
@ -528,6 +584,16 @@ if ($web) {
exit($exit);
sub ignore_email_address {
my ($address) = @_;
foreach my $ignore (@ignore_emails) {
return 1 if ($ignore eq $address);
}
return 0;
}
sub range_is_maintained {
my ($start, $end) = @_;
@ -659,8 +725,10 @@ sub get_maintainers {
$line =~ s/\\\./\./g; ##Convert \. to .
$line =~ s/\.\*/\*/g; ##Convert .* to *
}
$line =~ s/^([A-Z]):/$1:\t/g;
print("$line\n");
my $count = $line =~ s/^([A-Z]):/$1:\t/g;
if ($letters eq "" || (!$count || $letters =~ /$1/i)) {
print("$line\n");
}
}
print("\n");
}
@ -764,10 +832,12 @@ MAINTAINER field selection options:
--git-max-maintainers => maximum maintainers to add (default: $email_git_max_maintainers)
--git-min-percent => minimum percentage of commits required (default: $email_git_min_percent)
--git-blame => use git blame to find modified commits for patch or file
--git-blame-signatures => when used with --git-blame, also include all commit signers
--git-since => git history to use (default: $email_git_since)
--hg-since => hg history to use (default: $email_hg_since)
--interactive => display a menu (mostly useful if used with the --git option)
--m => include maintainer(s) if any
--r => include reviewer(s) if any
--n => include name 'Full Name <addr\@domain.tld>'
--l => include list(s) if any
--s => include subscriber only list(s) if any
@ -789,12 +859,13 @@ Other options:
--pattern-depth => Number of pattern directory traversals (default: 0 (all))
--keywords => scan patch for keywords (default: $keywords)
--sections => print all of the subsystem sections with pattern matches
--letters => print all matching 'letter' types from all matching sections
--mailmap => use .mailmap file (default: $email_use_mailmap)
--version => show version
--help => show this help information
Default options:
[--email --nogit --git-fallback --m --n --l --multiline -pattern-depth=0
[--email --nogit --git-fallback --m --r --n --l --multiline --pattern-depth=0
--remove-duplicates --rolestats]
Notes:
@ -826,6 +897,9 @@ Notes:
Entries in this file can be any command line argument.
This file is prepended to any additional command line arguments.
Multiple lines and # comments are allowed.
Most options have both positive and negative forms.
The negative forms for --<foo> are --no<foo> and --no-<foo>.
EOT
}
@ -836,7 +910,7 @@ sub top_of_kernel_tree {
$lk_path .= "/";
}
if ( (-f "${lk_path}Kbuild")
&& (-f "${lk_path}MAINTAINERS")
&& (-e "${lk_path}MAINTAINERS")
&& (-f "${lk_path}Makefile")
&& (-f "${lk_path}README")
&& (-d "${lk_path}arch")
@ -954,20 +1028,29 @@ sub find_ending_index {
return $index;
}
sub get_maintainer_role {
sub get_subsystem_name {
my ($index) = @_;
my $i;
my $start = find_starting_index($index);
my $end = find_ending_index($index);
my $role = "unknown";
my $subsystem = $typevalue[$start];
if (length($subsystem) > 20) {
$subsystem = substr($subsystem, 0, 17);
if ($output_section_maxlen && length($subsystem) > $output_section_maxlen) {
$subsystem = substr($subsystem, 0, $output_section_maxlen - 3);
$subsystem =~ s/\s*$//;
$subsystem = $subsystem . "...";
}
return $subsystem;
}
sub get_maintainer_role {
my ($index) = @_;
my $i;
my $start = find_starting_index($index);
my $end = find_ending_index($index);
my $role = "unknown";
my $subsystem = get_subsystem_name($index);
for ($i = $start + 1; $i < $end; $i++) {
my $tv = $typevalue[$i];
@ -1001,16 +1084,7 @@ sub get_maintainer_role {
sub get_list_role {
my ($index) = @_;
my $i;
my $start = find_starting_index($index);
my $end = find_ending_index($index);
my $subsystem = $typevalue[$start];
if (length($subsystem) > 20) {
$subsystem = substr($subsystem, 0, 17);
$subsystem =~ s/\s*$//;
$subsystem = $subsystem . "...";
}
my $subsystem = get_subsystem_name($index);
if ($subsystem eq "THE REST") {
$subsystem = "";
@ -1084,6 +1158,23 @@ sub add_categories {
my $role = get_maintainer_role($i);
push_email_addresses($pvalue, $role);
}
} elsif ($ptype eq "R") {
my ($name, $address) = parse_email($pvalue);
if ($name eq "") {
if ($i > 0) {
my $tv = $typevalue[$i - 1];
if ($tv =~ m/^([A-Z]):\s*(.*)/) {
if ($1 eq "P") {
$name = $2;
$pvalue = format_email($name, $address, $email_usename);
}
}
}
}
if ($email_reviewer) {
my $subsystem = get_subsystem_name($i);
push_email_addresses($pvalue, "reviewer:$subsystem");
}
} elsif ($ptype eq "T") {
push(@scm, $pvalue);
} elsif ($ptype eq "W") {
@ -1868,6 +1959,7 @@ sub vcs_assign {
my $percent = $sign_offs * 100 / $divisor;
$percent = 100 if ($percent > 100);
next if (ignore_email_address($line));
$count++;
last if ($sign_offs < $email_git_min_signatures ||
$count > $email_git_max_maintainers ||
@ -2082,6 +2174,24 @@ sub vcs_file_blame {
}
}
sub vcs_file_exists {
my ($file) = @_;
my $exists;
my $vcs_used = vcs_exists();
return 0 if (!$vcs_used);
my $cmd = $VCS_cmds{"file_exists_cmd"};
$cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd
$cmd .= " 2>&1";
$exists = &{$VCS_cmds{"execute_cmd"}}($cmd);
return 0 if ($? != 0);
return $exists;
}
sub uniq {
my (@parms) = @_;

Loading…
Cancel
Save