From: Richard Earnshaw <[email protected]>

Now that the MAINTAINERS.yml data is as we desire it, use it to generate
a new version of the MAINTAINERS file.  Update the testsuite to check
that the MAINTAINERS file is correctly generated from the YAML.

Remove contrib/check-MAINTAINERS.py: it's nolonger needed now that
we generate the file automatically.

ChangeLog:

        * MAINTAINERS: Regenerate from MAINTAINERS.yml

contrib/ChangeLog:

        * check-MAINTAINERS.py: Delete.

gcc/testsuite/ChangeLog:

        * gcc.src/maintainers.exp:
---
 MAINTAINERS                           |  27 +--
 contrib/check-MAINTAINERS.py          | 229 --------------------------
 gcc/testsuite/gcc.src/maintainers.exp |  29 +++-
 3 files changed, 37 insertions(+), 248 deletions(-)
 delete mode 100755 contrib/check-MAINTAINERS.py

diff --git a/MAINTAINERS b/MAINTAINERS
index b978c6b50ea6..4b2bfb13dbc5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1,6 +1,11 @@
 Note
 ====
 
+This file is autogenerated.  DO NOT EDIT or your changes will be lost.
+Instead, add your details to contrib/MAINTAINERS.yml and run
+
+        contrib/gen-MAINTAINERS.py -o MAINTAINERS MAINTAINERS.yml
+
 This file contains information about people who are permitted to make
 changes to various parts of the compiler and associated libraries.
 
@@ -23,9 +28,6 @@ Note: when adding someone who has commit access to a more 
specific section,
 please also ensure that there is a corresponding entry in the Write After
 Approval list, since that list contains the gcc.gnu.org account name.
 
-Note: please verify that sorting is correct with:
-./contrib/check-MAINTAINERS.py MAINTAINERS
-
 Maintainers
 ===========
 
@@ -222,14 +224,17 @@ jump.cc                 David S. Miller         
<[email protected]>
 libbacktrace            Ian Lance Taylor        <[email protected]>
 libcpp                  Per Bothner             <[email protected]>
 libcpp                  David Malcolm           <[email protected]>
-libcpp                  All C and C++ front end maintainers
+libcpp                  Jason Merrill           <[email protected]>
+libcpp                  Joseph Myers            <[email protected]>
+libcpp                  Nathan Sidwell          <[email protected]>
 libga68                 Jose E. Marchesi        <[email protected]>
 libgcc                  Ian Lance Taylor        <[email protected]>
 libgo                   Ian Lance Taylor        <[email protected]>
 libgomp                 Tobias Burnus           <[email protected]>
 libgomp                 Jakub Jelinek           <[email protected]>
 libgomp (OpenACC)       Thomas Schwinge         <[email protected]>
-libgrust                All Rust front end maintainers
+libgrust                Arthur Cohen            <[email protected]>
+libgrust                Philip Herron           <[email protected]>
 libiberty               Ian Lance Taylor        <[email protected]>
 libitm                  Torvald Riegel          <[email protected]>
 libobjc                 Nicola Pero             
<[email protected]>
@@ -338,13 +343,13 @@ from other maintainers or reviewers.
 
 Name                            BZ account      Email
 
-Soumya AR                       soumyaa         <[email protected]>
 Spencer Abson                   sabson          
<[email protected]>
 Mark G. Adams                   mgadams         <[email protected]>
 Ajit Kumar Agarwal              aagarwa         <[email protected]>
 Pedro Alves                     palves          <[email protected]>
 John David Anglin               danglin         <[email protected]>
 Harald Anlauf                   anlauf          <[email protected]>
+Soumya AR                       soumyaa         <[email protected]>
 Paul-Antoine Arras              parras          <[email protected]>
 Arsen Arsenović                 arsen           <[email protected]>
 Raksit Ashok                    raksit          <[email protected]>
@@ -622,10 +627,10 @@ Prathamesh Kulkarni             prathamesh3492  
<[email protected]>
 Venkataramanan Kumar            vekumar         <[email protected]>
 Maxim Kuvyrkov                  mkuvyrkov       <[email protected]>
 Doug Kwan                       dougkwan        <[email protected]>
