Re: [PATCH v2] get_maintainer: add --json output mode
From: Joe Perches
Date: Wed Apr 08 2026 - 16:11:57 EST
On Wed, 2026-04-08 at 15:45 -0400, Sasha Levin wrote:
> 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](mailto:sashal@xxxxxxxxxx)>
Thanks Sasha. Looks nicer now.
Acked-by: Joe Perches <joe@xxxxxxxxxxx>
> ---
> 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))
>
> ```