Skip to content

Commit 93c6773

Browse files
committed
1 parent 23948d5 commit 93c6773

File tree

112 files changed

+28091
-60
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+28091
-60
lines changed

.claude/settings.local.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,23 @@
1010
"mcp__memory__write-cypher",
1111
"mcp__memory__read-cypher",
1212
"Skill(jujutsu)",
13-
"Bash(ls:*)"
13+
"Bash(ls:*)",
14+
"Bash(find /Users/jstegeman/Projects/dfiles -name symlink_*)",
15+
"Bash(find /Users/jstegeman/Projects/dfiles/source -name symlink_*)",
16+
"Bash(find /Users/jstegeman/Projects/dfiles -path */source/* -name symlink_*)",
17+
"Bash(find /Users/jstegeman/Projects/dfiles -path */source/* -iname *settings*)",
18+
"Bash(find /Users/jstegeman/Projects/dfiles/source -name *.tmpl)",
19+
"Bash(python3 -m json.tool --no-indent)",
20+
"Read(//Users/jstegeman/.haven/**)",
21+
"Read(//Users/jstegeman/**)",
22+
"Bash(python3 -m json.tool)",
23+
"Bash(haven --version)",
24+
"Bash(git -C /Users/jstegeman/Projects/dfiles log --oneline --all)",
25+
"Bash(haven apply:*)",
26+
"Bash(grep -r \"maccask\\\\|class OS\\\\|module OS\" /Users/jstegeman/Projects/dfiles --include=*.rs --include=*.toml --include=*.md)",
27+
"WebFetch(domain:yadm.io)",
28+
"Bash(jj diff:*)",
29+
"Bash(grep -v \"^+++\\\\|^+use\\\\|^+ *//\\\\|^+ *$\")"
1430
]
1531
}
1632
}

.github/workflows/docs.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Deploy docs
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'docs/**'
9+
- 'mkdocs.yml'
10+
- 'CHANGELOG.md'
11+
- '.github/workflows/docs.yml'
12+
workflow_dispatch:
13+
14+
permissions:
15+
contents: write
16+
17+
jobs:
18+
deploy:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0
24+
25+
- uses: actions/setup-python@v5
26+
with:
27+
python-version: '3.12'
28+
cache: pip
29+
cache-dependency-path: docs/requirements.txt
30+
31+
- name: Install dependencies
32+
run: pip install mkdocs mkdocs-include-markdown-plugin
33+
34+
- name: Deploy to GitHub Pages
35+
run: mkdocs gh-deploy --force

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/target
2+
/site
23
.gstack/
34
.claude/settings.local.json

CHANGELOG.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,43 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
1111

1212
---
1313

14+
## [v0.5.5] — 2026-03-24
15+
16+
### Added
17+
18+
- **Brewfile auto-sort** — set `[homebrew] sort = true` in any module config to
19+
keep the Brewfile sorted alphabetically after every `haven brew install` or
20+
`haven brew uninstall`. Each kind (`tap`, `brew`, `cask`) is sorted
21+
independently; blank lines and comments are preserved in place.
22+
- **`haven apply` Brewfile summary** — the apply summary now reports how many
23+
Brewfiles were run: `Applied N file(s), M Brewfile(s) across K module(s)`.
24+
- **`haven status` improvements** — the profile name is now printed at the top
25+
of status output. A `✓ Everything up to date` message is shown when no drift
26+
is found.
27+
- **`haven import` symlink warning** — after importing from chezmoi, a summary
28+
of all imported `symlink_` entries is printed with a reminder to verify
29+
symlink targets before running `haven apply`.
30+
- **Documentation site** — full MkDocs documentation at
31+
[johnstegeman.github.io/haven](https://johnstegeman.github.io/haven), covering
32+
concepts, task-oriented guides, a reference section, and a dedicated
33+
"For chezmoi Users" section. Deployed automatically via GitHub Actions.
34+
35+
### Fixed
36+
37+
- **Symlink idempotency**`haven apply` no longer re-writes a symlink that
38+
already points to the correct target. Previously it would overwrite and
39+
count the file even when nothing changed.
40+
- **Dangling symlink backup**`haven apply` no longer attempts to back up a
41+
dangling symlink (one whose target has been deleted) before overwriting it.
42+
`std::fs::copy` follows symlinks and would fail; the dangling link is now
43+
removed directly.
44+
- **`brew bundle install` output** — spurious `Using <formula>` lines from
45+
`brew bundle` are now suppressed. Output is streamed in real time instead of
46+
being buffered until completion.
47+
- **Unused import** — removed unused `serde_yaml` import in `chezmoi.rs`.
48+
49+
---
50+
1451
## [v0.5.0] — 2026-03-23
1552

1653
### Added

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "haven"
3-
version = "0.5.0"
3+
version = "0.5.5"
44
edition = "2021"
55
description = "AI-first dotfiles & environment manager"
66
license = "MIT"

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
<img src="assets/logo-wide.svg" width="520" height="100" alt="haven — AI-first dotfiles &amp; environment manager"/>
33
</p>
44

5+
<p align="center">
6+
<a href="https://johnstegeman.github.io/haven">Documentation</a>
7+
</p>
8+
59
---
610

711
**haven** is a declarative, AI-first developer environment manager. It tracks your

design_auto_sort_brewfiles.md

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
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?

docs/changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{%
2+
include-markdown "../CHANGELOG.md"
3+
%}

0 commit comments

Comments
 (0)