-Aaron W. LaFramboise            aaronwl         <[email protected]>
 Scott Robert Ladd               srladd          <[email protected]>
 Razya Ladelsky                  razya           <[email protected]>
 Thierry Lafage                  tlafage         <[email protected]>
+Aaron W. LaFramboise            aaronwl         <[email protected]>
 Rask Ingemann Lambertsen        rask            <[email protected]>
 Jerome Lambourg                 lambourg        <[email protected]>
 Tim Lange                       tlange          <[email protected]>
@@ -648,7 +653,7 @@ Renlin Li                       renlin          
<[email protected]>
 Xinliang David Li               davidxl         <[email protected]>
 Kewen Lin                       linkw           <[email protected]>
 Chen Liqin                      liqin           <[email protected]>
-Martin Liska                    marxin          <[email protected]>
+Martin LiÅ¡ka                    marxin          <[email protected]>
 Hao Liu                         hliu            <[email protected]>
 Hongtao Liu                     liuhongt        <[email protected]>
 Jiangning Liu                   liujiangning    <[email protected]>
@@ -670,8 +675,8 @@ Christophe Lyon                 clyon           
<[email protected]>
 Jin Ma                          majin           <[email protected]>
 Jun Ma                          junma           <[email protected]>
 Yuao Ma                         yuao            <[email protected]>
-Andrew MacLeod                  amacleod        <[email protected]>
 Luis Machado                    luisgpm         <[email protected]>
+Andrew MacLeod                  amacleod        <[email protected]>
 Ziga Mahkovec                   ziga            <[email protected]>
 Vladimir Makarov                vmakarov        <[email protected]>
 David Malcolm                   dmalcolm        <[email protected]>
@@ -727,7 +732,7 @@ Thomas Neumann                  tneumann        
<[email protected]>
 Dan Nicolaescu                  dann            <[email protected]>
 Kelvin Nilsen                   kelvin          <[email protected]>
 Hans-Peter Nilsson              hp              <[email protected]>
-James Norris
+James Norris                    -               <[email protected]>
 Diego Novillo                   dnovillo        <[email protected]>
 Dorit Nuzman                    dorit           <[email protected]>
 David O'Brien                   obrien          <[email protected]>
@@ -980,7 +985,7 @@ Robin Dapp                                      
<[email protected]>
 Robin Dapp                                      <[email protected]>
 Robin Dapp                                      <[email protected]>
 Prachi Godbole                                  <[email protected]>
-Naveen Gowda                                    
<[email protected]>
+Naveen H.S                                      
<[email protected]>
 Aldy Hernandez                                  <[email protected]>
 Michal Jires                                    <[email protected]>
 Matthias Kretz                                  <[email protected]>
