[v2,5/6] maintainer_utils: Ensure the list of user data is sorted.

Message ID bmm.hlw1gcuuvc.gcc.gcc.rearnsha.222.2.5@forge-stage.sourceware.org
State Committed
Commit 58579b58f4fd109d8437991d44302ecc8925462b
Headers
Series maintainer_utils.py: general cleanups |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-aarch64-bootstrap success Build passed

Commit Message

Richard Earnshaw via Sourceware Forge Sept. 1, 2026, 2:36 p.m. UTC
  From: Richard Earnshaw <rearnsha@arm.com>

The YAML data for the list of maintainers is sorted by surname (sn) and
full name (cn).  Add a sort function that we use before storing the
data, with a couple of additional keys (account and forgeid) to ensure
the list is always fully ordered.  When verifying the data check the
sort order.

Since the store routine now handles this, clean up add-write-after to
remove the now unneeded sorting.

contrib/ChangeLog:

	* maintainer_utils.py (_unilower): New function.
	(sort_users): Likewise.
	(verify): Check the sort order of the user data.
	(store): Sort the user data before writing it.
	* add-write-after.py (unilower): Delete
	(main): No need to sort the user data here now.
---
 contrib/add-write-after.py  |  9 +--------
 contrib/maintainer_utils.py | 31 +++++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 8 deletions(-)
  

Patch

diff --git a/contrib/add-write-after.py b/contrib/add-write-after.py
index c6c11bbcf5c87..690fdbfb80200 100755
--- a/contrib/add-write-after.py
+++ b/contrib/add-write-after.py
@@ -25,17 +25,12 @@  import os
 import pwd
 import re
 import sys
-import unidecode
 import yaml
 
 from optparse import OptionParser
 
 import maintainer_utils as maintutils
 
-def unilower(txt):
-    """return a lower-case version of txt, mapping accented characters
-    onto their ASCII near equivalents."""
-    return unidecode.unidecode(txt).lower()
 
 def get_surname(name):
     parts = name.split()
@@ -148,9 +143,7 @@  def main():
         print("Note, this script can only be used to add new accounts.")
         return 1
     data['users'].append (newuser)
-    data['users'] = sorted(data['users'],
-                           key = lambda k: (unilower(k['sn']),
-                                            unilower(k['cn'])))
+
     if opts.outfilename and opts.outfilename == '-':
         maintutils.store(data)
     else:
diff --git a/contrib/maintainer_utils.py b/contrib/maintainer_utils.py
index 13861a0401c47..462d7d44e71e6 100755
--- a/contrib/maintainer_utils.py
+++ b/contrib/maintainer_utils.py
@@ -253,6 +253,12 @@  def _check_schema(data):
     return
 
 
+def _unilower(txt):
+    """return a lower-case version of txt, mapping accented characters
+    onto their ASCII near equivalents."""
+    return unidecode.unidecode(txt).lower()
+
+
 def _check_dco(user):
     # An email addrss in a DCO entry must also be listed in either the
     # active emails list, or the inactive_emails list.
@@ -270,6 +276,19 @@  def _check_dco(user):
             _error(f"User: {user['cn']} inactive_DCO {dco} also listed in DCO")
 
 
+def sort_users(user_data):
+    """Sort the user data into canonical order."""
+    return sorted(
+        user_data,
+        key = lambda k: (
+            _unilower(k['sn']),
+            _unilower(k['cn']),
+            k.get('account', ''),
+            k.get('forgeid', ''),
+        )
+    )
+
+
 def validate(data):
     """Check the data against the schema and our own consistency checks"""
     _check_schema(data)
@@ -321,6 +340,17 @@  def validate(data):
                     _error(f"Multiple subsystem entries for '{n}'.")
         if not seen_writeafter:
             _error(f"User '{u['cn']}' lacks WriteAfter role.")
+
+    sorted = sort_users(data['users'])
+    if sorted != data['users']:
+        _error("User data is incorrectly sorted.")
+        for right, wrong in zip(sorted, data['users']):
+            if right != wrong:
+                print(
+                    f"First incorrect entry is for {wrong['cn']}",
+                    file=sys.stderr
+                )
+                break
     if error_count:
         sys.exit(1)
     return
@@ -333,6 +363,7 @@  def load(file):
 
 
 def store(data, file=None, fd=sys.stdout):
+    data['users'] = sort_users(data['users'])
     # Make sure we don't write something that is not conformant
     validate(data)
     if file: