https://gcc.gnu.org/g:4aab703df1b7002f7b1d7ae9a842b2d775dfb56e

commit r17-3872-g4aab703df1b7002f7b1d7ae9a842b2d775dfb56e
Author: Richard Earnshaw <[email protected]>
Date:   Thu Aug 20 12:30:27 2026 +0100

    maintainer_utils: Move DCO entries outside of roles.
    
    Logically, DCO entries are just another list of email addresses; they
    aren't really roles within the project.  This patch splits them out of
    the roles entry into their own list.  It does make it a bit more work to
    re-generate the MAINTAINERS file, but it isn't enough to continue using
    the existing structure.  While there, add some additional validation of
    DCO entries: addresses used for a DCO must either be in the list of
    active emails or the list of inactive ones.
    
    contrib/ChangeLog:
    
            * maintainer_utils.py (maintainer_schema): Move the DCO data
            to a top-level user list.  Ensure that each user entry has at
            least one of roles and DCO.
            (_check_dco): New function.
            (validate): Use it.  Handle roles being absent.
            * gen-MAINTAINERS.py (format_output):  Scan the list of DCO
            entries if generating the DCO table.  Split the overflowing
            field logic into ...
            (paginate): ... here.
            * add-write-after.py (getuserdata): Write DCO data to new field.
            Check that DCO email address is known and add to inactive_email
            if not.
    
    ChangeLog:
    
            * MAINTAINERS.yml: Move all DCO 'roles' to a separate list.

Diff:
---
 MAINTAINERS.yml             | 194 ++++++++++++++++++++++++++++----------------
 contrib/add-write-after.py  |  12 ++-
 contrib/gen-MAINTAINERS.py  |  40 ++++++---
 contrib/maintainer_utils.py |  40 ++++++---
 4 files changed, 192 insertions(+), 94 deletions(-)

diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml
index e14432c67ee1..b48c753ede97 100644
--- a/MAINTAINERS.yml
+++ b/MAINTAINERS.yml
@@ -71,8 +71,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: soumyaa
+  DCO:
+  - [email protected]
 - sn: Arras
   cn: Paul-Antoine Arras
   email:
@@ -227,11 +228,12 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
-  - DCO: [email protected]
   account: dbarboza
   aliases:
   - Daniel Henrique Barboza
+  DCO:
+  - [email protected]
+  - [email protected]
 - sn: Bauermann
   cn: Thiago Jung Bauermann
   email:
@@ -340,11 +342,12 @@ users:
   roles:
   - Reviewer: register allocation
   - WriteAfter
-  - DCO: [email protected]
   account: bergner
   inactive_email:
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Berlin
   cn: Daniel Berlin
   email:
@@ -845,8 +848,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: dhruvc
+  DCO:
+  - [email protected]
 - sn: Chen
   cn: Dehao Chen
   email:
@@ -864,11 +868,12 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
-  - DCO: [email protected]
   account: zhongyao
   aliases:
   - zhongyao
+  DCO:
+  - [email protected]
+  - [email protected]
 - sn: Chêne
   cn: Fabien Chêne
   email:
@@ -966,8 +971,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: jchrist
+  DCO:
+  - [email protected]
 - sn: Christina
   cn: Tamar Christina
   email:
@@ -1063,10 +1069,11 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: alx
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Conner
   cn: Josh Conner
   email:
@@ -1187,8 +1194,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: peppe
+  DCO:
+  - [email protected]
 - sn: Dabbelt
   cn: Palmer Dabbelt
   email:
@@ -1238,14 +1246,15 @@ users:
   - Maintainer: riscv port
   - Reviewer: vectorizer (+ tree-if-conv)
   - WriteAfter
-  - DCO: [email protected]
-  - DCO: [email protected]
-  - DCO: [email protected]
   account: rdapp
   inactive_email:
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
+  - [email protected]
+  - [email protected]
 - sn: Dardis
   cn: Simon Dardis
   email:
@@ -1677,10 +1686,11 @@ users:
   roles:
   - Reviewer: CTF, BTF, bpf port
   - WriteAfter
