gcc/contrib/check-MAINTAINERS.py
Richard Sandiford 6fc24a0222 Add gcc.gnu.org account names to MAINTAINERS
As discussed in the thread starting at:

  https://gcc.gnu.org/pipermail/gcc/2024-June/244199.html

it would be useful to have the @gcc.gnu.org bugzilla account names
in MAINTAINERS.  This is because:

(a) Not every non-@gcc.gnu.org email listed in MAINTAINERS is registered
    as a bugzilla user.

(b) Only @gcc.gnu.org accounts tend to have full rights to modify tickets.

(c) A maintainer's name and email address aren't always enough to guess
    the bugzilla account name.

(d) The users list on bugzilla has many blank entries for "real name".

However, including @gcc.gnu.org to the account name might encourage
people to use it for ordinary email, rather than just for bugzilla.
This patch goes for the compromise of using the unqualified account
name, with some text near the top of the file to explain its usage.

There isn't room in the area maintainer sections for a new column,
so it seemed better to have the account name only in the Write
After Approval section.  It's then necessary to list all maintainers
there, even if they have more specific roles as well.

Also, there were some entries that didn't line up with the
prevailing columns (they had one tab too many or one tab too few).
It seemed easier to check for and report this, and other things,
if the file used spaces rather than tabs.

There was one instance of an email address without the trailing ">".
The updates to check-MAINTAINERS.py includes a test for that.

The account names in the file were taken from a trawl of the
gcc-cvs archives, with a very small number of manual edits for
ambiguities.  There are a handful of names that I couldn't find;
the new column has "-" for those.  The names were then filtered
against the bugzilla @gcc.gnu.org user list, with those not
present again being blanked out with "-".

ChangeLog:
	* MAINTAINERS: Replace tabs with spaces.  Add a bugzilla account
	name column to the Write After Approval section.  Line up the
	email column and fix an entry that was missing the trailing ">".

contrib/ChangeLog:
	* check-MAINTAINERS.py (sort_by_surname): Replace with...
	(get_surname): ...this.
	(has_tab, is_empty): Delete.
	(check_group): Take a list of column positions as argument.
	Check that lines conform to these column numbers.  Check that the
	final column is an email in angle brackets.  Record surnames on
	the fly.
	(top level): Reject tabs.  Use paragraph counts to identify which
	groups of lines should be checked.  Report missing sections.
2024-07-13 16:22:58 +01:00

150 lines
4.2 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright (C) 2022-2024 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.
import locale
import sys
from difflib import ndiff
from itertools import groupby
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_surname(name):
parts = name.split()
surname = parts[-1]
# Special-case some names
if name == 'Stefan Schulze Frielinghaus':
surname = parts[1]
elif name == 'Kris Van Hees':
surname = parts[1]
elif surname == "d'Humieres":
surname = 'Humieres'
# Remove accents
return unidecode.unidecode(surname)
def check_group(name, lines, columns):
global exit_code
named_lines = []
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_surname(line), line + "\n"))
continue
pieces = []
for i, column in enumerate(columns):
piece = ""
if len(line) <= column:
print(f'Line too short: "{line}"')
exit_code = 4
elif column > 0 and line[column - 1] != ' ':
print(f'Column {column - 1} should be empty: "{line}"')
exit_code = 5
elif line[column] == ' ':
print(f'Column {column} should be nonempty: "{line}"')
exit_code = 6
elif i == len(columns) - 1:
piece = line[column:].rstrip()
else:
piece = line[column:columns[i + 1]].rstrip()
if " " in piece:
print(f'Malformed field at column {column}: "{line}"')
exit_code = 7
pieces.append(piece)
named_lines.append((get_surname(pieces[0]), line + "\n"))
email = pieces[-1]
if email and (not email.startswith('<') or not email.endswith('>')):
print(f'Malformed email address: "{line}"')
exit_code = 8
lines = [line + "\n" for line in lines]
sorted_lines = [line for _, line in sorted(named_lines)]
if lines != sorted_lines:
exit_code = 1
diff = ndiff(lines, sorted_lines)
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
('Global Reviewers', 1, [0, 48]),
('Write After Approval', 2, [0, 32, 48]),
('Bug database only accounts', 1, [0, 48]),
('Contributing under the DCO', 2, [0, 48])
]
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])
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)