Linux users might laugh at us but this is still very convenient and according to the upvotes still new for some people.

It might be less polished than this solution but on Windows the same can be done with Chocolatey: https://chocolatey.org/search?q=font

> Linux users might laugh at us...

Why? I have my system config source controlled and even have a bootstrap script to set up a new Mac from scratch that installs Homebrew, which installs git and Python, and then installs via Homebrew all my system packages and casks like Google Chrome, iTerm2, Spotify, etc. plus programming language packages through their respective package managers, etc. And now fonts (which I only discovered the tap for a little while ago). That's one less thing to install/update manually and it's very appreciated.

>> Linux users might laugh at us...

> Why?

As a mostly exclusive user of GNU+Linux for the past 9 years who started using a Mac last year because it was issued to me by my employer:

because Homebrew lacks many of the strengths of the kinds of package managers you find in the Linux ecosystem.

It only half-installs some packages, leaving you to manually link things in to certain directories (it was like this with Varnish a few months ago, and maybe still is). It's generally nondeterministic. Huge parts of it are basically scripted installation of preexisting binary packages, putting it more on par with Chocolatey or yaourt than a tool like apt backed by proper repos with source packages.

More on the topic of fonts in particular, there are tons of reasons that Apple's font handling, especially but not only in terms of installation and configuration management, is an embarrassment. macOS lacks configurable font substitutions, so extended characters like those provided in the ‘nerd fonts’ can only appear in applications which can be explicitly configured to use those fonts. Certain fonts are considered ‘required’ parts of the system, so that to modify or remove them on a Mac you have to disable System Integrity Protection, and a whole host of apps will simply crash on startup if, e.g., the Apple Color Emoji font is missing. macOS ignores emoji embedded in fonts that the user has chosen, and instead always injects the Apple emoji. Font rendering in macOS and iOS has been the source of numerous crashing and freezing issues of such a similar kind to one another that it is somewhat surprising and interesting that the entire class of such bugs wasn't fixed after the first major incident (as has been discussed on Hacker News recently).

Homebrew is also basically incapable of reliable uninstallation of packages; common advice is to use separate prefixes or wipe your whole installation with a series of commands that force you to reckon with the internal structure of Homebrew. It's not always compatible with other package managers for macOS, so care has to be taken if multiple alternatives are supposed to be usable. The state of Homebrew installations is so frequently a broken one that they have a dedicated subcommand for trying to figure out why Homebrew is broken in `brew doctor`, and sometimes breakages are caused by updates to macOS itself, which are installed via a separate mechanism.

And even when it works, Homebrew is essentially still always operating on fundamentally two distinct kinds of packages (traditional source-based installations in the FHS and macOS-specific `.app` bundles), whose difference is noticed and felt by every user because different subcommands are used for handling such packages, and they end up in different places.

I'd imagine, too, that the fact you had to write your own bootstrap script could be part of what the parent poster was getting at, in that Linux has a ton of choices for configuration management tooling due to its presence on the server.

Homebrew is an awesome effort, and I use it whenever Nixpkgs is missing something I don't feel like packaging myself. The casks are really nice because almost every end-user application on macOS is distributed as a DMG archive that extracts to a .app folder, so there are not as many applications one must use a browser to hunt for as there are on Windows.

I wouldn't want to mock macOS users over this, nor to disparage all of the useful and impressive work that Homebrew contributors have done in retrofitting macOS with a package manager which can do a lot. And to the extent that a bootstrapping script based on tools like Homebrew gets its job done, it is a success in its own right. But Homebrew offers nowhere near the control, speed, or basic featureset of something like apt, Portage, Nix, or zypper. And it's not integrated into the system like the native package manager is on any Linux distro. There's a lot for Linux users to miss from their old package managers when they're using Homebrew on macOS. And the font situation on macOS is a controlling, user-hostile travesty to anyone who expects their OS to do what they tell it rather than the other way around, and disconcertingly coupled with core system components besides.

tl;dr: Homebrew is a great project, but habitual Linux users on macOS know there's no place like home when it comes to package management (or font configuration, for that matter)

Generally everything you're saying about Linux package management vs Homebrew is the opposite of my experience. A coworker uses Linux for his machine and apt's packages always seem out of date or he has problems installing things, whereas Homebrew always just works.

I get what you're saying about source installs and so on, but these seem like more philosophical issues, since Homebrew just works and I install pretty much literally everything on my system through it, including full apps like Chrome, LibreOffice, etc.

> I'd imagine, too, that the fact you had to write your own bootstrap script could be part of what the parent poster was getting at

I'd have to do basically the same anyway. All the bootstrap script does is make sure Homebrew, git, and Python 3 are installed, checks out my repo, and then runs my setup program to set up everything.

P A R T . . . O N E

> Generally everything you're saying about Linux package management vs Homebrew is the opposite of my experience. A coworker uses Linux for his machine and apt's packages always seem out of date or he has problems installing things, whereas Homebrew always just works.

A TALE OF TWO HOMEBREWS: the package management tools

I think it would be helpful here to distinguish Homebrew-as-package-manager ( https://github.com/Homebrew/brew ) from Homebrew-as-repository ( https://github.com/Homebrew/homebrew-core ).

As a technology or stack of technologies for building, installing, upgrading, and configuring software, Homebrew can be compared to package management systems on Linux distros. In my opinion, the package management system is the heart of a Linux distribution. Two distros are essentially interchangeable if they share repositories and a package manager; they're the same system twice, each time with a different desktop environment installed by default. And with a little courage and good ole apt, you can even convert from Ubuntu to Linux Mint! Here, I don't think Homebrew (in particular `brew`) stands up very well.

For example, Homebrew doesn't handle orphaned packages. When a package is installed, it drags in all its dependencies. But when the package is uninstalled, they are left behind. In the Linux world, different tools handle this problem differently. The `aptitude` command-line interface for apt tries to remove all orphaned dependencies every time you install, uninstall, or upgrade. Apt users (Debian, Ubuntu, Linux Mint, PopOS, all their remixes and many more) can also use `apt-get autoremove` to clean up any orphaned dependencies they may have left over. Gentoo users can remove orphaned dependencies with `emerge --depclean`. Fedora users can run `dnf autoremove`. NixOS and GuixSD have a garbage collector for packages.

By contrast, if you run `brew install cowsay` and then `brew uninstall cowsay`, everything that Homebrew installed just to put `cowsay` on your system is left behind. You're accruing ‘cruft’ with each package installation. And sometimes you might then find out that some package you were compiling got a different library version than you expected, and you can't for the life of you figure out why you even have that version of that library installed. It appears at a glance that Homebrew lacks any solution for removing orphaned dependencies after the fact, as with `apt autoremove`, but there is a third-party extension for removing hopefully-obsolete dependencies at uninstall time. It gives you a `brew rmtree` subcommand.

The first thing you'll notice on its GitHub page is a great big warning ( https://github.com/beeftornado/homebrew-rmtree#warning ). One thing this warning reveals is that Homebrew doesn't distinguish between packages that the user has chosen to install and packages that just happen to be present on the system. This is the reason that `brew rmtree` might remove command-line tools that you actually use-- because nothing _else_ you have installed depends on them, even though they're a package you explicitly told `brew` to install, because you wanted it. The author's workaround is a command-line flag `--ignore`, which allows you to list packages you want preserved, presumably after you notice that they got removed when you didn't want them to. The best user experience I can imagine for this feature is aliasing or wrapping the command with a list of your ‘preserved packages’, so that `brew rmtree` becomes safe to use with respect to them.

Not only is this not a problem with the package manager of any decent Linux distro, in addition to tracking which packages were installed on purpose (enabling the automatic removal of unused dependencies in a way that is actually safe to use), Linux package managers also offer a whole range of powerful and sensible tools for handling the trickier cases. On Sabayon Linux, for example, the Entropy package management system provides (vs. the `--ignore` flag on a third-party extension we get with Homebrew, one command-line argument you can use at install time only) a system of package masking, whereby one can specify ranges of versions, prohibit or require that particular packages be bleeding edge releases or that they come from the battle-tried stable repositories, and so on. On openSUSE, with `zypper`, each repository has a priority (they are all the same priority by default), which users can modify. By prioritizing your repositories, you can control the versions of specific pieces of software but still receive security updates. You can also pin packages at specific version or range of versions. In addition, Zypper associates each package with a `vendor`, to make better sense of choosing packages from different sources. This is really nice if, for example, you want your base system to be a stable distro release, but you want Firefox and all of its dependencies to come from a repository that houses the latest stable Firefox builds. At the same time, you may want to install the latest version of your favorite multimedia player, but retain the codecs from your base system, or a repository that ships codecs with the greatest compatibility. Many Linux distros provide excellent tools for easily managing things like this.

To return to Homebrew, on that side we have `brew pin`, which allows you to tell Homebrew not to automatically update a particular package along the way to doing other things you tell it to do in the future. For repository management, Homebrew has the tap system, which offers no real priority but a `brew tap pin` command whose documentation contains the following caveat:

‘Do note that pinned taps are prioritized only when the formula name is directly given by you, i.e. it will not influence formulae automatically installed as dependencies.’

so it does not effect a systemwide change (and presumably no mechanism for doing so is provided). Besides only affecting part of the system, the only function of `brew tap pin` is ‘to prioritize a tap over homebrew/core’ ( https://docs.brew.sh/Taps ). So we get no way to control the relative priorities of taps at all.

Linux distros have been hacking on their package management tools for ages and ages, as core components of entire operating systems. The tools are usually written in C and operate on little databases. They've equipped these systems to roll out configuration changes (after backing up the old ones), safely migrate users to equivalent packages when old forks die, stop and start services, optionally guide users through configuration, install bootloaders, recalculate font caches, tell the desktop environment to reindex its application shortcuts for search. And they do these things in ways that make it possible to disable the ‘hooks’ associated with these packages, (or re-run them whenever), and to lint these packages for all kinds of standards. Macros in the package definition formats make it possible for a single package definition to be usable for multiple Linux distributions, even including different operating system kernels. Homebrew only recently got ‘bottles’, which are a non-integrated mechanism of providing caches of prebuilt binaries for Homebrew's source-based packages; many Linux distros, on the other hand, have been distributing updates as compressed binary deltas between the currently installed version and the latest installed versions, for years.

Distros are working on deep, deep aspects of package quality, as well, in a way that I haven't seen as much outside of those projects. Debian, for example, has been doing a ton of work with upstream projects to make their builds deterministic, so that Debian packages can be built so reliably that one can usually expect bit-for-bit reproducibility. NixOS and GuixSD have pioneered and developed an approach to package management which draws upon the principles of functional programming in order to facilitate exhaustive, declarative configuration and provide guarantees portability, determinism, and the ability to roll back upgrades and installations at will. openSUSE builds every one of their packages by allocating a fresh, empty virtual machine and installing only the dependencies specified in the package, to make it impossible for their packages to have any missing, hidden, or broken dependencies. And on Linux systems, package managers are tightly integrated into the system in a way that Homebrew will likely never be, not for any lack of expertise or effort on the part of Homebrew developers, but because the choice is ultimately not up to them. On a GNU+Linux system, the same package management tool is used for system upgrades as for application installation, and there's a lot of power, convenience, and predictability which comes from that.