Skip to contentSkip to conversation

scripts/get_maintainer.pl: update to current version

PATCH New Heinrich Schuchardt 3 participants 5 messages Oct 28, 2017 – Oct 29, 2017 1 message not in the archive GET_MAINTAINER script

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): 1509162258.1932.3.camel@localhost

#1 lore raw

PATCH 1/1 scripts/get_maintainer.pl: update to current version

Quoted 10 lines · waltfeasel at gmail.com

Heinrich,

I ran across a problem with not getting a maintainer for a correction I was putting together. I tracked it down to the line:

"+my $find_maintainer_files = 0;"

When I changed the "0" to a "1" I was able to get the maintainer as intended.

Quoted 6 lines

My error was as follows:

$ perl scripts/get_maintainer.pl -m -r -l -f board/Marvell/dreamplug/
Bad divisor in main::vcs_assign: 0
"GitAuthor: Walt Feasel" <[email protected]> (authored:2/1=100%)
u-boot at lists.denx.de (open list)

Hello Walt,

I am not able to reproduce your problem with perl v5.4.21 on Debian Stretch:

$ scripts/get_maintainer.pl -f board/Marvell/dreamplug/
u-boot at lists.denx.de (open list)
$ perl scripts/get_maintainer.pl -m -r -l -f board/Marvell/dreamplug/
u-boot at lists.denx.de (open list)
$

I wonder why you are calling perl with -m -r -l.

The get_maintainer.pl script is maintained in the Linux kernel source tree. So if you find any problem, please, send a mail

TO: Joe Perches <[email protected]> (maintainer:GET_MAINTAINER SCRIPT)
CC: linux-kernel at vger.kernel.org (open list)

As we have many MAINTAINERS files in subdirectories you are right in that we should enable finding these. I will submit a patch.

Best regards

Heinrich

Quoted 509 lines

When I changed from the "0" to the "1" as stated above I get:

$ perl scripts/get_maintainer.pl -m -r -l -f board/Marvell/dreamplug/
Jason Cooper <[email protected]> (maintainer:DREAMPLUG BOARD)
u-boot at lists.denx.de (open list)

As I would expect and believe is intended.

I have included below the text of your e-mail to the u-boot list as a reference.

I do not know if this is the proper fix for it or if it may cause issues with your intentions so I will leave it to you and or Tom to decide what to do.

Also, I am currently not subscribed to the mailing list so unable to post there.

Sincerely,

Walt Feasel

ORIGINAL POST ON MAILING LIST BELOW

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.

---
 scripts/get_maintainer.pl | 202 +++++++++++++++++++++++++++++++++++---
--------

 1 file changed, 156 insertions(+), 46 deletions(-)
scripts/get_maintainer.pl +1 -1
index 83a4e5bad2..8b6037b73f 100755
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
  # (c) 2007, Joe Perches <[email protected]>
  #           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;

scripts/get_maintainer.pl +3 -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;

scripts/get_maintainer.pl +1 -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 = (

scripts/get_maintainer.pl +1 -0
@@ -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");

scripts/get_maintainer.pl +0 -0
@@ -184,6 +193,27 @@ if (-f $conf) {
      unshift(@ARGV, @conf_args) if @conf_args;
  }

scripts/get_maintainer.pl +5 -0
+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>) {

scripts/get_maintainer.pl +15 -0
+	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,

scripts/get_maintainer.pl +3 -0
@@ -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);

scripts/get_maintainer.pl +2 -1
-if ($sections) {
+if ($sections || $letters ne "") {
+    $sections = 1;

     $email = 0;
     $email_list = 0;
     $scm = 0;

scripts/get_maintainer.pl +0 -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 "

scripts/get_maintainer.pl +1 -1
-	. "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 = ();

scripts/get_maintainer.pl +2 -20
-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")

scripts/get_maintainer.pl +1 -0
+	or die "$P: Can't open MAINTAINERS file '$file': $!\n";

     while (<$maint>) {
  my $line = $_;

scripts/get_maintainer.pl +23 -1
@@ -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 !~
 /^\./);
+    }
  }

