@@ -139,27 +139,35 @@ def check_governance(bots: list[Bot], root: Path, owner: str) -> None:
139139 disqualified_names = {entry ["bot" ] for entry in banned .get ("disqualifiedBots" , [])}
140140 if owner in banned_accounts :
141141 raise ValidationError (f"owner `{ owner } ` is banned from submissions" )
142- known_names : dict [str , str ] = {name : record ["ownerId" ] for record in owners .get ("owners" , []) for name in record .get ("bots" , [])}
143142 catalog_entries = read_json (root / "bots" / "index.json" ).get ("bots" , []) if (root / "bots" / "index.json" ).exists () else []
144143 catalog_by_name = {entry ["name" ]: entry for entry in catalog_entries if entry .get ("status" ) == "active" }
144+ submitted_bots = [
145+ bot
146+ for bot in bots
147+ if (previous := catalog_by_name .get (bot .name )) is None
148+ or previous .get ("version" ) != bot .config ["version" ]
149+ or previous .get ("sourceHash" ) != bot .source_hash
150+ ]
151+ owner_by_bot = {name : record for record in owners .get ("owners" , []) for name in record .get ("bots" , [])}
145152 seen_skeletons : dict [str , str ] = {}
146- for bot in bots :
153+ for bot in submitted_bots :
147154 if bot .name in disqualified_names :
148155 raise ValidationError (f"bot `{ bot .name } ` is disqualified" )
149156 bot_skeleton = skeleton (bot .name )
150157 previous = seen_skeletons .get (bot_skeleton )
151158 if previous is not None and previous != bot .name :
152159 raise ValidationError (f"bot `{ bot .name } ` is confusable with `{ previous } `" )
153160 seen_skeletons [bot_skeleton ] = bot .name
154- existing_owner = known_names .get (bot .name )
155- if existing_owner is not None and existing_owner != owner :
156- raise ValidationError (f"bot `{ bot .name } ` belongs to owner `{ existing_owner } `" )
161+ existing_owner = owner_by_bot .get (bot .name )
162+ if existing_owner is not None and owner not in existing_owner . get ( "accounts" , []) :
163+ raise ValidationError (f"bot `{ bot .name } ` belongs to owner `{ existing_owner [ 'ownerId' ] } `" )
157164 previous = catalog_by_name .get (bot .name )
158165 if previous is not None and previous .get ("version" ) == bot .config ["version" ] and previous .get ("sourceHash" ) != bot .source_hash :
159166 raise ValidationError (f"bot `{ bot .name } ` changed source without increasing its version" )
160167 active_by_owner : dict [str , int ] = {}
161- for bot in bots :
162- active_by_owner [known_names .get (bot .name , owner )] = active_by_owner .get (known_names .get (bot .name , owner ), 0 ) + 1
168+ for bot in submitted_bots :
169+ if bot .name not in owner_by_bot :
170+ active_by_owner [owner ] = active_by_owner .get (owner , 0 ) + 1
163171 if active_by_owner .get (owner , 0 ) > 5 :
164172 raise ValidationError (f"owner `{ owner } ` exceeds the five active bot slot limit" )
165173
@@ -172,10 +180,28 @@ def generated_catalog(bots: list[Bot], root: Path, owner: str) -> tuple[dict[str
172180 for bot in bots :
173181 bot_owner = owner_by_bot .get (bot .name , owner )
174182 records .setdefault (bot_owner , []).append (bot .name )
175- owners = {record ["ownerId" ]: set (record .get ("bots" , [])) for record in existing_owners .get ("owners" , [])}
183+ owners = {
184+ record ["ownerId" ]: {
185+ "accounts" : record .get ("accounts" , []),
186+ "bots" : set (record .get ("bots" , [])),
187+ }
188+ for record in existing_owners .get ("owners" , [])
189+ }
176190 for owner_id , names in records .items ():
177- owners .setdefault (owner_id , set ()).update (names )
178- owner_data = {"schemaVersion" : 1 , "owners" : [{"ownerId" : owner_id , "accounts" : [owner_id ], "bots" : sorted (names ), "activeSlots" : len (names )} for owner_id , names in sorted (owners .items ())]}
191+ owner_record = owners .setdefault (owner_id , {"accounts" : [owner_id ], "bots" : set ()})
192+ owner_record ["bots" ].update (names )
193+ owner_data = {
194+ "schemaVersion" : 1 ,
195+ "owners" : [
196+ {
197+ "ownerId" : owner_id ,
198+ "accounts" : owner_record ["accounts" ],
199+ "bots" : sorted (owner_record ["bots" ]),
200+ "activeSlots" : len (owner_record ["bots" ]),
201+ }
202+ for owner_id , owner_record in sorted (owners .items ())
203+ ],
204+ }
179205 today = datetime .now (UTC ).date ().isoformat ()
180206 current_by_name = {bot .name : bot for bot in bots }
181207 history = []
0 commit comments