|
1 | 1 | import collections |
2 | 2 | from dataclasses import dataclass, field |
3 | 3 | import functools |
| 4 | +import json |
4 | 5 | import os |
5 | 6 | import sys |
6 | 7 |
|
@@ -291,6 +292,7 @@ def report_blocking_components(loop_detector): |
291 | 292 | log('\nDetected dependency loops:') |
292 | 293 | for loop in sorted(loops, key=lambda t: -len(t)): |
293 | 294 | log(' • ' + ' → '.join(loop)) |
| 295 | + return loops |
294 | 296 |
|
295 | 297 |
|
296 | 298 | def get_component_status_info(component, missing_packages, components, unresolvable_components, prerel_abi_blocked_components=None): |
@@ -540,34 +542,72 @@ def process_component(component, ctx): |
540 | 542 | check_bcond_builds(component, number_of_resolved, ctx) |
541 | 543 |
|
542 | 544 |
|
| 545 | +def assemble_component_info(component, count, ctx): |
| 546 | + entry = { |
| 547 | + 'component': component, |
| 548 | + 'count': count, |
| 549 | + } |
| 550 | + if component in ctx.unresolvable_components: |
| 551 | + entry['unresolvable'] = True |
| 552 | + if component in ctx.prerel_abi_blocked_components: |
| 553 | + entry['prerel_abi_blocked'] = True |
| 554 | + if component in ctx.missing_packages: |
| 555 | + entry['blocked_by'] = sorted(ctx.missing_packages[component]) |
| 556 | + return entry |
| 557 | + |
| 558 | + |
543 | 559 | def generate_reports(ctx): |
544 | 560 | """ |
545 | 561 | Generate and print all summary reports. |
546 | | - |
| 562 | + Also saves the report data to commonly-needed-report.json. |
| 563 | +
|
547 | 564 | Args: |
548 | 565 | ctx: RebuildContext with statistics and component data |
549 | 566 | """ |
| 567 | + report_data = { |
| 568 | + 'most_commonly_needed': [], |
| 569 | + 'most_commonly_last_blocking': [], |
| 570 | + 'most_commonly_last_blocking_combinations': [], |
| 571 | + 'dependency_loops': [] |
| 572 | + } |
| 573 | + |
550 | 574 | log('\nThe 50 most commonly needed components are:') |
551 | 575 | for component, count in ctx.blocker_counter['general'].most_common(50): |
552 | 576 | status_info = get_component_status_info( |
553 | 577 | component, ctx.missing_packages, ctx.components, |
554 | 578 | ctx.unresolvable_components, ctx.prerel_abi_blocked_components |
555 | 579 | ) |
556 | 580 | log(f'{count:>5} {component:<35} {status_info}') |
557 | | - |
| 581 | + |
| 582 | + entry = assemble_component_info(component, count, ctx) |
| 583 | + report_data['most_commonly_needed'].append(entry) |
| 584 | + |
558 | 585 | log('\nThe 20 most commonly last-blocking components are:') |
559 | 586 | for component, count in ctx.blocker_counter['single'].most_common(20): |
560 | 587 | status_info = get_component_status_info( |
561 | 588 | component, ctx.missing_packages, ctx.components, |
562 | 589 | ctx.unresolvable_components, ctx.prerel_abi_blocked_components |
563 | 590 | ) |
564 | 591 | log(f'{count:>5} {component:<35} {status_info}') |
565 | | - |
| 592 | + |
| 593 | + entry = assemble_component_info(component, count, ctx) |
| 594 | + report_data['most_commonly_last_blocking'].append(entry) |
| 595 | + |
566 | 596 | log('\nThe 20 most commonly last-blocking small combinations of components are:') |
567 | 597 | for components_tuple, count in ctx.blocker_counter['combinations'].most_common(20): |
568 | 598 | log(f'{count:>5} {", ".join(components_tuple)}') |
569 | | - |
570 | | - report_blocking_components(ctx.loop_detector) |
| 599 | + |
| 600 | + report_data['most_commonly_last_blocking_combinations'].append({ |
| 601 | + 'components': list(components_tuple), |
| 602 | + 'count': count |
| 603 | + }) |
| 604 | + |
| 605 | + loops = report_blocking_components(ctx.loop_detector) |
| 606 | + report_data['dependency_loops'] = [list(loop) for loop in loops] |
| 607 | + |
| 608 | + with open('commonly-needed-report.json', 'w') as f: |
| 609 | + json.dump(report_data, f, indent=2) |
| 610 | + log('\nReport saved to commonly-needed-report.json') |
571 | 611 |
|
572 | 612 |
|
573 | 613 | def main(): |
|
0 commit comments