scripts/get_maintainer.pl +7 -0
+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";

scripts/get_maintainer.pl +5 -0
+}
+
+foreach my $file (@mfiles) {
+    read_maintainer_file("$file");
+}


 #
 # Read mail address map

scripts/get_maintainer.pl +3 -1
@@ -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)

scripts/get_maintainer.pl +0 -0
@@ -528,6 +584,16 @@ if ($web) {


 exit($exit);

scripts/get_maintainer.pl +10 -0
+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) = @_;

scripts/get_maintainer.pl +0 -0
@@ -659,8 +725,10 @@ sub get_maintainers {

  $line =~ s/\\\./\./g;        ##Convert
\. to .
  $line =~ s/\.\*/\*/g;        ##Convert
.* to *
      }

scripts/get_maintainer.pl +2 -2
-		    $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)) {

scripts/get_maintainer.pl +2 -0
+			print("$line\n");
+		    }

  }
  print("\n");
      }

scripts/get_maintainer.pl +0 -0
@@ -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

scripts/get_maintainer.pl +0 -0
@@ -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:

scripts/get_maintainer.pl +0 -0
@@ -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
 }

scripts/get_maintainer.pl +1 -1
@@ -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;
  }

scripts/get_maintainer.pl +1 -1
-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) {

scripts/get_maintainer.pl +1 -1
-	$subsystem = substr($subsystem, 0, 17);
+    if ($output_section_maxlen && length($subsystem) >

$output_section_maxlen) {

scripts/get_maintainer.pl +1 -0
+	$subsystem = substr($subsystem, 0, $output_section_maxlen -

3);
  $subsystem =~ s/\s*$//;
  $subsystem = $subsystem . "...";
     }
+    return $subsystem;

scripts/get_maintainer.pl +11 -0
+}
+
+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];

scripts/get_maintainer.pl +0 -0
@@ -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);

scripts/get_maintainer.pl +1 -7
-
-    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 = "";

scripts/get_maintainer.pl +17 -0
@@ -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") {

scripts/get_maintainer.pl +0 -0
@@ -1868,6 +1959,7 @@ sub vcs_assign {
  	my $percent = $sign_offs * 100 / $divisor;


  $percent = 100 if ($percent > 100);

scripts/get_maintainer.pl +1 -0
+	next if (ignore_email_address($line));

  $count++;
  last if ($sign_offs < $email_git_min_signatures || $count > $email_git_max_maintainers ||

scripts/get_maintainer.pl +0 -0
@@ -2082,6 +2174,24 @@ sub vcs_file_blame {
      }
  }

scripts/get_maintainer.pl +18 -0
+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) = @_;

--
2.14.1

#2 lore raw

PATCH 1/1 scripts/get_maintainer.pl: enable find_maintainer_files

Many MAINTAINERS files are in subdirectories.
We should enable searching these.

---
 scripts/get_maintainer.pl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/get_maintainer.pl +1 -1
index 8b6037b73f..07800e62d1 100755
@@ -59,7 +59,7 @@ my $from_filename = 0;
 my $pattern_depth = 0;
 my $version = 0;
 my $help = 0;
-my $find_maintainer_files = 0;
+my $find_maintainer_files = 1;
 
 my $vcs_used = 0;
 
Signature · 1 line
2.14.1
#3 lore raw

PATCH 1/1 scripts/get_maintainer.pl: enable find_maintainer_files

Quoted 19 lines · Heinrich Schuchardt

Many MAINTAINERS files are in subdirectories.
We should enable searching these.

---
 scripts/get_maintainer.pl | 2 +-

 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/get_maintainer.pl +1 -1
index 8b6037b73f..07800e62d1 100755
@@ -59,7 +59,7 @@ my $from_filename = 0;
  my $pattern_depth = 0;
  my $version = 0;
  my $help = 0;
-my $find_maintainer_files = 0;
+my $find_maintainer_files = 1;
Quoted 3 lines


 my $vcs_used = 0;