-  - DCO: [email protected]
   account: dfaust
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Feifer
   cn: Sam Feifer
   email:
@@ -1763,8 +1773,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: kael
+  DCO:
+  - [email protected]
 - sn: Franke
   cn: Daniel Franke
   email:
@@ -1918,11 +1929,12 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: pgodbole
   inactive_email:
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Granlund
   cn: Torbjorn Granlund
   email:
@@ -2067,10 +2079,11 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: eikansh
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Gupta
   cn: Vineet Gupta
   email:
@@ -2089,7 +2102,6 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: naveenh
   aliases:
   - Naveen Gowda
@@ -2099,6 +2111,8 @@ users:
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Hagog
   cn: Mostafa Hagog
   email:
@@ -2313,11 +2327,12 @@ users:
   - Maintainer: '*gimpl*'
   - Maintainer: '*vrp, ranger'
   - WriteAfter
-  - DCO: [email protected]
   account: aldyh
   inactive_email:
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Herron
   cn: Philip Herron
   email:
@@ -2730,8 +2745,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: mjires
+  DCO:
+  - [email protected]
 - sn: Johnson
   cn: Janis Johnson
   email:
@@ -3078,10 +3094,11 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: mkretz
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Krupp
   cn: Louis Krupp
   email:
@@ -3098,11 +3115,12 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: prathamesh3492
   inactive_email:
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Kumar
   cn: Venkataramanan Kumar
   email:
@@ -3205,9 +3223,10 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: tlange
   inactive: true
+  DCO:
+  - [email protected]
 - sn: Langton
   cn: Asher Langton
   email:
@@ -3269,11 +3288,6 @@ users:
   - Maintainer: scheduler (+ haifa)
     email: [email protected]
   - WriteAfter: [email protected]
-  - DCO: [email protected]
-  - DCO: [email protected]
-  - DCO: [email protected]
-  - DCO: [email protected]
-  - DCO: [email protected]
   account: law
   aliases:
   - jlaw
@@ -3282,6 +3296,12 @@ users:
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
+  - [email protected]
+  - [email protected]
+  - [email protected]
+  - [email protected]
 - sn: Lawrence
   cn: Alan Lawrence
   email:
@@ -3338,8 +3358,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: garthlei
+  DCO:
+  - [email protected]
 - sn: Lemke
   cn: James Lemke
   email:
@@ -3413,8 +3434,8 @@ users:
   cn: Jim Lin
   email:
   - [email protected]
-  roles:
-  - DCO: [email protected]
+  DCO:
+  - [email protected]
 - sn: Lin
   cn: Kewen Lin
   email:
@@ -3446,8 +3467,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: marxin
+  DCO:
+  - [email protected]
 - sn: Liu
   cn: Hao Liu
   email:
@@ -3592,7 +3614,6 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: hjl
   inactive_email:
   - [email protected]
@@ -3600,6 +3621,8 @@ users:
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Luo
   cn: Longjun Luo
   email:
@@ -3607,8 +3630,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: anatasluo
+  DCO:
+  - [email protected]
 - sn: Luo
   cn: Xiong Hu Luo
   email:
@@ -3667,8 +3691,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: yuao
+  DCO:
+  - [email protected]
 - sn: Machado
   cn: Luis Machado
   email:
@@ -3742,10 +3767,11 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: matmal01
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Maltsev
   cn: Mikhail Maltsev
   email:
@@ -3768,9 +3794,10 @@ users:
   - Maintainer: libga68
     email: [email protected]
   - WriteAfter
-  - DCO: [email protected]
   account: jemarch
   forgeid: jemarch
+  DCO:
+  - [email protected]
 - sn: Markianos-Wright
   cn: Stamatis Markianos-Wright
   email:
@@ -4036,12 +4063,13 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: mir
   inactive: true
   inactive_email:
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Miranda
   cn: Cupertino Miranda
   email:
@@ -4182,10 +4210,11 @@ users:
   roles:
   - Maintainer: Modula-2 front end
   - WriteAfter
