@@ -260,7 +260,7 @@ def manifest_at_rev(sha):
260
260
261
261
return (old_manifest , new_manifest )
262
262
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 ):
264
264
strs = []
265
265
def plural (count ):
266
266
return 's' if count > 1 else ''
@@ -271,13 +271,17 @@ def plural(count):
271
271
strs .append (f'{ len_r } removed project{ plural (len_r )} ' )
272
272
if len_pr :
273
273
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' )
274
276
if impostor_shas :
275
277
strs .append (f'{ impostor_shas } impostor SHA{ plural (impostor_shas )} ' )
278
+ if unreachables :
279
+ strs .append (f'{ unreachables } unreachable repo{ plural (unreachables )} ' )
276
280
277
281
if not len (strs ):
278
282
return False , '\u2705 **All manifest checks OK**'
279
283
280
- n = '\u274c **DNM label due to: '
284
+ n = '\U000026D4 **DNM label due to: '
281
285
for i , s in enumerate (strs ):
282
286
if i == (len (strs ) - 1 ):
283
287
_s = f'and { s } ' if len (strs ) > 1 else s
@@ -445,6 +449,8 @@ def main():
445
449
log (f'projs_names: { str (projs_names )} ' )
446
450
447
451
impostor_shas = 0
452
+ unreachables = 0
453
+ files = dict ()
448
454
# Link main PR to project PRs
449
455
strs = list ()
450
456
if message :
@@ -462,6 +468,8 @@ def main():
462
468
new_rev = None if p in rprojs else p [1 ]
463
469
or_note = ' (Added)' if not old_rev else ''
464
470
nr_note = ' (Removed)' if not new_rev else ''
471
+ name_note = ' \U0001F195 ' if not old_rev else ' \U0000274c ' if \
472
+ not new_rev else ''
465
473
url = manifest .get_projects ([p [0 ]])[0 ].url
466
474
re_url = re .compile (r'https://github\.com/'
467
475
'([A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+)/?' )
@@ -470,15 +478,18 @@ def main():
470
478
except (GithubException , TypeError ) as error :
471
479
log (error )
472
480
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
474
483
continue
475
484
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 } '
477
486
if p in pr_projs :
478
487
pr = repo .get_pull (int (re_rev .match (new_rev )[1 ]))
479
488
line += f'| { pr .html_url } { nr_note } '
480
489
line += f'| [{ repo .full_name } #{ pr .number } /files]' + \
481
490
f'({ pr .html_url } /files) |'
491
+ # Store files changed
492
+ files [p [0 ]] = [f for f in pr .get_files ()]
482
493
else :
483
494
if check_impostor and new_rev and is_impostor (repo , new_rev ):
484
495
impostor_shas += 1
@@ -489,14 +500,73 @@ def main():
489
500
line += f'| [{ repo .full_name } @{ shorten_rev (old_rev )} ..' + \
490
501
f'{ shorten_rev (new_rev )} ]' + \
491
502
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 ]} " )
492
510
else :
493
511
line += '| N/A |'
494
512
495
513
strs .append (line )
496
514
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
+
497
567
# Add a note about the merge status of the manifest PR
498
568
dnm , status_note = _get_merge_status (len (aprojs ), len (rprojs ), len (pr_projs ),
499
- impostor_shas )
569
+ len ( meta_uprojs ), impostor_shas , unreachables )
500
570
status_note = f'\n \n { status_note } '
501
571
502
572
message = '\n ' .join (strs ) + status_note + NOTE
0 commit comments