@@ -260,7 +260,7 @@ def manifest_at_rev(sha):
260260
261261 return (old_manifest , new_manifest )
262262
263- def _get_merge_status (len_a , len_r , len_pr , impostor_shas ):
263+ def _get_merge_status (len_a , len_r , len_pr , len_meta , impostor_shas , unreachables ):
264264 strs = []
265265 def plural (count ):
266266 return 's' if count > 1 else ''
@@ -271,13 +271,17 @@ def plural(count):
271271 strs .append (f'{ len_r } removed project{ plural (len_r )} ' )
272272 if len_pr :
273273 strs .append (f'{ len_pr } project{ plural (len_pr )} with PR revision' )
274+ if len_meta :
275+ strs .append (f'{ len_meta } project{ plural (len_meta )} with metadata changes' )
274276 if impostor_shas :
275277 strs .append (f'{ impostor_shas } impostor SHA{ plural (impostor_shas )} ' )
278+ if unreachables :
279+ strs .append (f'{ unreachables } unreachable repo{ plural (unreachables )} ' )
276280
277281 if not len (strs ):
278282 return False , '\u2705 **All manifest checks OK**'
279283
280- n = '\u274c **DNM label due to: '
284+ n = '\U000026D4 **DNM label due to: '
281285 for i , s in enumerate (strs ):
282286 if i == (len (strs ) - 1 ):
283287 _s = f'and { s } ' if len (strs ) > 1 else s
@@ -445,6 +449,8 @@ def main():
445449 log (f'projs_names: { str (projs_names )} ' )
446450
447451 impostor_shas = 0
452+ unreachables = 0
453+ files = dict ()
448454 # Link main PR to project PRs
449455 strs = list ()
450456 if message :
@@ -462,6 +468,8 @@ def main():
462468 new_rev = None if p in rprojs else p [1 ]
463469 or_note = ' (Added)' if not old_rev else ''
464470 nr_note = ' (Removed)' if not new_rev else ''
471+ name_note = ' \U0001F195 ' if not old_rev else ' \U0000274c ' if \
472+ not new_rev else ''
465473 url = manifest .get_projects ([p [0 ]])[0 ].url
466474 re_url = re .compile (r'https://github\.com/'
467475 '([A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+)/?' )
@@ -470,15 +478,18 @@ def main():
470478 except (GithubException , TypeError ) as error :
471479 log (error )
472480 log (f"Can't get repo for { p [0 ]} ; output will be limited" )
473- strs .append (f'| { p [0 ]} | { old_rev } { or_note } | { new_rev } { nr_note } | N/A |' )
481+ strs .append (f'| { p [0 ]} { name_note } | { old_rev } { or_note } | { new_rev } { nr_note } | N/A |' )
482+ unreachables += 1
474483 continue
475484
476- line = f'| { p [0 ]} | { fmt_rev (repo , old_rev )} { or_note } '
485+ line = f'| { p [0 ]} { name_note } | { fmt_rev (repo , old_rev )} { or_note } '
477486 if p in pr_projs :
478487 pr = repo .get_pull (int (re_rev .match (new_rev )[1 ]))
479488 line += f'| { pr .html_url } { nr_note } '
480489 line += f'| [{ repo .full_name } #{ pr .number } /files]' + \
481490 f'({ pr .html_url } /files) |'
491+ # Store files changed
492+ files [p [0 ]] = [f for f in pr .get_files ()]
482493 else :
483494 if check_impostor and new_rev and is_impostor (repo , new_rev ):
484495 impostor_shas += 1
@@ -489,14 +500,73 @@ def main():
489500 line += f'| [{ repo .full_name } @{ shorten_rev (old_rev )} ..' + \
490501 f'{ shorten_rev (new_rev )} ]' + \
491502 f'({ repo .html_url } /compare/{ old_rev } ..{ new_rev } ) |'
503+ # Store files changed
504+ try :
505+ c = repo .compare (old_rev , new_rev )
506+ files [p [0 ]] = [f for f in c .files ]
507+ except GithubException as e :
508+ log (e )
509+ log (f"Can't get files changed for { p [0 ]} " )
492510 else :
493511 line += '| N/A |'
494512
495513 strs .append (line )
496514
515+ def _hashable (o ):
516+ if isinstance (o , list ):
517+ return frozenset (o )
518+ return o
519+
520+ def _module_changed (p ):
521+ if p .name in files :
522+ for f in files [p .name ]:
523+ if ('zephyr/module.yml' in f .filename or
524+ 'zephyr/module.yaml' in f .filename ):
525+ return True
526+ return False
527+
528+ # Check additional metadata
529+ meta_op = set ((p .name , p .url , _hashable (p .submodules ),
530+ _hashable (p .west_commands ), False ) for p in ops )
531+ meta_np = set ((p .name , p .url , _hashable (p .submodules ),
532+ _hashable (p .west_commands ), _module_changed (p )) for p in nps )
533+
534+ log ('Metadata sets' )
535+ (_ , meta_rprojs , meta_uprojs , meta_aprojs ) = _get_sets (meta_op , meta_np )
536+ meta_projs = meta_uprojs | meta_aprojs
537+
538+ def _cmp_old_new (p , index , force_change = False ):
539+ old = None if p in meta_aprojs else next (filter (lambda _p : _p [0 ] == p [0 ], meta_op ))[index ]
540+ new = next (filter (lambda _p : _p [0 ] == p [0 ], meta_np ))[index ]
541+ log (f'name: { p [0 ]} index: { index } old: { old } new: { new } ' )
542+ # Special handling for an added project
543+ if old is None and not new :
544+ return ''
545+ # Select which symbol to show
546+ if not old and new :
547+ return '\U0001F195 ' if not force_change else '\u270f ' # added
548+ elif not new and old :
549+ return '\u274c ' # removed
550+ elif new != old :
551+ return '\u270f ' # modified
552+ else :
553+ return ''
554+
555+ if len (meta_uprojs ):
556+ strs .append ('\n \n Additional metadata changed:\n ' )
557+ strs .append ('| Name | URL | Submodules | West cmds | `module.yml` | ' )
558+ strs .append ('| ---- | --- | ---------- | --------- | ------------ | ' )
559+ for p in sorted (meta_uprojs , key = lambda _p : _p [0 ]):
560+ url = _cmp_old_new (p , 1 )
561+ subms = _cmp_old_new (p , 2 )
562+ wcmds = _cmp_old_new (p , 3 )
563+ mys = _cmp_old_new (p , 4 , True )
564+ line = f'| { p [0 ]} | { url } | { subms } | { wcmds } | { mys } |'
565+ strs .append (line )
566+
497567 # Add a note about the merge status of the manifest PR
498568 dnm , status_note = _get_merge_status (len (aprojs ), len (rprojs ), len (pr_projs ),
499- impostor_shas )
569+ len ( meta_uprojs ), impostor_shas , unreachables )
500570 status_note = f'\n \n { status_note } '
501571
502572 message = '\n ' .join (strs ) + status_note + NOTE
0 commit comments