get_maintainer.pl: update from Linux kernel v5.13-rc6

Update U-Boot's version of scripts/get_maintainer.pl to sync it up with the
latest changes to the Linux kernel's version of the same script.

The last sync was with Linux kernel version v4.16. The commits to the kernel's
get_maintainer.pl since then (starting with the most recent) are:

	6343f6b71f83 get_maintainer: exclude MAINTAINERS file(s) from --git-fallback
	cdfe2d220476 get_maintainer: add test for file in VCS
	e33c9fe8b80c get_maintainer: fix unexpected behavior for path/to//file (double slashes)
	0c78c0137621 get_maintainer: add email addresses from .yaml files
	0ef82fcefb99 scripts/get_maintainer.pl: deprioritize old Fixes: addresses
	ef0c08192ac0 get_maintainer: remove uses of P: for maintainer name
	2f5bd343694e scripts/get_maintainer.pl: add signatures from Fixes: <badcommit> lines in commit message
	49662503e8e4 get_maintainer: add ability to skip moderated mailing lists
	0fbd75fd7fee get_maintainer: allow option --mpath <directory> to read all files in <directory>
	5f0baf95b1ed get_maintainer.pl: add -mpath=<path or file> for MAINTAINERS file location
	31bb82c9caa9 get_maintainer: allow usage outside of kernel tree
	0455c74788fd get_maintainer: improve patch recognition
	882ea1d64eb3 scripts: use SPDX tag in get_maintainer and checkpatch

Signed-off-by: Trevor Woerner <twoerner@gmail.com>
This commit is contained in:
Trevor Woerner 2021-06-15 03:30:29 -04:00 committed by Tom Rini
parent e94ef57952
commit e57c7c5c42

View file