-  - DCO: [email protected]
   account: gaius
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Müllner
   cn: Christoph Müllner
   email:
@@ -4199,9 +4228,9 @@ users:
   email:
   - [email protected]
   - [email protected]
-  roles:
-  - DCO: [email protected]
-  - DCO: [email protected]
+  DCO:
+  - [email protected]
+  - [email protected]
 - sn: Munroe
   cn: Steven Munroe
   email:
@@ -4263,11 +4292,12 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: nsz
   inactive: true
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Nascimento
   cn: Victor Do Nascimento
   email:
@@ -4568,11 +4598,12 @@ users:
   - Maintainer: Rust
   - Maintainer: libgrust
   - WriteAfter
-  - DCO: [email protected]
-  - DCO: [email protected]
   inactive_email:
   - [email protected]
   account: pep
+  DCO:
+  - [email protected]
+  - [email protected]
 - sn: Pavenis
   cn: Andris Pavenis
   email:
@@ -4635,10 +4666,11 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: mikpe
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Pfau
   cn: Johannes Pfau
   email:
@@ -4688,8 +4720,6 @@ users:
     email: [email protected]
   - Reviewer: aarch64 port
   - WriteAfter: [email protected]
-  - DCO: [email protected]
-  - DCO: [email protected]
   account: pinskia
   forgeid: pinskia
   inactive_email:
@@ -4700,6 +4730,9 @@ users:
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
+  - [email protected]
 - sn: Pitre
   cn: Nicolas Pitre
   email:
@@ -4784,13 +4817,14 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: siddhesh
   inactive_email:
   - [email protected]
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Praveen
   cn: Vidya Praveen
   email:
@@ -4881,7 +4915,6 @@ users:
   roles:
   - Maintainer: arm port
   - WriteAfter
-  - DCO: [email protected]
   account: ramana
   inactive_email:
   - [email protected]
@@ -4890,17 +4923,20 @@ users:
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Rahimi
   cn: Navid Rahimi
   email:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: navidr
   inactive: true
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Raj
   cn: Rishi Raj
   email:
@@ -4908,9 +4944,10 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: rshraj45035
   inactive: true
+  DCO:
+  - [email protected]
 - sn: Raman
   cn: Easwaran Raman
   email:
@@ -5004,8 +5041,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: egas
+  DCO:
+  - [email protected]
 - sn: Richards
   cn: Alfie Richards
   email:
@@ -5249,12 +5287,13 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: tbsaunde
   inactive: true
   inactive_email:
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Sawdey
   cn: Aaron Sawdey
   email:
@@ -5312,14 +5351,14 @@ users:
   cn: Bill Schmidt
   email:
   - [email protected]
-  roles:
-  - DCO: [email protected]
   inactive: true
   inactive_email:
   - [email protected]
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Schmidt
   cn: Will Schmidt
   email:
@@ -5490,8 +5529,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: nshead
+  DCO:
+  - [email protected]
 - sn: Shen
   cn: Tim Shen
   email:
@@ -5534,12 +5574,13 @@ users:
   - Maintainer: libcpp
   - Maintainer: gcov
   - WriteAfter
-  - DCO: [email protected]
   account: nathan
   inactive_email:
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Singhai
   cn: Sharad Singhai
   email:
@@ -5593,11 +5634,12 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: emsr
   inactive: true
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Sokolov
   cn: Anatoly Sokolov
   email:
@@ -5636,10 +5678,11 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: maskray
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Stallman
   cn: Richard Stallman
   email:
@@ -5981,11 +6024,12 @@ users:
   roles:
   - Maintainer: aarch64 port
   - WriteAfter
-  - DCO: [email protected]
   account: ktkachov
   forgeid: ktkachov
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Tobler
   cn: Andreas Tobler
   email:
@@ -6019,11 +6063,12 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: tomner
   inactive: true
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Tomsich
   cn: Philipp Tomsich
   email:
@@ -6104,12 +6149,13 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: uecker
   inactive_email:
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Ung
   cn: David Ung
   email:
