Auto-fix IWYU violations by removing offending lines. Args: violations: {relative_file_path: [removal_strings]} where each removal string contains '// lines N-N' with the line number. Returns: 0 on success, 1 on any error.
(violations: dict[str, list[str]])
| 650 | |
| 651 | |
| 652 | def fix_iwyu_violations(violations: dict[str, list[str]]) -> int: |
| 653 | """Auto-fix IWYU violations by removing offending lines. |
| 654 | |
| 655 | Args: |
| 656 | violations: {relative_file_path: [removal_strings]} where each |
| 657 | removal string contains '// lines N-N' with the line number. |
| 658 | |
| 659 | Returns: |
| 660 | 0 on success, 1 on any error. |
| 661 | """ |
| 662 | if not violations: |
| 663 | print("✅ No violations to fix") |
| 664 | return 0 |
| 665 | |
| 666 | total_fixes = 0 |
| 667 | total_files = 0 |
| 668 | |
| 669 | for rel_path, removals in sorted(violations.items()): |
| 670 | file_path = _PROJECT_ROOT / rel_path |
| 671 | if not file_path.exists(): |
| 672 | print(f" ⚠️ {rel_path}: file not found, skipping") |
| 673 | continue |
| 674 | |
| 675 | # Collect line numbers to remove |
| 676 | lines_to_remove: set[int] = set() |
| 677 | for removal in removals: |
| 678 | line_num = _extract_line_number(removal) |
| 679 | if line_num is not None: |
| 680 | lines_to_remove.add(line_num) |
| 681 | |
| 682 | if not lines_to_remove: |
| 683 | continue |
| 684 | |
| 685 | try: |
| 686 | original = file_path.read_text(encoding="utf-8", errors="replace") |
| 687 | original_lines = original.splitlines(keepends=True) |
| 688 | new_lines: list[str] = [] |
| 689 | removed_count = 0 |
| 690 | |
| 691 | for i, line in enumerate(original_lines, start=1): |
| 692 | if i in lines_to_remove: |
| 693 | removed_count += 1 |
| 694 | # Also skip blank line immediately after removal if it |
| 695 | # would leave two consecutive blank lines. |
| 696 | else: |
| 697 | new_lines.append(line) |
| 698 | |
| 699 | # Clean up: collapse runs of 3+ blank lines into 2 |
| 700 | cleaned: list[str] = [] |
| 701 | blank_run = 0 |
| 702 | for line in new_lines: |
| 703 | if line.strip() == "": |
| 704 | blank_run += 1 |
| 705 | if blank_run <= 2: |
| 706 | cleaned.append(line) |
| 707 | else: |
| 708 | blank_run = 0 |
| 709 | cleaned.append(line) |