@ -1,4 +1,6 @@
#!/usr/bin/env perl
# SPDX-License-Identifier: GPL-2.0
#
# (c) 2007, Joe Perches <joe@perches.com>
# created from checkpatch.pl
#
@ -7,8 +9,6 @@
#
# usage: perl scripts/get_maintainer.pl [OPTIONS] <patch>
# perl scripts/get_maintainer.pl [OPTIONS] -f <file>
#
# Licensed under the terms of the GNU GPL License version 2
use warnings;
use strict;
@ -19,6 +19,7 @@ my $V = '0.26';
use Getopt::Long qw(:config no_auto_abbrev);
use Cwd;
use File::Find;
use File::Spec::Functions;
my $cur_path = fastgetcwd() . '/';
my $lk_path = "./";
@ -26,7 +27,9 @@ my $email = 1;
my $email_usename = 1;
my $email_maintainer = 1;
my $email_reviewer = 1;
my $email_fixes = 1;
my $email_list = 1;
my $email_moderated_list = 1;
my $email_subscriber_list = 0;
my $email_git_penguin_chiefs = 0;
my $email_git = 0;
@ -48,24 +51,31 @@ my $output_roles = 0;
my $output_rolestats = 1;
my $output_section_maxlen = 50;
my $scm = 0;
my $tree = 1;
my $web = 0;
my $subsystem = 0;
my $status = 0;
my $letters = "";
my $keywords = 1;
my $sections = 0;
my $file_emails = 0;
my $email_file_emails = 0;
my $from_filename = 0;
my $pattern_depth = 0;
my $self_test = undef;
my $version = 0;
my $help = 0;
my $find_maintainer_files = 1;
my $find_maintainer_files = 0;
my $maintainer_path;
my $vcs_used = 0;
my $exit = 0;
my @files = ();
my @fixes = (); # If a patch description includes Fixes: lines
my @range = ();
my @keyword_tvi = ();
my @file_emails = ();
my %commit_author_hash;
my %commit_signer_hash;
@ -245,6 +255,8 @@ if (!GetOptions(
'r!' => \$email_reviewer,
'n!' => \$email_usename,
'l!' => \$email_list,
'fixes!' => \$email_fixes,
'moderated!' => \$email_moderated_list,
's!' => \$email_subscriber_list,
'multiline!' => \$output_multiline,
'roles!' => \$output_roles,
@ -253,14 +265,16 @@ if (!GetOptions(
'subsystem!' => \$subsystem,
'status!' => \$status,
'scm!' => \$scm,
'tree!' => \$tree,
'web!' => \$web,
'letters=s' => \$letters,
'pattern-depth=i' => \$pattern_depth,
'k|keywords!' => \$keywords,
'sections!' => \$sections,
'fe|file-emails!' => \$file_emails,
'fe|file-emails!' => \$email_file_emails,
'f|file' => \$from_filename,
'find-maintainer-files' => \$find_maintainer_files,
'mpath|maintainer-path=s' => \$maintainer_path,
'self-test:s' => \$self_test,
'v|version' => \$version,
'h|help|usage' => \$help,
@ -317,7 +331,7 @@ if ($email &&
die "$P: Please select at least 1 email option\n";
}
if (!top_of_kernel_tree($lk_path)) {
if ($tree && !top_of_kernel_tree($lk_path)) {
die "$P: The current directory does not appear to be "
. "a U-Boot source tree.\n";
}
@ -382,26 +396,52 @@ sub find_ignore_git {
read_all_maintainer_files();
sub read_all_maintainer_files {
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 !~ /^\./);
}
my $path = "${lk_path}MAINTAINERS";
if (defined $maintainer_path) {
$path = $maintainer_path;
# Perl Cookbook tilde expansion if necessary
$path =~ s@^~([^/]*)@ $1 ? (getpwnam($1))[7] : ( $ENV{HOME} || $ENV{LOGDIR} || (getpwuid($<))[7])@ex;
}
if ($find_maintainer_files) {
find( { wanted => \&find_is_maintainer_file,
preprocess => \&find_ignore_git,
no_chdir => 1,
}, "${lk_path}");
if (-d $path) {
$path .= '/' if ($path !~ m@/$@);
if ($find_maintainer_files) {
find( { wanted => \&find_is_maintainer_file,
preprocess => \&find_ignore_git,
no_chdir => 1,
}, "$path");
} else {
opendir(DIR, "$path") or die $!;
my @files = readdir(DIR);
closedir(DIR);
foreach my $file (@files) {
push(@mfiles, "$path$file") if ($file !~ /^\./);
}
}
} elsif (-f "$path") {
push(@mfiles, "$path");
} else {
push(@mfiles, "${lk_path}MAINTAINERS") if -f "${lk_path}MAINTAINERS";
die "$P: MAINTAINER file not found '$path'\n";
}
die "$P: No MAINTAINER files found in '$path'\n" if (scalar(@mfiles) == 0);
foreach my $file (@mfiles) {
read_maintainer_file("$file");
read_maintainer_file("$file");
}
}
sub maintainers_in_file {
my ($file) = @_;
return if ($file =~ m@\bMAINTAINERS$@);
if (-f $file && ($email_file_emails || $file =~ /\.yaml$/)) {
open(my $f, '<', $file)
or die "$P: Can't open $file: $!\n";
my $text = do { local($/) ; <$f> };
close($f);
my @poss_addr = $text =~ m$[A-Za-zÀ-ÿ\"\' \,\.\+-]*\s*[\,]*\s*[\(\<\{]{0,1}[A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+\.[A-Za-z0-9]+[\)\>\}]{0,1}$g;
push(@file_emails, clean_file_emails(@poss_addr));
}
}
@ -485,17 +525,13 @@ sub read_mailmap {
## use the filenames on the command line or find the filenames in the patchfiles
my @files = ();
my @range = ();
my @keyword_tvi = ();
my @file_emails = ();
if (!@ARGV) {
push(@ARGV, "&STDIN");
}
foreach my $file (@ARGV) {
if ($file ne "&STDIN") {
$file = canonpath($file);
##if $file is a directory and it lacks a trailing slash, add one
if ((-d $file)) {
$file =~ s@([^/])$@$1/@;
@ -503,11 +539,14 @@ foreach my $file (@ARGV) {
die "$P: file '${file}' not found\n";
}
}
if ($from_filename && (vcs_exists() && !vcs_file_exists($file))) {
warn "$P: file '$file' not found in version control $!\n";
}
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)) {
if ($file ne "MAINTAINERS" && -f $file && $keywords) {
open(my $f, '<', $file)
or die "$P: Can't open $file: $!\n";
my $text = do { local($/) ; <$f> };
@ -519,10 +558,6 @@ foreach my $file (@ARGV) {
}
}
}
if ($file_emails) {
my @poss_addr = $text =~ m$[A-Za-zÀ-ÿ\"\' \,\.\+-]*\s*[\,]*\s*[\(\<\{]{0,1}[A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+\.[A-Za-z0-9]+[\)\>\}]{0,1}$g;
push(@file_emails, clean_file_emails(@poss_addr));
}
}
} else {
my $file_cnt = @files;
@ -540,7 +575,20 @@ foreach my $file (@ARGV) {
while (<$patch>) {
my $patch_line = $_;
if (m/^\+\+\+\s+(\S+)/ or m/^---\s+(\S+)/) {
if (m/^ mode change [0-7]+ => [0-7]+ (\S+)\s*$/) {
my $filename = $1;
push(@files, $filename);
} elsif (m/^rename (?:from|to) (\S+)\s*$/) {
my $filename = $1;
push(@files, $filename);
} elsif (m/^diff --git a\/(\S+) b\/(\S+)\s*$/) {
my $filename1 = $1;
my $filename2 = $2;
push(@files, $filename1);
push(@files, $filename2);
} elsif (m/^Fixes:\s+([0-9a-fA-F]{6,40})/) {
push(@fixes, $1) if ($email_fixes);
} elsif (m/^\+\+\+\s+(\S+)/ or m/^---\s+(\S+)/) {
my $filename = $1;
$filename =~ s@^[^/]*/@@;
$filename =~ s@\n@@;
@ -570,6 +618,7 @@ foreach my $file (@ARGV) {
}
@file_emails = uniq(@file_emails);
@fixes = uniq(@fixes);
my %email_hash_name;
my %email_hash_address;
@ -584,7 +633,6 @@ my %deduplicate_name_hash = ();
my %deduplicate_address_hash = ();
my @maintainers = get_maintainers();
if (@maintainers) {
@maintainers = merge_email(@maintainers);
output(@maintainers);
@ -890,6 +938,8 @@ sub get_maintainers {
print("\n");
}
}
maintainers_in_file($file);
}
if ($keywords) {
@ -905,8 +955,10 @@ sub get_maintainers {
foreach my $file (@files) {
if ($email &&
($email_git || ($email_git_fallback &&
!$exact_pattern_match_hash{$file}))) {
($email_git ||
($email_git_fallback &&
$file !~ /MAINTAINERS$/ &&
!$exact_pattern_match_hash{$file}))) {
vcs_file_signoffs($file);
}
if ($email && $email_git_blame) {
@ -937,6 +989,10 @@ sub get_maintainers {
}
}
foreach my $fix (@fixes) {
vcs_add_commit_signers($fix, "blamed_fixes");
}
my @to = ();
if ($email || $email_list) {
if ($email) {
@ -997,11 +1053,13 @@ MAINTAINER field selection options:
--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
--moderated => include moderated lists(s) if any (default: true)
--s => include subscriber only list(s) if any (default: false)
--remove-duplicates => minimize duplicate email names/addresses
--roles => show roles (status:subsystem, git-signer, list, etc...)
--rolestats => show roles and statistics (commits/total_commits, %)
--file-emails => add email addresses found in -f file (default: 0 (off))
--fixes => for patches, add signatures of commits with 'Fixes: <commit>' (default: 1 (on))
--scm => print SCM tree(s) if any
--status => print status if any
--subsystem => print subsystem name if any
@ -1018,13 +1076,14 @@ Other options:
--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)
--no-tree => run without a kernel tree
--self-test => show potential issues with MAINTAINERS file content
--version => show version
--help => show this help information
Default options:
[--email --nogit --git-fallback --m --r --n --l --multiline --pattern-depth=0
--remove-duplicates --rolestats]
[--email --tree --nogit --git-fallback --m --r --n --l --multiline
--pattern-depth=0 --remove-duplicates --rolestats]
Notes:
Using "-f directory" may give unexpected results:
@ -1288,11 +1347,14 @@ sub add_categories {
} else {
if ($email_list) {
if (!$hash_list_to{lc($list_address)}) {
$hash_list_to{lc($list_address)} = 1;
if ($list_additional =~ m/moderated/) {
push(@list_to, [$list_address,
"moderated list${list_role}"]);
if ($email_moderated_list) {
$hash_list_to{lc($list_address)} = 1;
push(@list_to, [$list_address,
"moderated list${list_role}"]);
}
} else {
$hash_list_to{lc($list_address)} = 1;
push(@list_to, [$list_address,
"open list${list_role}"]);
}
@ -1300,35 +1362,11 @@ sub add_categories {
}
}
} elsif ($ptype eq "M") {
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_maintainer) {
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");
@ -1699,6 +1737,32 @@ sub vcs_is_hg {
return $vcs_used == 2;
}
sub vcs_add_commit_signers {
return if (!vcs_exists());
my ($commit, $desc) = @_;
my $commit_count = 0;
my $commit_authors_ref;
my $commit_signers_ref;
my $stats_ref;
my @commit_authors = ();
my @commit_signers = ();
my $cmd;
$cmd = $VCS_cmds{"find_commit_signers_cmd"};
$cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd
($commit_count, $commit_signers_ref, $commit_authors_ref, $stats_ref) = vcs_find_signers($cmd, "");
@commit_authors = @{$commit_authors_ref} if defined $commit_authors_ref;
@commit_signers = @{$commit_signers_ref} if defined $commit_signers_ref;
foreach my $signer (@commit_signers) {
$signer = deduplicate_email($signer);
}
vcs_assign($desc, 1, @commit_signers);
}
sub interactive_get_maintainers {
my ($list_ref) = @_;
my @list = @$list_ref;
@ -1792,7 +1856,7 @@ tm toggle maintainers
tg toggle git entries
tl toggle open list entries
ts toggle subscriber list entries
f emails in file [$file_emails]
f emails in file [$email_file_emails]
k keywords in file [$keywords]
r remove duplicates [$email_remove_duplicates]
p# pattern match depth [$pattern_depth]
@ -1917,7 +1981,7 @@ EOT
bool_invert(\$email_git_all_signature_types);
$rerun = 1;
} elsif ($sel eq "f") {
bool_invert(\$file_emails);
bool_invert(\$email_file_emails);
$rerun = 1;
} elsif ($sel eq "r") {
bool_invert(\$email_remove_duplicates);