@@ -6203,10 +6249,11 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: kugan
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Volkov
   cn: Artemiy Volkov
   email:
@@ -6285,7 +6332,6 @@ users:
   roles:
   - Maintainer: c++ runtime libs
   - WriteAfter
-  - DCO: [email protected]
   account: redi
   forgeid: redi
   inactive_email:
@@ -6293,6 +6339,8 @@ users:
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Walfridsson
   cn: Krister Walfridsson
   email:
@@ -6437,9 +6485,10 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: alexanderw
   inactive: true
+  DCO:
+  - [email protected]
 - sn: Wielaard
   cn: Mark Wielaard
   email:
@@ -6557,8 +6606,9 @@ users:
   roles:
   - Maintainer: nds32 port
   - WriteAfter
-  - DCO: [email protected]
   account: jasonwucj
+  DCO:
+  - [email protected]
 - sn: Wu
   cn: Le-Chun Wu
   email:
@@ -6801,9 +6851,10 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
-  - DCO: [email protected]
   account: pzheng
+  DCO:
+  - [email protected]
+  - [email protected]
 - sn: Zhong
   cn: Juzhe Zhong
   email:
@@ -6841,11 +6892,12 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
-  - DCO: [email protected]
   account: rzinsly
   aliases:
   - Raphael Moreira Zinsly
+  DCO:
+  - [email protected]
+  - [email protected]
 - sn: Zippel
   cn: Roman Zippel
   email:
diff --git a/contrib/add-write-after.py b/contrib/add-write-after.py
index 693bd8cd9536..c6c11bbcf5c8 100755
--- a/contrib/add-write-after.py
+++ b/contrib/add-write-after.py
@@ -107,11 +107,21 @@ def getuserdata():
         newuser['forgeid'] = forgeid
     print("If you are using a Developer Certificate of Origin (DCO)")
     print("you can add appropriate email addresses here")
+    dco = []
+    inactive_emails = []
     while (e := ask("DCO email (return to stop)", None, required=False)):
         if email_valid(e):
-            newuser['roles'].append({'DCO': e})
+            dco.append(e)
+            if e not in newuser['email']:
+                print(f"<{e}> not mentioned in the above list of emails.")
+                print("Adding it to inactive_emails list.")
+                inactive_emails.append(e)
         else:
             print ("That address does not look valid.  Ignored.")
+    if len(inactive_emails) > 0:
+        newuser['inactive_email'] = inactive_emails
+    if len(dco) > 0:
+        newuser['DCO'] = dco
     return newuser
 
 def main():
diff --git a/contrib/gen-MAINTAINERS.py b/contrib/gen-MAINTAINERS.py
index 124505d2890e..4fcc4dcfc852 100755
--- a/contrib/gen-MAINTAINERS.py
+++ b/contrib/gen-MAINTAINERS.py
@@ -211,6 +211,21 @@ def uni2alower(txt):
     return unidecode.unidecode(txt).lower()
 
 
+def paginate(data, widths):
+    """
+    Calculate the field widths for 'data', taking into account over-long
+    elements.
+    """
+    w = dict()
+    col = 0
+    overrun = 0
+    for field, width in widths:
+        width -= overrun
+        w[field] = max(width, 1)
+        overrun = max(len(data[field]) - width, 0)
+    return w
+
+
 def format_output(outfile, data):
     global active_only
     all_users = data['users']
@@ -229,7 +244,19 @@ def format_output(outfile, data):
             role = section['filter']['role']
             subclass = section['filter'].get('subclass')
             for u in all_users:
-                for r in filter(lambda x: role in x, u['roles']):
+                if role == 'DCO':
+                    for email in u.get('DCO', []):
+                        d = {
+                            'email': email,
+                            'account': u.get('account', '-'),
+                            'sn': u['sn'],
+                            'cn': u['cn'],
+                            'subsystem': None,
+                        }
+                        d['w'] = paginate(d, section['widths'])
+                        l.append(d)
+                    continue
+                for r in filter(lambda x: role in x, u.get('roles', [])):
                     if subclass:
                         sc = [
                             s
@@ -249,20 +276,11 @@ def format_output(outfile, data):
                         'cn': u['cn'],
                         'subsystem': r[role] if type(r) == dict else None,
                     }
