On Homebrew

I get the impression that Homebrew is now the most popular OS X "package manager".

After some frustrating experiences with Fink back in the earlier days of Mac OS X, I decided I wasn’t much a fan of OS X package managers. My core complaint was that using them was placing yourself at the mercy of the package managers to provide you with up-to-date software. In the end, I ended up preferring just building it myself, which was generally ok as most open source software nowadays builds just fine on OS X with a simple ./configure && make && sudo make install. This has been true from the very early days of OS X.

Homebrew is so popular nowadays that this complaint is largely resolved. The range of packages ("formulae" in Homebrew lingo) is so large, and they are so promptly updated, that Homebrew stands to offer considerable convenience in exchange for relatively minimal risk of vendor lock-in.

Nevertheless, there is something that horrifies me about Homebrew, and it’s its desire to "own" /usr/local. It does this by enforcing a non-standard set of more liberal ownership and permissions on /usr/local and its subdirectories.

The argument is made that this is in service of avoiding sudo. sudo is bad and scary, and running with non-elevated privileges is good. Nevertheless, it seems utterly backwards to dispense with sudo by loosening the permissions on shared parts of the filesystem. This is merely trading one security risk for another, and its doing so in a way that violates the principle of least surprise and absolutely will clash with conventions and other software.

There is a brew doctor tool that you can run to check that everything is in order; here’s some sample output:

$ brew doctor
Warning: /usr/local/etc isn't writable.
This can happen if you "sudo make install" software that isn't managed
by Homebrew.

If a brew tries to write a file to this directory, the install will
fail during the link step.

You should probably `chown` /usr/local/etc

It’s very clear that Homebrew wants /usr/local all to itself, despite the fact that the Homebrew FAQ for "Can I install my own stuff to /usr/local?" says, "Yes, brew is designed to not get in your way so you can use it how you like."

Why does Homebrew want /usr/local so badly? Why doesn’t it conform itself with some other sandbox like /sw (which Fink uses)? The Homebrew FAQ claims:

Apple has conformed to POSIX and left this directory for us. Which means there is no /usr/local directory by default, so there is no need to worry about messing up existing tools.

I believe this is wishful thinking not grounded in reality. The MacPorts FAQ describes why it chooses to use /opt/local instead:

Traditionally, the place to install third party software on many UNIX systems is /usr/local. However, having MacPorts under /usr/local would be error-prone for precisely that reason. Many other software packages and packaging systems install into /usr/local, and could accidentaly overwrite what MacPorts has installed, or vice versa.

In my opinion, this is just common sense, and Homebrew is making the wrong trade off. The most robust thing to do would be to have Homebrew work within a sandbox like the other package managers do.

Another reason Homebrew wants to own /usr/local is convenience. The argument is that /usr/local/bin is in the PATH by default, so things will "just work". It’s true that /usr/local/bin is present (thanks to /etc/paths; see also man path_helper), but as Homebrew’s own FAQ points out, GUI apps which rely on command-line tools don’t see anything that you install via Homebrew, and Homebrew recommends hacking your ~/.MacOSX/environment.plist file to inject /usr/local/bin in the PATH that GUI apps see.

One final gripe: Homebrew wants /usr/local all to itself, but doesn’t confine itself to there; it also wants to write to brew --cache (usually /Library/Caches/Homebrew).

All of this is deeply disappointing, and detracts from what otherwise looks to be a really great project with a nice DSL and engaged community.