From 73a6ceda1bd5d8e09953c136b521e42f0bc8e94d Mon Sep 17 00:00:00 2001 From: Emily Date: Sat, 11 Jan 2025 15:44:41 +0000 Subject: [PATCH] homebrew: move to system activation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds an optional explicit `homebrew.user` option that allows users to avoid setting `system.primaryUser`, partly as a proof of concept of what the interfaces should look like in the future. Homebrew only officially support one global installation, so a singleton matches upstream’s expectations; in practice, it may be useful for us to nest this into `users.users.*.homebrew` instead, at the expense of being an unsupported setup if used to its full potential. Since that would be a breaking change to the inteface anyway, I think adding `homebrew.user` for now is acceptable. (I think one native Apple Silicon and one Rosetta 2 Homebrew installation – under `/opt/homebrew` and `/usr/local` respectively – may be exceptions to this lack of upstream support, but that would be complicated to support even with `users.users.*.homebrew`.) I’m not entirely sure where in system activation this should go. Probably after the user defaults and launch agents stuff, to match the existing logic in user activation, and I lean towards doing it as late as possible; too early and we might not have the users and groups required to bootstrap a Homebrew installation set up, but as Homebrew installations could be fiddly and fail, doing it in the middle could leave a partially‐activated system. Probably it should be done in a launch agent or something instead, but this is my best guess as to the appropriate place for now. The downside is that activation scripts generally won’t be able to assume that the Homebrew prefix is populated according to the current configuration, but they probably shouldn’t be depending on that anyway? --- modules/homebrew.nix | 18 ++++++++++++++++++ modules/system/activation-scripts.nix | 2 +- tests/homebrew.nix | 2 ++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/modules/homebrew.nix b/modules/homebrew.nix index 10764fbb..c78d41fe 100644 --- a/modules/homebrew.nix +++ b/modules/homebrew.nix @@ -559,6 +559,17 @@ in This module also provides a few options for modifying how Homebrew commands behave when you manually invoke them, under [](#opt-homebrew.global)''; + user = mkOption { + type = types.str; + default = config.system.primaryUser; + defaultText = literalExpression "config.system.primaryUser"; + description = '' + The user that owns the Homebrew installation. In most cases + this should be the normal user account that you installed + Homebrew as. + ''; + }; + brewPrefix = mkOption { type = types.str; default = if pkgs.stdenv.hostPlatform.isAarch64 then "/opt/homebrew/bin" else "/usr/local/bin"; @@ -764,6 +775,10 @@ in (mkIf (options.homebrew.autoUpdate.isDefined || options.homebrew.cleanup.isDefined) "The `homebrew' module no longer upgrades outdated formulae and apps by default during `nix-darwin' system activation. To enable upgrading, set `homebrew.onActivation.upgrade = true'.") ]; + system.requiresPrimaryUser = mkIf (cfg.enable && options.homebrew.user.highestPrio == (mkOptionDefault {}).priority) [ + "homebrew.enable" + ]; + homebrew.brews = optional (cfg.whalebrews != [ ]) "whalebrew"; @@ -786,6 +801,9 @@ in echo >&2 "Homebrew bundle..." if [ -f "${cfg.brewPrefix}/brew" ]; then PATH="${cfg.brewPrefix}:${lib.makeBinPath [ pkgs.mas ]}:$PATH" \ + sudo \ + --user=${escapeShellArg cfg.user} \ + --set-home \ ${cfg.onActivation.brewBundleCmd} else echo -e "\e[1;31merror: Homebrew is not installed, skipping...\e[0m" >&2 diff --git a/modules/system/activation-scripts.nix b/modules/system/activation-scripts.nix index c8ad20ad..40a2ed23 100644 --- a/modules/system/activation-scripts.nix +++ b/modules/system/activation-scripts.nix @@ -96,6 +96,7 @@ in ${cfg.activationScripts.keyboard.text} ${cfg.activationScripts.fonts.text} ${cfg.activationScripts.nvram.text} + ${cfg.activationScripts.homebrew.text} ${cfg.activationScripts.postActivation.text} @@ -138,7 +139,6 @@ in ${cfg.activationScripts.extraUserActivation.text} ${cfg.activationScripts.userDefaults.text} ${cfg.activationScripts.userLaunchd.text} - ${cfg.activationScripts.homebrew.text} ${cfg.activationScripts.postUserActivation.text} diff --git a/tests/homebrew.nix b/tests/homebrew.nix index d7fdeabc..65ece025 100644 --- a/tests/homebrew.nix +++ b/tests/homebrew.nix @@ -15,6 +15,8 @@ in { homebrew.enable = true; + homebrew.user = "test-homebrew-user"; + # Examples taken from https://github.com/Homebrew/homebrew-bundle homebrew.taps = [ "homebrew/cask"