|
| 1 | +# Auto-Sort Brewfiles: Design Document |
| 2 | + |
| 3 | +## Summary |
| 4 | + |
| 5 | +Add an optional configuration to automatically sort Brewfile formulas alphabetically when the user enables auto-sorting. |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Motivation |
| 10 | + |
| 11 | +**Problem:** Unsorted Brewfiles can make it hard to: |
| 12 | +- Spot missing dependencies (no obvious gaps) |
| 13 | +- See where a new formula should be added |
| 14 | +- Quickly scan for duplicate formulas |
| 15 | + |
| 16 | +**Reference:** Telemetry entry Q000001 raised this question. |
| 17 | + |
| 18 | +--- |
| 19 | + |
| 20 | +## Design Options |
| 21 | + |
| 22 | +### Option A: Opt-in Auto-Sort (Recommended) |
| 23 | + |
| 24 | +**Configuration:** |
| 25 | +```toml |
| 26 | +[brewfiles] |
| 27 | +sort = "on" # or "off" (default) |
| 28 | +``` |
| 29 | + |
| 30 | +**Behavior:** |
| 31 | +- When enabled, `haven apply` re-sorts formulas after `brew bundle dump` |
| 32 | +- Formulas are sorted by their name (short name without version prefix) |
| 33 | +- Comments and anchors are preserved in place |
| 34 | + |
| 35 | +**Pros:** |
| 36 | +- Simple, predictable behavior |
| 37 | +- Easy to opt-out per-module |
| 38 | +- Minimal complexity |
| 39 | + |
| 40 | +**Cons:** |
| 41 | +- Requires explicit opt-in |
| 42 | +- May need to migrate existing Brewfiles |
| 43 | + |
| 44 | +### Option B: Smart Re-Sort |
| 45 | + |
| 46 | +**Behavior:** |
| 47 | +- Same as Option A, but preserves formatting (tabs vs spaces, line length) |
| 48 | +- Anchors (`^anchor`) maintain position but are noted in comments |
| 49 | +- Comments referencing specific formulas move with them |
| 50 | + |
| 51 | +**Pros:** |
| 52 | +- Respects user's style preferences |
| 53 | +- Anchors remain valid after re-sort |
| 54 | + |
| 55 | +**Cons:** |
| 56 | +- More complex implementation |
| 57 | +- Edge cases around comment preservation |
| 58 | + |
| 59 | +### Option C: Hybrid (Per-Module) |
| 60 | + |
| 61 | +**Configuration:** |
| 62 | +```toml |
| 63 | +[[module]] |
| 64 | +name = "packages" |
| 65 | +sort = "on" |
| 66 | + |
| 67 | +[[module]] |
| 68 | +name = "my-custom-brew" |
| 69 | +sort = "off" |
| 70 | +``` |
| 71 | + |
| 72 | +**Pros:** |
| 73 | +- Fine-grained control |
| 74 | +- Can mix sorted and unsorted Brewfiles |
| 75 | + |
| 76 | +**Cons:** |
| 77 | +- More configuration options |
| 78 | +- Users might not need this level of control |
| 79 | + |
| 80 | +--- |
| 81 | + |
| 82 | +## Recommended Implementation |
| 83 | + |
| 84 | +**Start with Option A** — simple opt-in sorting. |
| 85 | + |
| 86 | +**Phase 1:** Basic sort after `brew bundle dump` |
| 87 | +**Phase 2:** Add comment preservation (if feasible) |
| 88 | +**Phase 3:** Per-module control (if requested) |
| 89 | + |
| 90 | +--- |
| 91 | + |
| 92 | +## Implementation Notes |
| 93 | + |
| 94 | +### Where to integrate |
| 95 | + |
| 96 | +The sorting should happen in `brew::dump()` in `src/lib.rs`, after the `brew bundle dump` command: |
| 97 | + |
| 98 | +```rust |
| 99 | +pub fn dump(path: &Path, output: &str) -> Result<()> { |
| 100 | + // 1. Write to Brewfile.tmp |
| 101 | + // 2. Run "brew bundle dump --file=Brewfile" |
| 102 | + // 3. If sort is enabled: |
| 103 | + // - Read Brewfile.tmp |
| 104 | + // - Extract formulas and comments |
| 105 | + // - Sort formulas by name |
| 106 | + // - Reconstruct with comments in place |
| 107 | + // 4. Replace original Brewfile |
| 108 | +} |
| 109 | +``` |
| 110 | + |
| 111 | +### Handling comments and anchors |
| 112 | + |
| 113 | +Brewfile examples: |
| 114 | +```ruby |
| 115 | +# This is a comment |
| 116 | +^anchor: some-anchor |
| 117 | + |
| 118 | +homebrew/cask-fonts # @homebrew/cask-fonts |
| 119 | +``` |
| 120 | + |
| 121 | +On sort: |
| 122 | +- Keep `^anchor:` lines exactly where they are |
| 123 | +- Move `homebrew/cask-fonts` to its sorted position |
| 124 | +- Keep comments with their formulas |
| 125 | +- Orphaned comments could become: `# (moved from line X)` |
| 126 | + |
| 127 | +--- |
| 128 | + |
| 129 | +## UX Considerations |
| 130 | + |
| 131 | +1. **Migration path:** When enabling auto-sort, suggest running `haven apply --remove-unreferenced-brews` to clean up first. |
| 132 | + |
| 133 | +2. **Dry-run mode:** `haven apply --dry-run --sort-brews` to preview the sorting effect. |
| 134 | + |
| 135 | +3. **Undo:** Keep a backup of the unsorted version temporarily; offer `haven undo --brews` to revert. |
| 136 | + |
| 137 | +4. **Documentation:** Add note to `COMMANDS.md` about the sort option when enabled. |
| 138 | + |
| 139 | +--- |
| 140 | + |
| 141 | +## Acceptance Criteria |
| 142 | + |
| 143 | +- [ ] Config option works correctly |
| 144 | +- [ ] Formulas are sorted by short name (without `homebrew/tap/` prefix) |
| 145 | +- [ ] Comments are preserved (either attached to formulas or marked as moved) |
| 146 | +- [ ] Anchors remain valid after sort |
| 147 | +- [ ] Existing unsorted Brewfiles still work (opt-in) |
| 148 | +- [ ] Unit tests cover sorting logic |
| 149 | + |
| 150 | +--- |
| 151 | + |
| 152 | +## Open Questions |
| 153 | + |
| 154 | +1. Should we preserve the exact line width and formatting of the original Brewfile? |
| 155 | +2. How to handle formulas that get added/removed between `brew bundle update` and `brew bundle dump`? |
| 156 | +3. Should we provide a CLI flag `--sort-brews` for manual sorting? |
0 commit comments