[PATCH v2] get_maintainer: add --json output mode
From: Sasha Levin
Date: Wed Apr 08 2026 - 15:45:49 EST
Add a --json flag to get_maintainer.pl that emits structured JSON
output, making results machine-parseable for CI systems, IDE
integrations, and AI-assisted development tools.
The JSON output includes a maintainers array with structured name,
email, and role fields, plus optional arrays for scm, status,
subsystem, web, and bug information when those flags are enabled.
Normal text output behavior is completely unchanged when --json is
not specified.
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
---
Changes since v1:
- Replace hand-rolled json_escape_str()/json_str_array() with JSON::PP
module (core since perl 5.14)
- Reuse merge_email() for deduplication instead of reimplementing it,
per Joe's review
- Consolidate uniq() dedup calls before the json/non-json branch so
both paths share the same logic
---
scripts/get_maintainer.pl | 73 +++++++++++++++++++++++----------------
1 file changed, 43 insertions(+), 30 deletions(-)
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 4414194bedcfd..1bd4170684483 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -21,6 +21,7 @@ use Cwd;
use File::Find;
use File::Spec::Functions;
use open qw(:std :encoding(UTF-8));
+use JSON::PP;
my $cur_path = fastgetcwd() . '/';
my $lk_path = "./";
@@ -68,6 +69,7 @@ my $pattern_depth = 0;
my $self_test = undef;
my $version = 0;
my $help = 0;
+my $json = 0;
my $find_maintainer_files = 0;
my $maintainer_path;
my $vcs_used = 0;
@@ -285,6 +287,7 @@ if (!GetOptions(
'find-maintainer-files' => \$find_maintainer_files,
'mpath|maintainer-path=s' => \$maintainer_path,
'self-test:s' => \$self_test,
+ 'json!' => \$json,
'v|version' => \$version,
'h|help|usage' => \$help,
)) {
@@ -648,39 +651,48 @@ my %deduplicate_name_hash = ();
my %deduplicate_address_hash = ();
my @maintainers = get_maintainers();
-if (@maintainers) {
- @maintainers = merge_email(@maintainers);
- output(@maintainers);
-}
-
-if ($scm) {
- @scm = uniq(@scm);
- output(@scm);
-}
-
-if ($output_substatus) {
- @substatus = uniq(@substatus);
- output(@substatus);
-}
-
-if ($status) {
- @status = uniq(@status);
- output(@status);
-}
-if ($subsystem) {
- @subsystem = uniq(@subsystem);
- output(@subsystem);
-}
+@maintainers = merge_email(@maintainers) if (@maintainers);
+@scm = uniq(@scm) if ($scm);
+@substatus = uniq(@substatus) if ($output_substatus);
+@status = uniq(@status) if ($status);
+@subsystem = uniq(@subsystem) if ($subsystem);
+@web = uniq(@web) if ($web);
+@bug = uniq(@bug) if ($bug);
+
+if ($json) {
+ my @json_maintainers;
+ for my $m (@maintainers) {
+ my ($addr, $role);
+ if ($output_roles && $m =~ /^(.*?)\s+\((.+)\)\s*$/) {
+ $addr = $1;
+ $role = $2;
+ } else {
+ $addr = $m;
+ }
+ my ($name, $email_addr) = parse_email($addr);
+ my %entry = (name => $name, email => $email_addr);
+ $entry{role} = $role if (defined $role && $role ne '');
+ push(@json_maintainers, \%entry);
+ }
-if ($web) {
- @web = uniq(@web);
- output(@web);
-}
+ my %result = (maintainers => \@json_maintainers);
+ $result{scm} = \@scm if ($scm);
+ $result{status} = \@status if ($status);
+ $result{subsystem} = \@subsystem if ($subsystem);
+ $result{web} = \@web if ($web);
+ $result{bug} = \@bug if ($bug);
-if ($bug) {
- @bug = uniq(@bug);
- output(@bug);
+ my $json_encoder = JSON::PP->new->canonical->utf8;
+ print($json_encoder->encode(\%result) . "\n");
+} else {
+ output(@maintainers) if (@maintainers);
+ output(@scm) if ($scm);
+ output(@substatus) if ($output_substatus);
+ output(@status) if ($status);
+ output(@subsystem) if ($subsystem);
+ output(@web) if ($web);
+ output(@bug) if ($bug);
}
exit($exit);
@@ -1099,6 +1111,7 @@ Output type options:
--separator [, ] => separator for multiple entries on 1 line
using --separator also sets --nomultiline if --separator is not [, ]
--multiline => print 1 entry per line
+ --json => output results as JSON
Other options:
--pattern-depth => Number of pattern directory traversals (default: 0 (all))
--
2.53.0