Tags: zieka/bru
Tags
fix: correct cask upgrade silent failures and version drift (#114) - `bru upgrade` no longer silently downgrades casks on recent macOS when an older OS has a variation override. - Upgrades now actually replace the .app in /Applications instead of warning and reporting fake success. - Failed installs no longer leave stranded caskroom directories. - Download/HTTP errors now include the status code and URL.
fix: harden bru upgrade against real-world cask edge cases (#113) Five independent upgrade failures, all fixed: - Retry transient HTTP failures (3 tries, backoff) — recovers from mid-stream WriteFailed and HttpConnectionClosing aborts. - Upgrade GUI-only .app casks — the upgrade path skipped anything without CLI binaries, silently no-op'ing discord, obsidian, etc. - Sniff archive magic bytes when a cask URL has no extension (e.g. visual-studio-code's /darwin-arm64/stable). - Fall back to system tar when bottles use hard links — Zig's native iterator aborts on TarUnsupportedHeader (e.g. mingw-w64). - Stage binaries inside .app bundles: stage apps first, probe /Applications as a fallback source root, normalize absolute target paths to basename. Fixes docker-desktop's FileNotFound cluster.
feat: benchmark installs against native alternatives and add .app cas… …k support (#112) - Add `test/benchmark/` (bench_contenders.sh + bench_chart.sh) that times cold and warm installs across brew, zerobrew, nanobrew, malt, and bru, then runs per-formula correctness probes (pkg-config placeholder scan, transcode, query execution, tessdata presence, codesign verify) and renders one polished SVG per package. - Cask installer now handles `app` artifacts: `bru install --cask <name>` moves the .app bundle into /Applications and leaves a back-symlink in the Caskroom, matching brew's default behaviour. - README "How bru compares" updated with the empirical findings (zerobrew / nanobrew / malt skip various pkg-config and data-file patching steps); new Benchmark (beta) section embeds the result SVGs.
feat: support cask upgrades (#111) bru outdated and bru upgrade now handle casks alongside formulae. Both accept --cask and --formula flags; with no flag they operate on both. Upgraded casks swap symlinks atomically and remove the old Caskroom version after a successful link.
feat: run post_install scripts during bru install (#110) Formulas like node, openssl@3, fontconfig, ca-certificates, and gnupg ship a post_install Ruby block that creates symlinks, regenerates caches, and writes config the binary expects to find at runtime. bru now executes these blocks via /usr/bin/ruby with an embedded Homebrew-compatible runtime stub, so packages work end-to-end after install instead of being half-configured. Default ON. Disable per-invocation with --no-post-install, override the Ruby with --use-system-ruby=<path>, or set BRU_NO_POST_INSTALL=1. Failures are logged to <cache>/post-install-logs/ and never block the install. The install receipt records the outcome under a "bru" key.
fix: uninstall correctly removes Homebrew-installed packages (#109) When uninstalling a package originally installed by Homebrew (whose symlinks have relative targets like `/opt/homebrew/bin/mod -> ../Cellar/mod/...`), bru now resolves each target against the symlink's parent directory before deciding whether to remove it, instead of leaving dangling symlinks behind. Also guards against false matches between kegs with version-prefix overlap (e.g. `foo/1.0` vs `foo/1.0.1`). Adds a dangling-symlink sweep to `bru cleanup` so stragglers from the old behavior can be collected automatically.
feat: add bru relocate to repair pre-fix broken kegs (#108) * fix: use streaming writer in Output so multi-print works when redirected Output.print created a new File.Writer per call via file.writer(buf), which defaults to positional writes. Each new writer starts at file offset 0, so successive print calls overwrote each other whenever stdout was redirected to a regular file (e.g. `bru X > out.txt` or in CI log capture). Interactive TTY was unaffected because pwrite falls back to sequential write on non-seekable fds. Switch to writerStreaming, which tracks the file descriptor's actual position, so successive prints append in order. * feat: add relocate command to repair pre-fix broken kegs Adds \`bru relocate [name...]\` which re-runs replacePlaceholders and relocateMachO on already-installed kegs. With no args, sweeps the entire cellar; with names, repairs only those formulae. Needed because any keg that bru upgraded before the Mach-O relocation fix (before d19e4e0 / v0.4.0) still has literal @@HOMEBREW_PREFIX@@ paths in its dylib load commands. Uninstalling and reinstalling each affected formula works but is slow and breaks on formulae with reverse dependencies. relocate is a pure repair pass — no download, no symlink changes, just install_name_tool rewrites. Empirically verified by sweeping a 184-keg cellar with 0 errors and confirming mpv loads cleanly afterward (previously failed on missing symbols from libarchive, freetype, and harfbuzz due to stale placeholder load commands).
ci: detect conventional commits in squash-merge body bullets (#107) The version job skipped releasing PR #106 because its squash-merge subject ("Harden Mach-O relocation and add LC_RPATH parity (#106)") is not itself a conventional commit. GitHub's default squash-merge preserves each original commit as a "* type: ..." bullet in the body, so extend detection to include those lines — scan both subjects and body bullets instead of subjects alone.
fix: dangling stack pointer segfault in upgrade for revisioned packag… …es (#104) When a formula has revision > 0, prepareOne() formatted the version string into a stack-local buffer. That pointer was returned in PrepareResult.success.version, but the stack frame was destroyed when prepareOne returned — leaving the swap phase reading dead memory. Allocate from the arena instead, which outlives the swap phase.
PreviousNext