From nobody Sun Jun 21 06:28:21 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9D2DE345741 for ; Mon, 6 Apr 2026 17:01:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775494901; cv=none; b=lo13THbjYFThJQWUQOKDutjhTw3ZtFcvXsntEy4WQxWPriKjb8R9ndcgSHWhXhFFDmFudC1VOIh1NtdP1cj5tTiNrBVwIsHoeXhX7veTa2vwIK+Q8GgdCxRwlqR8fan52SGaon4PhHEqvzJ9Zszi08kgcHrXmd41CK9J4w0gL/M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775494901; c=relaxed/simple; bh=BoLAQgE3ogJwMZ8QsboXTVrqtI2HVOlEqHoufIF/wWE=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=QzLNpjIIwUMlapZ6dFL9Uxew0cldOE/Zbv45BEL1uKBSbGBmeELCMJFN/cGSi1lnyik/XEiWmCFqew0V4aDgExq+neBe4qedpRF6LVy9g6LktYVtiBP5OJri/LsrQggHKm6zSKuitegIzrIZe7/J+n0KJNGvy29C4QHNi2vtIAs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ldqsMsAZ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ldqsMsAZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C3B3BC4CEF7; Mon, 6 Apr 2026 17:01:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775494901; bh=BoLAQgE3ogJwMZ8QsboXTVrqtI2HVOlEqHoufIF/wWE=; h=From:To:Cc:Subject:Date:From; b=ldqsMsAZhjZiVn1EZcA8XuHf3PBshKQjlCf+9hulOEg4biHthEdX3JnJvo5G2I6/G aG/BRQEZY7TzxW6/7gx4NwREgWoa7xRQzJPXuDEMpplvjL15C41/MB7IF/RMuVeWw6 qwHX0m0MljuFL5oE0c8CmCr9oPX/uvtIOeobe/oHeXUcpX44CNgVnTsSyZVQg+ai5v TjvA2pkh4/DFvbBCRfZkcy5yTP/btg6ln+eORe9Mzf5lOlUWr/ABWXzF4pG62wXPjC ELjZPNr5krwIEKu4QfXNhiehxqoHBBMS4h9tnv7OLC4IZVX21UAwqpk0VHH2V6dD/d rQVCixg8jseiQ== From: Sasha Levin To: joe@perches.com Cc: linux-kernel@vger.kernel.org, Sasha Levin Subject: [PATCH] get_maintainer: add --json output mode Date: Mon, 6 Apr 2026 13:01:38 -0400 Message-ID: <20260406170138.4034983-1-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- scripts/get_maintainer.pl | 114 +++++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 27 deletions(-) diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 4414194bedcfd..37817ca701bd6 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -68,6 +68,7 @@ my $pattern_depth =3D 0; my $self_test =3D undef; my $version =3D 0; my $help =3D 0; +my $json =3D 0; my $find_maintainer_files =3D 0; my $maintainer_path; my $vcs_used =3D 0; @@ -285,6 +286,7 @@ if (!GetOptions( 'find-maintainer-files' =3D> \$find_maintainer_files, 'mpath|maintainer-path=3Ds' =3D> \$maintainer_path, 'self-test:s' =3D> \$self_test, + 'json!' =3D> \$json, 'v|version' =3D> \$version, 'h|help|usage' =3D> \$help, )) { @@ -648,39 +650,74 @@ my %deduplicate_name_hash =3D (); my %deduplicate_address_hash =3D (); =20 my @maintainers =3D get_maintainers(); -if (@maintainers) { - @maintainers =3D merge_email(@maintainers); - output(@maintainers); -} =20 -if ($scm) { - @scm =3D uniq(@scm); - output(@scm); -} +if ($json) { + my @json_maintainers; + if (@maintainers) { + my %saw; + for (@maintainers) { + my ($address, $role) =3D @$_; + if (!$saw{$address}) { + my ($name, $email_addr) =3D parse_email($address); + my $entry =3D '{"name":"' . json_escape_str($name) . + '","email":"' . json_escape_str($email_addr) . '"'; + $entry .=3D ',"role":"' . json_escape_str($role) . '"' if ($output_roles= && $role ne ''); + $entry .=3D '}'; + push(@json_maintainers, $entry); + $saw{$address} =3D 1; + } + } + } =20 -if ($output_substatus) { - @substatus =3D uniq(@substatus); - output(@substatus); -} + @scm =3D uniq(@scm) if ($scm); + @status =3D uniq(@status) if ($status); + @subsystem =3D uniq(@subsystem) if ($subsystem); + @web =3D uniq(@web) if ($web); + @bug =3D uniq(@bug) if ($bug); =20 -if ($status) { - @status =3D uniq(@status); - output(@status); -} + my @fields; + push(@fields, '"maintainers":[' . join(',', @json_maintainers) . ']'); + push(@fields, '"scm":' . json_str_array(@scm)) if ($scm); + push(@fields, '"status":' . json_str_array(@status)) if ($status); + push(@fields, '"subsystem":' . json_str_array(@subsystem)) if ($subsys= tem); + push(@fields, '"web":' . json_str_array(@web)) if ($web); + push(@fields, '"bug":' . json_str_array(@bug)) if ($bug); + print('{' . join(',', @fields) . '}' . "\n"); +} else { + if (@maintainers) { + @maintainers =3D merge_email(@maintainers); + output(@maintainers); + } =20 -if ($subsystem) { - @subsystem =3D uniq(@subsystem); - output(@subsystem); -} + if ($scm) { + @scm =3D uniq(@scm); + output(@scm); + } =20 -if ($web) { - @web =3D uniq(@web); - output(@web); -} + if ($output_substatus) { + @substatus =3D uniq(@substatus); + output(@substatus); + } =20 -if ($bug) { - @bug =3D uniq(@bug); - output(@bug); + if ($status) { + @status =3D uniq(@status); + output(@status); + } + + if ($subsystem) { + @subsystem =3D uniq(@subsystem); + output(@subsystem); + } + + if ($web) { + @web =3D uniq(@web); + output(@web); + } + + if ($bug) { + @bug =3D uniq(@bug); + output(@bug); + } } =20 exit($exit); @@ -1099,6 +1136,7 @@ Output type options: --separator [, ] =3D> separator for multiple entries on 1 line using --separator also sets --nomultiline if --separator is not [, ] --multiline =3D> print 1 entry per line + --json =3D> output results as JSON =20 Other options: --pattern-depth =3D> Number of pattern directory traversals (default: 0 = (all)) @@ -2549,6 +2587,28 @@ sub merge_email { return @lines; } =20 +sub json_escape_str { + my ($str) =3D @_; + $str =3D~ s/\\/\\\\/g; + $str =3D~ s/"/\\"/g; + $str =3D~ s/\n/\\n/g; + $str =3D~ s/\r/\\r/g; + $str =3D~ s/\t/\\t/g; + $str =3D~ s/\x08/\\b/g; + $str =3D~ s/\x0c/\\f/g; + $str =3D~ s/([\x00-\x07\x0b\x0e-\x1f])/sprintf("\\u%04x", ord($1))/ge; + return $str; +} + +sub json_str_array { + my (@arr) =3D @_; + my @quoted; + foreach my $s (@arr) { + push(@quoted, '"' . json_escape_str($s) . '"'); + } + return '[' . join(',', @quoted) . ']'; +} + sub output { my (@parms) =3D @_; =20 --=20 2.53.0