Description
Changes to homebrew-cask installation behaviour
Depending on how long you’ve been following the development of homebrew-cask (henceforth HBC), you might’ve come across this great rant1. It was the turning point in making the link
stanza (precursor to app
) a requirement to every cask. Prior to that, HBC tried hard to be smart about what to link, but we eventually concluded being smart doesn’t work — there are too many edge cases.
The end of linking, and the beginning of moving (reasoning)
We reached another such point with linking. What works for CLI apps does not work for GUI apps, and by sticking close to the homebrew model we’re bending apps to do what they’re not expecting, and only suffering from it. Issues we cannot fix continue to pop up, and copy as merely a preference or something to be done occasionally can’t solve them. We cannot, in addition to the inconsistency with pkg
s being installed instead of linked, add yet one extra inconsistency where even app
s won’t have a predictable behaviour. To put it bluntly, linking sucks for GUI apps. It doesn’t work and will never not be broken, as we can’t control what other developers do.
Linking isn’t even needed, if you think about it. What separation of concerns are we worried about? CLI tools should have the separation homebrew provides because some of their apps (like newer versions of OS-level tools) provide critical features that could break the entire system if overridden. That is not the case at all with GUI apps; the only apps we have that could break the system on install (pkg
s) are already given free range. If you use HBC, there’s not even any reason to install a GUI app any other way, so why would that separation matter?
GUI apps aren’t the only suffering from the current behaviour, even. Other artifacts suffer from similar issues and some even required the introduction of a different kind of linking.
In addition, while having different versions of the same CLI app is many times desirable, that is a far from the norm with GUI apps. Having an upgrade
that works on every app, even ones that auto-update, also becomes nonsensical.
We should emulate regular usage (i.e. what people do without HBC), instead of trying to perpetuate a new paradigm that is basically contradicting expectations. This, however, does not mean losing customisation options when it makes sense (like --appdir
).
Every workaround we build is forcing apps to fit our model, and our model is bad. We’re building workaround on top of workaround, adding more code and work for something that will never work correctly.
From The Cathedral and the Bazaar: “you often don't really understand the problem until after the first time you implement a solution. The second time, maybe you know enough to do it right. So if you want to get it right, be ready to start over at least once”.
As with other changes in the past, we now understand this problem a bit better and will adjust our solution accordingly.
The end of linking, and the beginning of moving (technical)
First steps towards new behaviour:
- Every artifact stanza except
binary
will move its target to the appropriate location, instead of being sym/hardlinked. app
s will be moved to/Applications
by default.:target
will continue to work, but rename the artifact itself instead of a link.- The Caskroom (
/opt/homebrew-cask/Caskroom/
by default) still needs to exist. - Versioned subdirectories of the Caskroom won’t exist anymore, though.
Explanations:
- Explained in the reasonings above why most artifacts will be moved instead of linked. As for binaries being the exception, it’s simple: not only is it expected, it’s advantageous, recommended, and sometimes necessary. Many times a
binary
is linked from inside an app bundle and cannot simply be moved/copied from there and continue to work. In these cases, symlinking is the recommended (by the developer) course of action anyway, so we stay in line with the idea of emulating regular usage. It also makes it work similarly to other CLI tools, like installs from homebrew. - Self-explanatory. It’s what most users expect, and would be our default anyway.
- Self-explanatory.
- It will be needed to keep a few things:
- The originals from
binary
, when they’re standalone. - Other things like uninstall scripts that come with some
pkg
s.
- The originals from
- Explained in the reasonings above.
New stanzas/keys/flags to enhance these changes
auto_updates
. Similarly tostage_only
, it should be used when a value oftrue
is needed. It means “the artifact this cask uses auto-updates, so even if the cask file updates, leave this alone when upgrading others”. This does not meanupgrade
in general is no longer a desirable feature — it is, but for casks who do not do it themselves.:required_location
. Example:app 'FontForge.app', :required_location => '/Applications'
. It means the artifact needs to be in a certain location to function correctly and as such will be moved there even if you have a different default location.--force-appdir
. Takes no arguments and forcibly overridesrequired_location
.
Pseudo-code for :required_location
, considering an app
:
if (--appdir is unset)
move_to /Applications
else
if (cask has :require_location) and (required_location_target != wherever_appdir_is_set_to)
print_warning "This app only works if installed in required_location_target, so it will be moved there"
move_to required_location_target
else
move_to wherever_appdir_is_set_to
end
Doesn’t this mean a bunch of stuff might break?
In the short term, yes, it does, but it is the right decision. We understand we have a bunch of users that are using homebrew-cask daily, and ideally we could try to make this a smooth transition like in the past. However, we’re admittedly pre-alpha and setting transition strategies is an inglorious job (everything will be discarded in the end, after all) that puts on hold even the smallest of changes indefinitely. It is incredibly time consuming, has variable results (we still get a bunch of issues pertaining to it), and (above all) kills momentum. Furthermore, this is a big change and there’s really no good way to make this seamlessly.
In the end, we want to continue to move forward and improve HBC. Being afraid of changes in a pre-alpha would mean stagnation.
Are there any other big changes planned?
There are ideas, yes, but no exact plans yet. Those ideas still need to be discussed and most are concerned with the creation and maintenance of casks, not the usage of HBC.
1 If you haven’t, I highly recommend it as piece of HBC’s history.