@@ -16,12 +16,14 @@ my $P = $0;
my $V = '0.26';
use Getopt::Long qw(:config no_auto_abbrev);
-use File::Find;
+use Cwd;
+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,6 +44,7 @@ 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;
@@ -128,6 +131,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 +160,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 +189,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 +227,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,
@@ -259,7 +286,8 @@ 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";
}
@@ -274,53 +302,34 @@ if (!top_of_kernel_tree($lk_path)) {
my @typevalue = ();
my %keyword_hash;
-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) = @_;
-
- while (<$maint>) {
- my $line = $_;
-
- if ($line =~ m/^([A-Z]):\s*(.*)/) {
- my $type = $1;
- my $value = $2;
-
- ##Filename pattern matching
- if ($type eq "F" || $type eq "X") {
- $value =~ s@\.@\\\.@g; ##Convert . to \.
- $value =~ s/\*/\.\*/g; ##Convert * to .*
- $value =~ s/\?/\./g; ##Convert ? to .
- ##if pattern is a directory and it lacks a trailing slash, add one
- if ((-d $value)) {
- $value =~ s@([^/])$@$1/@;
- }
- } elsif ($type eq "K") {
- $keyword_hash{@typevalue} = $value;
+open (my $maint, '<', "${lk_path}MAINTAINERS")
+ or die "$P: Can't open MAINTAINERS: $!\n";
+while (<$maint>) {
+ my $line = $_;
+
+ if ($line =~ m/^([A-Z]):\s*(.*)/) {
+ my $type = $1;
+ my $value = $2;
+
+ ##Filename pattern matching
+ if ($type eq "F" || $type eq "X") {
+ $value =~ s@\.@\\\.@g; ##Convert . to \.
+ $value =~ s/\*/\.\*/g; ##Convert * to .*
+ $value =~ s/\?/\./g; ##Convert ? to .
+ ##if pattern is a directory and it lacks a trailing slash, add one
+ if ((-d $value)) {
+ $value =~ s@([^/])$@$1/@;
}
- push(@typevalue, "$type:$value");
- } elsif (!/^(\s)*$/) {
- $line =~ s/\n$//g;
- push(@typevalue, $line);
+ } elsif ($type eq "K") {
+ $keyword_hash{@typevalue} = $value;
}
+ push(@typevalue, "$type:$value");
+ } elsif (!/^(\s)*$/) {
+ $line =~ s/\n$//g;
+ push(@typevalue, $line);
}
}
+close($maint);
#
@@ -421,7 +430,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 +539,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) = @_;
@@ -764,10 +785,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