Repository navigation
bundle: add a pin: true Brewfile option - #24454
Conversation
MikeMcQuaid
left a comment
There was a problem hiding this comment.
Good idea, implementation needs some work:
- CI is failing
- Please address any CodeRabbit comments when they come in
- Let's use
pin: truerather thanpinned: true - Ensure
brew bundle dumpworks correctly - Try to slim the code here; it feels pretty complex for what should be simple
Summary
Merge Risk:
|
Since Homebrew 6.0.9 `brew upgrade` and `brew bundle` upgrade casks with `auto_updates true` whenever the tap version is confirmed newer than the installed one, and the only opt-out is the global `HOMEBREW_NO_UPGRADE_AUTO_UPDATES_CASKS`. `brew pin` already keeps a formula or cask out of both commands, but it is machine-local state that a `Brewfile` could not declare (Homebrew/discussions#6951). - `brew "foo", pin: true` and `cask "foo", pin: true` install the package when it is missing and then `brew pin` it. An installed, unpinned package is pinned without being upgraded; a pinned one is skipped. - `brew bundle dump` writes `pin: true` for pinned formulae and casks.
45c95c5 to
55ffa41
Compare
pinned: true Brewfile optionpin: true Brewfile option
|
Hi @MikeMcQuaid , all the requirements are addressed, the 2 CodeRabbit comments are manually resolved because I think making more commits breaks your "keep it simple" point. Similar to |
MikeMcQuaid
left a comment
There was a problem hiding this comment.
Thanks, this is more like it, nice work!
brew benchmarkresults.brewcommands to reproduce the bug?brew lgtm(style, typechecking and tests) locally?AI/LLM disclosure: the code, tests and docs in this PR were drafted with Claude Code (model Claude Fable 5.1) from the behaviour discussed in Homebrew/discussions#6951, and reworked the same way after the first review.
brew lgtmwas run locally, and the option was exercised end to end on a Mac (below). I review the diff myself and answer review comments myself.What
A per-entry
pin: trueoption forbrewandcasklines in aBrewfile:brew bundle installinstalls the package if it is missing and then runsbrew pinon it. An installed, unpinned package is pinned without being upgraded (progress verbPinning); a package that is already pinned is skipped. A pinned entry is never upgraded bybrew bundle, andbrew upgradeskips it as it skips any pinned package.brew bundle dumpwritespin: truefor pinned formulae and casks, so a dumpedBrewfilereproduces the pins on another machine.Undoing it is
brew unpin, as with any pin;brew bundle checktreats the option likegreedy:(it only sees the pin once it exists). Pinned casks withauto_updates truecan still update themselves outside Homebrew, asbrew pinalready warns.Why
Since 6.0.9,
brew upgradeandbrew bundleupgrade anauto_updates truecask whenever the version in the tap is confirmed newer than the installed app bundle. For a browser kept on its own update channel that is unwanted, and the only opt-out,HOMEBREW_NO_UPGRADE_AUTO_UPDATES_CASKS, is global.brew pinis the per-package answer for bothbrew upgradeandbrew bundle, but it is machine-local state that aBrewfileshared across machines could not declare. In Homebrew/discussions#6951 (https://github.com/orgs/Homebrew/discussions/6951#discussioncomment-17882821) I asked whether a per-cask toggle exists forbrew bundleand @p-linnane answered "No, there isn't. Happy to review a PR adding this if you'd like." This is that PR.How
bundle/cask.rb:upgrading?is false for a pinned entry;preinstall!lets an installed, unpinned cask through;install!then only runsbrew pin --cask;dumpemitspin: true.bundle/brew.rb: the same for formulae (@pin,pin_change_state!withbrew pin --formula,install_verb,dump).docs/Brew-Bundle-and-Brewfile.md: one example in the advancedBrewfilelisting.Verified on a Mac with
cask "microsoft-edge", pin: truein a scratchBrewfile:brew bundle installprintedPinning microsoft-edgeand left the installed version alone, a second run skipped it,brew bundle dumpwrotecask "microsoft-edge", pin: true, andbrew unpin --cask microsoft-edgerestored the box.