|
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): |
@@ -543,31 +545,75 @@ def process_component(component, ctx): |
543 | 545 | def generate_reports(ctx): |
544 | 546 | """ |
545 | 547 | Generate and print all summary reports. |
546 | | - |
| 548 | + Also saves the report data to commonly-needed-report.json. |
| 549 | +
|
547 | 550 | Args: |
548 | 551 | ctx: RebuildContext with statistics and component data |
549 | 552 | """ |
| 553 | + # Build structured data for JSON export |
| 554 | + report_data = { |
| 555 | + 'most_commonly_needed': [], |
| 556 | + 'most_commonly_last_blocking': [], |
| 557 | + 'most_commonly_last_blocking_combinations': [], |
| 558 | + 'dependency_loops': [] |
| 559 | + } |
| 560 | + |
550 | 561 | log('\nThe 50 most commonly needed components are:') |
551 | 562 | for component, count in ctx.blocker_counter['general'].most_common(50): |
552 | 563 | status_info = get_component_status_info( |
553 | 564 | component, ctx.missing_packages, ctx.components, |
554 | 565 | ctx.unresolvable_components, ctx.prerel_abi_blocked_components |
555 | 566 | ) |
556 | 567 | log(f'{count:>5} {component:<35} {status_info}') |
557 | | - |
| 568 | + |
| 569 | + entry = { |
| 570 | + 'component': component, |
| 571 | + 'count': count, |
| 572 | + } |
| 573 | + if component in ctx.unresolvable_components: |
| 574 | + entry['unresolvable'] = True |
| 575 | + if component in ctx.prerel_abi_blocked_components: |
| 576 | + entry['prerel_abi_blocked'] = True |
| 577 | + if component in ctx.missing_packages: |
| 578 | + entry['blocked_by'] = sorted(ctx.missing_packages[component]) |
| 579 | + report_data['most_commonly_needed'].append(entry) |
| 580 | + |
558 | 581 | log('\nThe 20 most commonly last-blocking components are:') |
559 | 582 | for component, count in ctx.blocker_counter['single'].most_common(20): |
560 | 583 | status_info = get_component_status_info( |
561 | 584 | component, ctx.missing_packages, ctx.components, |
562 | 585 | ctx.unresolvable_components, ctx.prerel_abi_blocked_components |
563 | 586 | ) |
564 | 587 | log(f'{count:>5} {component:<35} {status_info}') |
565 | | - |
| 588 | + |
| 589 | + entry = { |
| 590 | + 'component': component, |
| 591 | + 'count': count, |
| 592 | + } |
| 593 | + if component in ctx.unresolvable_components: |
| 594 | + entry['unresolvable'] = True |
| 595 | + if component in ctx.prerel_abi_blocked_components: |
| 596 | + entry['prerel_abi_blocked'] = True |
| 597 | + if component in ctx.missing_packages: |
| 598 | + entry['blocked_by'] = sorted(ctx.missing_packages[component]) |
| 599 | + report_data['most_commonly_last_blocking'].append(entry) |
| 600 | + |
566 | 601 | log('\nThe 20 most commonly last-blocking small combinations of components are:') |
567 | 602 | for components_tuple, count in ctx.blocker_counter['combinations'].most_common(20): |
568 | 603 | log(f'{count:>5} {", ".join(components_tuple)}') |
569 | | - |
570 | | - report_blocking_components(ctx.loop_detector) |
| 604 | + |
| 605 | + report_data['most_commonly_last_blocking_combinations'].append({ |
| 606 | + 'components': list(components_tuple), |
| 607 | + 'count': count |
| 608 | + }) |
| 609 | + |
| 610 | + loops = report_blocking_components(ctx.loop_detector) |
| 611 | + for loop in loops: |
| 612 | + report_data['dependency_loops'].append(list(loop)) |
| 613 | + |
| 614 | + with open('commonly-needed-report.json', 'w') as f: |
| 615 | + json.dump(report_data, f, indent=2) |
| 616 | + log('\nReport saved to commonly-needed-report.json') |
571 | 617 |
|
572 | 618 |
|
573 | 619 | def main(): |
|
0 commit comments