diff --git a/contrib/check-MAINTAINERS.py b/contrib/check-MAINTAINERS.py
deleted file mode 100755
index b7a2dd9b229d..000000000000
--- a/contrib/check-MAINTAINERS.py
+++ /dev/null
@@ -1,229 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (C) 2022-2026 Free Software Foundation, Inc.
-#
-# This file is part of GCC.
-#
-# GCC is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GCC is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING.  If not, write to
-# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-# Boston, MA 02110-1301, USA.
-
-# Check that names in the file are sorted alphabetically by surname, name
-# bugzilla handle and email (in this order).
-
-import locale
-import sys
-import re
-from itertools import groupby
-from operator import itemgetter
-from difflib import ndiff
-import unidecode
-
-locale.setlocale(locale.LC_ALL, 'en_US.utf8')
-
-exit_code = 0
-
-if len(sys.argv) != 2:
-    print('Usage: ./check-MAINTAINERS.py path-to/MAINTAINERS')
-    sys.exit(1)
-
-
-def get_name_for_sort(name):
-    parts = name.split()
-    surname = parts[-1] + ", " + " ".join(parts[:-1])
-
-    # Special-case some names
-    if (name == 'Stefan Schulze Frielinghaus'
-        or name == 'Kris Van Hees'):
-        surname = " ".join(parts[1:]) + ", " + parts[0]
-    if surname.startswith("d'"):
-        surname = surname[2:]
-
-    # Remove accents
-    return unidecode.unidecode(surname)
-
-
-def check_group(name, lines, columns, matcher, sort_by):
-    global exit_code
-    named_lines = []
-    rex = re.compile (matcher)
-    for line in lines:
-        if line.startswith(' '):
-            print(f'Line should not start with space: "{line}"')
-            exit_code = 2
-            continue
-
-        if line.endswith(' '):
-            print(f'Line should not end with space: "{line}"')
-            exit_code = 3
-            continue
-
-        # Special-case some names
-        if line == 'James Norris':
-            named_lines.append((get_name_for_sort(line), "", "", line))
-            continue
-
-        fields = rex.match(line)
-        if not fields:
-            print(f'Could not parse line: "{line}"')
-            exit_code = 3
-            continue
-
-        matched_keys = [
-            name for name, idx in sorted (rex.groupindex.items(),
-                                        key=lambda x: x[1])
-            if fields.group(idx) is not None]
-
-        pos = 0
-        for i, k in enumerate (matched_keys):
-            if i >= len (columns):
-                break
-            if pos < columns[i]:
-                pos = columns[i]
-            start = fields.start(k)
-            if k == 'email':
-                start -= 1  # Account for the leading '<'
-            if start == pos:
-                True
-            elif (start > pos
-                  and pos > 2
-                  and k == 'email'
-                  and line[start-1] == " "
-                  and line[start-2] != " "):
-                True
-            elif (start > pos
-                  and k != 'email'
-                  and pos > 3
-                  and line[start-2:start] == "  "
-                  and line[start-3] != " "):
-                True
-            else:
-                exit_code = 3
-                print (line)
-                print (f"{k} starts in the wrong column: expected: {pos}, 
actual {start}")
-            pos += 1 + len (fields[k].rstrip())
-
-        fields = fields.groupdict()
-        if 'Team' in fields and fields['Team']:
-            fields['User'] = fields['Team']
-            fields['email'] = ""
-        pieces = []
-        for i, f in enumerate (sort_by):
-            if f not in fields:
-                print('Internal error: re mismatch')
-                sys.exit(10)
-            if f == 'User':
-                pieces.append(get_name_for_sort(fields[f].rstrip()))
-            elif f == 'component':
-                pieces.append(fields[f].rstrip().lower())
-            else:
-                pieces.append(fields[f].rstrip())
-        pieces.append (line)
-        named_lines.append(pieces)
-
-    order = []
-    for i, _ in enumerate (sort_by):
-        order.append(i)
-    order = tuple(order)
-    lines = [line + "\n" for line in lines]
-    sorted_lines = [line[-1] + "\n"
-                    for line in sorted(named_lines,
-                                       key = itemgetter(*order))]
-    if lines != sorted_lines:
-        exit_code = 1
-        diff = [line for line in ndiff(lines, sorted_lines)
-                if not line.startswith('? ')]
-        print(f'Wrong order for {name}:\n')
-        print(''.join(diff))
-    else:
-        print(f'{name} are fine!')
-
-
-text = open(sys.argv[1]).read()
-if '\t' in text:
-    print('The file should not contain tabs')
-    exit_code = 9
-
-sections = [
-    # heading, paragraph index, column numbers, regex, sort order
-    ('Global Reviewers',
-     1,
-     [0, 48],
-     r'^(?P<User>.{47}) <(?P<email>.*)>$',
-     ['User', 'email']),
-    ('CPU Port Maintainers    (CPU alphabetical order)',
-     1,
-     [0, 24, 48],
-     r'^(?P<component>.{23}) (?P<User>.*) <(?P<email>[^<>]*)>$',
-     ['component', 'User', 'email']),
-    ('OS Port Maintainers     (OS alphabetical order)',
-     1,
-     [0, 24, 48],
-     r'^(?P<component>.{23}) (?P<User>.*) <(?P<email>[^<>]*)>$',
-     ['component', 'User', 'email']),
-    ('Language Front Ends Maintainer',
-     1,
-     [0, 24, 48],
-     r'^(?P<component>.{23}) (?P<User>.*) <(?P<email>[^<>]*)>$',
-     ['component', 'User', 'email']),
-    ('Various Maintainers',
-     1,
-     [0, 24, 48],
-     r'''(?x)
-         ^(?P<component>(?:(?!\s\s).)*)\s\s+
-         (?:(?P<Team>All.*maintainers)
-          |(?P<User>[^\s].*)\s+<(?P<email>[^<>]*)>)$''',
-     ['component', 'User', 'email']),
-    ('Reviewers',
-     1,
-     [0, 24, 48],
-     r'^(?P<component>(?:(?!  ).)*)  +(?P<User>[^\s].*) <(?P<email>[^<>]*)>$',
-     ['component', 'User', 'email']),
-    ('Write After Approval',
-     2,
-     [0, 32, 48],
-     r'^(?P<User>.{31}) (?P<account>.{15}) <(?P<email>[^<>]*)>$',
-     ['User', 'email', 'account']),
-    ('Bug database only accounts',
-     1,
-     [0, 48],
-     r'^(?P<User>.{47}) <(?P<email>[^<>]*)>$',
-     ['User', 'email']),
-    ('Contributing under the DCO',
-     2,
-     [0, 48],
-     r'^(?P<User>.{47}) <(?P<email>[^<>]*)>$',
-     ['User', 'email'])
-]
-
-i = 0
-count = 0
-for is_empty, lines in groupby(text.splitlines(), lambda x: not x):
-    if is_empty:
-        continue
-    lines = list(lines)
-    if count > 0:
-        count -= 1
-        if count == 0:
-            check_group(sections[i][0], lines, sections[i][2], sections[i][3],
-                        sections[i][4])
-            i += 1
-    elif len(lines) == 1 and i < len(sections) and sections[i][0] in lines[0]:
-        count = sections[i][1]
-
-if i < len(sections):
-    print(f'Missing "{sections[i][0]}" section')
-    exit_code = 10
-
-sys.exit(exit_code)
diff --git a/gcc/testsuite/gcc.src/maintainers.exp 
b/gcc/testsuite/gcc.src/maintainers.exp
index afcec804748c..ec5b23f35faa 100644
--- a/gcc/testsuite/gcc.src/maintainers.exp
+++ b/gcc/testsuite/gcc.src/maintainers.exp
@@ -17,31 +17,44 @@
 load_lib "target-supports.exp"
 
 proc gcc_src_run_maintainers_verify_sh {} {
-    set script check-MAINTAINERS.py
+    set script gen-MAINTAINERS.py
 
     global srcdir
     set rootdir $srcdir/../..
     set contrib $rootdir/contrib
     set maintainers $rootdir/MAINTAINERS
+    set maintainers_yml $rootdir/MAINTAINERS.yml
 
     if { ![check_effective_target_recent_python3] } {
       unsupported "$script recent python3 is missing"
       return
     }
 
-    if { ![check_effective_target_python3_module "unidecode"] } {
-      unsupported "$script 'unidecode' python3 module is missing"
-      return
+    foreach pylib {"unidecode" "jsonschema" "yaml"} {
+       if { ![check_effective_target_python3_module $pylib] } {
+           unsupported "$script '$pylib' python3 module is missing"
+           return
+       }
     }
 
-
-    set result [remote_exec host $contrib/$script $maintainers]
+    # This will generate a new copy of the MAINTAINERS data from the
+    # YAML data after performing some sanity checks on the input.  There
+    # are two failure modes to consider - the YAML is invalid and the
+    # generated result does not match the expected MAINTAINERS file.
+    set result [remote_exec host $contrib/$script "-o MAINTAINERS.tst 
$maintainers_yml"]
     set status [lindex $result 0]
     if { $status == 0 } then {
-       pass "$script"
+       set result [remote_exec host "diff" "-u $maintainers MAINTAINERS.tst"]
+       set status [lindex $result 0]
+       if { $status == 0 } then {
+           pass "$script"
+       } else {
+           send_log "$result\n"
+           fail "$script: $maintainers not updated correctly"
+       }
     } else {
        send_log "$result\n"
-       fail "$script"
+       fail "$script: generate failed"
     }
 }
 
-- 
2.54.0

Reply via email to