You are a Rock Star!

Thanks,

Walt

#4 lore raw

PATCH 1/1 scripts/get_maintainer.pl: enable find_maintainer_files

In reply to Heinrich Schuchardt
Quoted 5 lines · Heinrich Schuchardt

Many MAINTAINERS files are in subdirectories.
We should enable searching these.

Applied to u-boot/master, thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171029/59b57e27/attachment.sig>
#5 lore raw

PATCH 1/1 scripts/get_maintainer.pl: update to current version

In reply to Heinrich Schuchardt
Quoted 14 lines · Heinrich Schuchardt
Quoted 13 lines · waltfeasel at gmail.com

Heinrich,

I ran across a problem with not getting a maintainer for a correction I
was putting together. I tracked it down to the line:

"+my $find_maintainer_files = 0;"

When I changed the "0" to a "1" I was able to get the maintainer as intended.

My error was as follows:

Quoted 8 lines
Quoted 5 lines
$ perl scripts/get_maintainer.pl -m -r -l -f
board/Marvell/dreamplug/
Bad divisor in main::vcs_assign: 0
"GitAuthor: Walt Feasel" <[email protected]> (authored:2/1=100%)
u-boot at lists.denx.de (open list)

Hello Walt,

Heinrich,

Quoted 3 lines

I am not able to reproduce your problem with perl v5.4.21 on Debian Stretch:

I have perl 5.24.1-3+deb9u2 on Debian Stretch.

Quoted 6 lines
$ scripts/get_maintainer.pl -f board/Marvell/dreamplug/
u-boot at lists.denx.de (open list)
$ perl scripts/get_maintainer.pl -m -r -l -f board/Marvell/dreamplug/
u-boot at lists.denx.de (open list)
$

These are missing Jason Cooper whom is the maintainer so neither is correct but not sure why I have the bad divisor if you also have the "+my $find_maintainer_files = 0;" setting.

Quoted 2 lines

I wonder why you are calling perl with -m -r -l.

From my uneducated understanding:

-m = maintainer
-r = reviewers
-l = mailing list

to get the email listings for each.

Quoted 3 lines

The get_maintainer.pl script is maintained in the Linux kernel source tree. So if you find any problem, please, send a mail

Sorry, I thought you had made the modifications.

Quoted 6 lines

TO: Joe Perches <[email protected]> (maintainer:GET_MAINTAINER SCRIPT)
CC: linux-kernel at vger.kernel.org (open list)

As we have many MAINTAINERS files in subdirectories you are right in that we should enable finding these. I will submit a patch.

Thank you very much!

Quoted 4 lines

Best regards

Heinrich

Walt

Quoted 530 lines
Quoted 528 lines

When I changed from the "0" to the "1" as stated above I get:

$ perl scripts/get_maintainer.pl -m -r -l -f
board/Marvell/dreamplug/
Jason Cooper <[email protected]> (maintainer:DREAMPLUG BOARD)
u-boot at lists.denx.de (open list)

As I would expect and believe is intended.

I have included below the text of your e-mail to the u-boot list as a
reference.

I do not know if this is the proper fix for it or if it may cause issues with your intentions so I will leave it to you and or Tom to decide what to do.

Also, I am currently not subscribed to the mailing list so unable to
post there.

Sincerely,

Walt Feasel

ORIGINAL POST ON MAILING LIST BELOW

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.

---
 scripts/get_maintainer.pl | 202
+++++++++++++++++++++++++++++++++++---
--------

 1 file changed, 156 insertions(+), 46 deletions(-)
scripts/get_maintainer.pl +1 -1
index 83a4e5bad2..8b6037b73f 100755
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
  # (c) 2007, Joe Perches <[email protected]>
  #           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;

scripts/get_maintainer.pl +3 -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;

