What I appreciate about Homebrew is that in years of using it, I have never felt the need to dive deeply into its inner workings. For the most part, it just works. I can access the utilities I need to do my work and reliably keep them updated. Homebrew has its problems for sure, but the tooling has improved immensely over the recent years. So thank you for your work!!!
Also side note, I just recently discovered the brew bundle command's --global flag. It basically let's you use a declarative format globally installed taps, formula, casks, and vscode extensions. I can add the .Brewfile to my dotfiles repo to sync across machines. Though, it's not really what the bundle command is meant for, it sure beats manually copying down and installing the list of formula.
Way too often technical people care more about the pureness of the underlying implementation than they do the end-user experience. I've both worked with and been that person in the past, the person that wants to impose internal implementation limits on the UI/UX. One of the best lessons I've learned is try to make software that behaves how people want it to behave, not necessarily in a way that perfectly jives with how you implemented something on the backend/internally.
I don't know much about the inner workings of homebrew and the best part is I don't have to. MacPorts worked decently enough for me pre-homebrew but it would sometimes break in unexpected ways. Homebrew "just works" in a way that I greatly appreciate.
I've never done a dive into package managers and just used what's been available. So even though homebrew is slower than other package managers, it has also rarely thrown me for a loop.
See the Nix Package Manager[1].
For instance, Google Chrome litters the filesystem and is not easy to clean up manually. Homebrew however can remove all traces by passing the --zap option:
brew uninstall --zap google-chrome
You can view the formula as follows: brew info --github google-chrome
Look for the zap stanza, there's a whole list of folders.1. It doesn't work well with multiple users 2. It doesn't build apps using DESTDIR correctly.
Number 2 has been a bigger issue for me. Homebrew configures autotools applications using the full prefix of /usr/local/Cellar/app/version. It then gets installed to that prefix and is symlinked to /usr/local.
The problem here, is apps built like this look for their data in their prefix path (/usr/local/Cellar/app/version/usr/share/data/) rather than /usr/local/data. This ends up breaking things.
For example, I was working on porting a gtk app to mac os, and needed to build gobject bindings. Normally, glib would be built with a prefix of /usr/local, so it'd look for all gobject bindings in /usr/local/share/gir-1.0/. But since glib is being build with a prefix of /usr/local/Cellar/glib/2.40.0, it is expecting all gobject bindings in /usr/local/Cellar/glib/2.40.0/usr/share/gir-1.0/.
But, when I build libchamplain, it installs its gobject file in /usr/local/Cellar/libchamplain/1.0.1/usr/share/gir-1.0/.
Now, everything gets symlinked to /usr/local/share/gir-1.0/, so it looks like it would work, right? Except, gobject was built with the full prefix, so it _only_ looks in /usr/local/Cellar/glib/2.40.0/usr/share/gir-1.0/ for gobject files. This means it doesn't find libchamplain or any other libraries.
The correct way to do this, is to run configure with the destination prefix (/usr/local/), then do an install using DESTIDR: make install DESTDIR=/usr/local/Cellar/glib/2.40.0/. Then you can symlink to /usr/local/.
Homebrew is a great project and has been an incredible help for me.
I am perfectly fine with macOS's UNIX™, out of the box experience.
This is what I was talking about about HN sentiment, though: for some reason you "don't care" enough to click through to the comments on a "Homebrew is Awesome" post and feel the need to tell everyone that you don't care. That's a different experience of "don't care" than I have and I find it intriguing.
For example I have a mono repository which contain Makefile and can produce one or six different executable tools. Four of these six tools are CLI utilities but the other three should work as a service. The problem I have encountered is the lack of documentation or an example of how to write auto-tests for daemons and for utilities in one formula because some of them require a working database from another Formula or in the root of the system. That is, it is very difficult to write such auto-tests, which would check workability, and really it was possible to run them when building the formula.
Yes, the workaround is to make own repository with Homebrew Tap but better to have it in main repository when users could setup software without any additional action.
I'm really not convinced that Ruby syntax is what makes the Homebrew formula DSL non-trivial. I've written enough YAML for k8s stuff that it seems like the language is rarely the cause of misunderstanding.
But If I know I am going to install multiple versions of a program ahead of time, I use asdf-vm instead
(I don’t know why Intel Macs still use /usr/local.) In any case, it’s possible to choose a custom installation location, even on Intel Macs if you prefer.
https://docs.brew.sh/Installation
Further discussion on the decision:
So you can, but apparently you shouldn't.