-                    if role == 'DCO':
-                        d['email'] = r['DCO']
                     if role == 'WriteAfter' and type(r) == dict:
                         d['email'] = r['WriteAfter']
                     elif type(r) == dict and 'email' in r:
                         d['email'] = r['email']
-                    w = dict()
-                    col = 0
-                    overrun = 0
-                    for field, width in section['widths']:
-                        width -= overrun
-                        w[field] = max(width, 1)
-                        overrun = max(len(d[field]) - width, 0)
-                    d['w'] = w
+                    d['w'] = paginate(d, section['widths'])
                     l.append(d)
             kfn = itemgetter(*section['filter']['order'])
             for u in sorted(
diff --git a/contrib/maintainer_utils.py b/contrib/maintainer_utils.py
index 51a78ab72eec..8199fd588758 100755
--- a/contrib/maintainer_utils.py
+++ b/contrib/maintainer_utils.py
@@ -67,6 +67,14 @@ maintainer_schema = {
                             'format': 'email',
                         },
                     },
+                    'DCO': {
+                        'type': 'array',
+                        'items': {
+                            'type': 'string',
+                            'format': 'email',
+                        },
+                        "minItems": 1,
+                    },
                     'roles': {
                         'type': 'array',
                         'items': {
@@ -82,10 +90,6 @@ maintainer_schema = {
                                             'type': 'string',
                                             'format': 'email',
                                         },
-                                        'DCO': {
-                                            'type': 'string',
-                                            'format': 'email',
-                                        },
                                     },
                                     'additionalProperties': False,
                                 },
@@ -135,7 +139,11 @@ maintainer_schema = {
                     },
                 },
                 'additionalProperties': False,
-                'required': ['sn', 'cn', 'email', 'roles'],
+                'required': ['sn', 'cn', 'email'],
+                'anyOf': [
+                    {'required': ['roles']},
+                    {'required': ['DCO']},
+                ],
             },
         },
         'subsystems': {
@@ -236,6 +244,15 @@ def _check_schema(data):
     return
 
 
+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.
+    emails = set(user['email'] + user.get('inactive_email', []))
+    for dco in user['DCO']:
+        if dco not in emails:
+            _error(f"User: {user['cn']} DCO {dco} not listed in other emails")
+
+
 def validate(data):
     """Check the data against the schema and our own consistency checks"""
     _check_schema(data)
@@ -246,12 +263,17 @@ def validate(data):
     # subsystems list; Maintainer entires must also have a class entry, though
     # that is optional for Reviewers.
     for u in data['users']:
+        if 'DCO' in u:
+            _check_dco(u)
+        # The schema ensures that at least one of 'DCO' or 'roles'
+        # exists, so if roles is missing, we're done.
+        if 'roles' not in u:
+            continue
         # Users with the 'BZ' role should not have any other roles; we
         # can quickly skip the additional checks if that is the case.
         if len(u['roles']) == 1 and u['roles'][0] == 'BZ':
             continue
         seen_writeafter = False
-        only_dco = True
         for r in u['roles']:
             if isinstance(r, str):
                 if r == 'BZ':
@@ -260,14 +282,10 @@ def validate(data):
                     )
                 if r == 'WriteAfter':
                     seen_writeafter = True
-                only_dco = False
                 continue
             if 'WriteAfter' in r:
                 seen_writeafter = True
             need_class = True
-            if 'DCO' in r:
-                continue
-            only_dco = False
             n = r.get('Maintainer')
             if not n:
                 need_class = False
@@ -283,7 +301,7 @@ def validate(data):
                     _error(f"No subsystem entry for '{n}'.")
                 else:
                     _error(f"Multiple subsystem entries for '{n}'.")
-        if not seen_writeafter and not only_dco:
+        if not seen_writeafter:
             _error(f"User '{u['cn']}' lacks WriteAfter role.")
     if error_count:
         sys.exit(1)

Reply via email to