A Rust crate that provides diff functionality for Homebrew packages managed through nix-darwin. It compares what Homebrew actually has installed on the system versus what a nix-darwin configuration declares should be installed.
This crate is designed to show users what Homebrew changes will occur when they activate a new nix-darwin configuration, similar to how the dix crate shows Nix store diffs.
- Extract Homebrew intent from nix-darwin profiles
- Query current Homebrew state (installed formulae, casks, and taps)
- Compute differences between current state and intended state
- Colorized output with clear add/remove indicators
- Thread-based async processing (mirrors dix pattern)
<<< /run/current-system
>>> /nix/var/nix/profiles/system-123-link
ADDED
Formulae
[A] curl
Casks
[A] firefox
[A] visual-studio-code
REMOVED
Formulae
[R] wget
Casks
[R] slack
- Reads the nix-darwin activation script to find the Brewfile path, then parses that Brewfile to extract Homebrew intent
- Queries Homebrew directly for current state:
- Uses
brew leavesfor formulae (only user-installed packages, not dependencies) - Uses
brew list --caskfor casks - Uses
brew tapfor taps - Uses
mas listfor Mac App Store apps
- Uses
- Diffs current state with intended state to find additions and removals
- Formats the diff with colors and clear indicators
use brewdiff;
use std::path::Path;
// Primary use case: compare current state with new nix-darwin profile
let new_profile = Path::new("/nix/var/nix/profiles/system-123-link");
// Async diff computation
let handle = brewdiff::spawn_homebrew_diff(new_profile.to_path_buf());
if let Ok(diff_data) = handle.join() {
let diff = diff_data?;
println!("Changes: {} additions, {} removals",
diff.brews.added.len(),
diff.brews.removed.len());
}
// Or synchronous diff with output
let lines_written = brewdiff::write_homebrew_diffln(
&mut std::io::stdout(),
new_profile,
)?;