scripts/get_maintainer.pl +1 -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 = (

scripts/get_maintainer.pl +1 -0
@@ -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");

scripts/get_maintainer.pl +0 -0
@@ -184,6 +193,27 @@ if (-f $conf) {
      unshift(@ARGV, @conf_args) if @conf_args;
  }

scripts/get_maintainer.pl +5 -0
+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>) {

scripts/get_maintainer.pl +15 -0
+	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,

scripts/get_maintainer.pl +3 -0
@@ -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,

  )) {

scripts/get_maintainer.pl +0 -0
@@ -242,7 +275,8 @@ $output_multiline = 0 if ($output_separator ne
 ",
 ");
  $output_rolestats = 1 if ($interactive);
  $output_roles = 1 if ($output_rolestats);

scripts/get_maintainer.pl +2 -1
-if ($sections) {
+if ($sections || $letters ne "") {
+    $sections = 1;

     $email = 0;
     $email_list = 0;
     $scm = 0;

scripts/get_maintainer.pl +0 -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 "

scripts/get_maintainer.pl +1 -1
-	. "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 = ();

scripts/get_maintainer.pl +2 -20
-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")

scripts/get_maintainer.pl +1 -0
+	or die "$P: Can't open MAINTAINERS file '$file': $!\n";

     while (<$maint>) {
  my $line = $_;

scripts/get_maintainer.pl +23 -1
@@ -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 !~
 /^\./);
+    }
  }

scripts/get_maintainer.pl +7 -0
+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";

scripts/get_maintainer.pl +5 -0
+}
+
+foreach my $file (@mfiles) {
+    read_maintainer_file("$file");
+}


 #
 # Read mail address map

scripts/get_maintainer.pl +2 -1
@@ -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

scripts/get_maintainer.pl +1 -0
+	$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)

scripts/get_maintainer.pl +0 -0
@@ -528,6 +584,16 @@ if ($web) {


 exit($exit);

scripts/get_maintainer.pl +10 -0
+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) = @_;

scripts/get_maintainer.pl +0 -0
@@ -659,8 +725,10 @@ sub get_maintainers {

  $line =~ s/\\\./\./g;        ##Conv
ert
\. to .
  $line =~ s/\.\*/\*/g;        ##Conv
ert
.* to *
      }

scripts/get_maintainer.pl +2 -2
-		    $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)) {

scripts/get_maintainer.pl +2 -0
+			print("$line\n");
+		    }

  }
  print("\n");
      }

scripts/get_maintainer.pl +0 -0
@@ -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

scripts/get_maintainer.pl +0 -0
@@ -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:

scripts/get_maintainer.pl +0 -0
@@ -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
 }

scripts/get_maintainer.pl +1 -1
@@ -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;
  }

scripts/get_maintainer.pl +1 -1
-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) {

scripts/get_maintainer.pl +1 -1
-	$subsystem = substr($subsystem, 0, 17);
+    if ($output_section_maxlen && length($subsystem) >

$output_section_maxlen) {

scripts/get_maintainer.pl +1 -1
+	$subsystem = substr($subsystem, 0, $output_section_maxlen
-

3);
  $subsystem =~ s/\s*$//;
  $subsystem = $subsystem . "...";
     }
+    return $subsystem;

scripts/get_maintainer.pl +11 -0
+}
+
+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];

scripts/get_maintainer.pl +0 -0
@@ -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);

scripts/get_maintainer.pl +1 -7
-
-    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 = "";

scripts/get_maintainer.pl +17 -0
@@ -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") {

scripts/get_maintainer.pl +0 -0
@@ -1868,6 +1959,7 @@ sub vcs_assign {
  	my $percent = $sign_offs * 100 / $divisor;


  $percent = 100 if ($percent > 100);

scripts/get_maintainer.pl +1 -0
+	next if (ignore_email_address($line));

  $count++;
  last if ($sign_offs < $email_git_min_signatures || $count > $email_git_max_maintainers ||

scripts/get_maintainer.pl +0 -0
@@ -2082,6 +2174,24 @@ sub vcs_file_blame {
      }
  }

scripts/get_maintainer.pl +18 -0
+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) = @_;

--
2.14.1