From: Richard Earnshaw <[email protected]>

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.
---
 MAINTAINERS.yml             | 189 +++++++++++++++++++++++-------------
 contrib/add-write-after.py  |  12 ++-
 contrib/gen-MAINTAINERS.py  |  40 +++++---
 contrib/maintainer_utils.py |  40 +++++---
 4 files changed, 189 insertions(+), 92 deletions(-)

diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml
index 5d44576d7579b..64a4d1b65e293 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:
@@ -1760,8 +1769,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: kael
+  DCO:
+  - [email protected]
 - sn: Franke
   cn: Daniel Franke
   email:
@@ -1915,11 +1925,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:
@@ -2064,10 +2075,11 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: eikansh
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Gupta
   cn: Vineet Gupta
   email:
@@ -2086,7 +2098,6 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: naveenh
   aliases:
   - Naveen Gowda
@@ -2096,6 +2107,8 @@ users:
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Hagog
   cn: Mostafa Hagog
   email:
@@ -2310,11 +2323,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:
@@ -2727,8 +2741,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: mjires
+  DCO:
+  - [email protected]
 - sn: Johnson
   cn: Janis Johnson
   email:
@@ -3075,10 +3090,11 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: mkretz
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Krupp
   cn: Louis Krupp
   email:
@@ -3095,11 +3111,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:
@@ -3202,9 +3219,10 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: tlange
   inactive: true
+  DCO:
+  - [email protected]
 - sn: Langton
   cn: Asher Langton
   email:
@@ -3266,11 +3284,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
@@ -3279,6 +3292,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:
@@ -3335,8 +3354,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: garthlei
+  DCO:
+  - [email protected]
 - sn: Lemke
   cn: James Lemke
   email:
@@ -3410,8 +3430,8 @@ users:
   cn: Jim Lin
   email:
   - [email protected]
-  roles:
-  - DCO: [email protected]
+  DCO:
+  - [email protected]
 - sn: Lin
   cn: Kewen Lin
   email:
@@ -3443,8 +3463,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: marxin
+  DCO:
+  - [email protected]
 - sn: Liu
   cn: Hao Liu
   email:
@@ -3589,7 +3610,6 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: hjl
   inactive_email:
   - [email protected]
@@ -3597,6 +3617,8 @@ users:
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Luo
   cn: Longjun Luo
   email:
@@ -3604,8 +3626,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: anatasluo
+  DCO:
+  - [email protected]
 - sn: Luo
   cn: Xiong Hu Luo
   email:
@@ -3664,8 +3687,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: yuao
+  DCO:
+  - [email protected]
 - sn: Machado
   cn: Luis Machado
   email:
@@ -3739,10 +3763,11 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: matmal01
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Maltsev
   cn: Mikhail Maltsev
   email:
@@ -3765,9 +3790,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:
@@ -4033,12 +4059,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:
@@ -4179,10 +4206,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:
@@ -4196,9 +4224,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:
@@ -4260,11 +4288,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:
@@ -4565,8 +4594,9 @@ users:
   - Maintainer: Rust
   - Maintainer: libgrust
   - WriteAfter
-  - DCO: [email protected]
   account: pep
+  DCO:
+  - [email protected]
 - sn: Pavenis
   cn: Andris Pavenis
   email:
@@ -4629,10 +4659,11 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: mikpe
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Pfau
   cn: Johannes Pfau
   email:
@@ -4682,8 +4713,6 @@ users:
     email: [email protected]
   - Reviewer: aarch64 port
   - WriteAfter: [email protected]
-  - DCO: [email protected]
-  - DCO: [email protected]
   account: pinskia
   forgeid: pinskia
   inactive_email:
@@ -4694,6 +4723,9 @@ users:
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
+  - [email protected]
 - sn: Pitre
   cn: Nicolas Pitre
   email:
@@ -4778,13 +4810,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:
@@ -4875,7 +4908,6 @@ users:
   roles:
   - Maintainer: arm port
   - WriteAfter
-  - DCO: [email protected]
   account: ramana
   inactive_email:
   - [email protected]
@@ -4884,17 +4916,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:
@@ -4902,9 +4937,10 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: rshraj45035
   inactive: true
+  DCO:
+  - [email protected]
 - sn: Raman
   cn: Easwaran Raman
   email:
@@ -4998,8 +5034,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: egas
+  DCO:
+  - [email protected]
 - sn: Richards
   cn: Alfie Richards
   email:
@@ -5243,12 +5280,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:
@@ -5306,14 +5344,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:
@@ -5484,8 +5522,9 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: nshead
+  DCO:
+  - [email protected]
 - sn: Shen
   cn: Tim Shen
   email:
@@ -5528,12 +5567,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:
@@ -5587,11 +5627,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:
@@ -5630,10 +5671,11 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: maskray
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Stallman
   cn: Richard Stallman
   email:
@@ -5975,11 +6017,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:
@@ -6013,11 +6056,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:
@@ -6098,12 +6142,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:
@@ -6197,10 +6242,11 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: kugan
   inactive_email:
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Volkov
   cn: Artemiy Volkov
   email:
@@ -6279,7 +6325,6 @@ users:
   roles:
   - Maintainer: c++ runtime libs
   - WriteAfter
-  - DCO: [email protected]
   account: redi
   forgeid: redi
   inactive_email:
@@ -6287,6 +6332,8 @@ users:
   - [email protected]
   - [email protected]
   - [email protected]
+  DCO:
+  - [email protected]
 - sn: Walfridsson
   cn: Krister Walfridsson
   email:
@@ -6431,9 +6478,10 @@ users:
   - [email protected]
   roles:
   - WriteAfter
-  - DCO: [email protected]
   account: alexanderw
   inactive: true
+  DCO:
+  - [email protected]
 - sn: Wielaard
   cn: Mark Wielaard
   email:
@@ -6551,8 +6599,9 @@ users:
   roles:
   - Maintainer: nds32 port
   - WriteAfter
-  - DCO: [email protected]
   account: jasonwucj
+  DCO:
+  - [email protected]
 - sn: Wu
   cn: Le-Chun Wu
   email:
@@ -6795,9 +6844,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:
@@ -6835,11 +6885,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 693bd8cd95362..c6c11bbcf5c87 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 124505d2890e2..4fcc4dcfc8527 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 51a78ab72eec7..8199fd588758f 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)
-- 
2.54.0

Reply via email to