-
-
Notifications
You must be signed in to change notification settings - Fork 481
/
Copy pathhomebrew.nix
214 lines (179 loc) · 8.11 KB
/
homebrew.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# Created by: https://github.com/malob
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.homebrew;
brewfileSection = heading: type: entries: optionalString (entries != [])
"# ${heading}\n" + (concatMapStrings (name: "${type} \"${name}\"\n") entries) + "\n";
masBrewfileSection = entries: optionalString (entries != {}) (
"# Mac App Store apps\n" +
concatStringsSep "\n" (mapAttrsToList (name: id: ''mas "${name}", id: ${toString id}'') entries) +
"\n"
);
brewfile = pkgs.writeText "Brewfile" (
brewfileSection "Taps" "tap" cfg.taps +
brewfileSection "Brews" "brew" cfg.brews +
brewfileSection "Casks" "cask" cfg.casks +
masBrewfileSection cfg.masApps +
brewfileSection "Docker containers" "whalebrew" cfg.whalebrews +
optionalString (cfg.extraConfig != "") ("# Extra config\n" + cfg.extraConfig)
);
brew-bundle-command = concatStringsSep " " (
optional (!cfg.autoUpdate) "HOMEBREW_NO_AUTO_UPDATE=1" ++
[ "brew bundle --file='${brewfile}' --no-lock" ] ++
optional (cfg.cleanup == "uninstall" || cfg.cleanup == "zap") "--cleanup" ++
optional (cfg.cleanup == "zap") "--zap"
);
in
{
options.homebrew = {
enable = mkEnableOption ''
configuring your Brewfile, and installing/updating the formulas therein via
the <command>brew bundle</command> command, using <command>nix-darwin</command>.
Note that enabling this option does not install Homebrew. See the Homebrew website for
installation instructions: https://brew.sh
'';
autoUpdate = mkOption {
type = types.bool;
default = false;
description = ''
When enabled, Homebrew is allowed to auto-update during <command>nix-darwin</command>
activation. The default is <literal>false</literal> so that repeated invocations of
<command>darwin-rebuild switch</command> are idempotent.
'';
};
cleanup = mkOption {
type = types.enum [ "none" "uninstall" "zap" ];
default = "none";
example = "uninstall";
description = ''
This option manages what happens to formulas installed by Homebrew, that aren't present in
the Brewfile generated by this module.
When set to <literal>"none"</literal> (the default), formulas not present in the generated
Brewfile are left installed.
When set to <literal>"uninstall"</literal>, <command>nix-darwin</command> invokes
<command>brew bundle [install]</command> with the <command>--cleanup</command> flag. This
uninstalls all formulas not listed in generate Brewfile, i.e.,
<command>brew uninstall</command> is run for those formulas.
When set to <literal>"zap"</literal>, <command>nix-darwin</command> invokes
<command>brew bundle [install]</command> with the <command>--cleanup --zap</command>
flags. This uninstalls all formulas not listed in the generated Brewfile, and if the
formula is a cask, removes all files associated with that cask. In other words,
<command>brew uninstall --zap</command> is run for all those formulas.
If you plan on exclusively using <command>nix-darwin</command> to manage formulas installed
by Homebrew, you probably want to set this option to <literal>"uninstall"</literal> or
<literal>"zap"</literal>.
'';
};
global.brewfile = mkOption {
type = types.bool;
default = false;
description = ''
When enabled, when you manually invoke <command>brew bundle</command>, it will automatically
use the Brewfile in the Nix store that this module generates.
Sets the <literal>HOMEBREW_BUNDLE_FILE</literal> environment variable to the path of the
Brewfile in the Nix store that this module generates, by adding it to
<option>environment.variables</option>.
'';
};
global.noLock = mkOption {
type = types.bool;
default = false;
description = ''
When enabled, lockfiles aren't generated when you manually invoke
<command>brew bundle [install]</command>. This is often desirable when
<option>homebrew.global.brewfile</option> is enabled, since
<command>brew bundle [install]</command> will try to write the lockfile in the Nix store,
and complain that it can't (though the command will run successfully regardless).
Sets the <literal>HOMEBREW_BUNDLE_NO_LOCK</literal> environment variable, by adding it to
<option>environment.variables</option>.
'';
};
taps = mkOption {
type = with types; listOf str;
default = [];
example = [ "homebrew/cask-fonts" ];
description = "Homebrew formula repositories to tap.";
};
brews = mkOption {
type = with types; listOf str;
default = [];
example = [ "mas" ];
description = "Homebrew brews to install.";
};
casks = mkOption {
type = with types; listOf str;
default = [];
example = [ "hammerspoon" "virtualbox" ];
description = "Homebrew casks to install.";
};
masApps = mkOption {
type = with types; attrsOf ints.positive;
default = {};
example = {
"1Password" = 1107421413;
Xcode = 497799835;
};
description = ''
Applications to install from Mac App Store using <command>mas</command>.
When this option is used, <literal>"mas"</literal> is automatically added to
<option>homebrew.brews</option>.
Note that you need to be signed into the Mac App Store for <command>mas</command> to
successfully install and upgrade applications, and that unfortunately apps removed from this
option will not be uninstalled automatically even if
<option>homebrew.cleanup</option> is set to <literal>"uninstall"</literal>
or <literal>"zap"</literal> (this is currently a limitation of Homebrew Bundle).
For more information on <command>mas</command> see: https://github.com/mas-cli/mas.
'';
};
whalebrews = mkOption {
type = with types; listOf str;
default = [];
example = [ "whalebrew/wget" ];
description = ''
Docker images to install using <command>whalebrew</command>.
When this option is used, <literal>"whalebrew"</literal> is automatically added to
<option>homebrew.brews</option>.
For more information on <command>whalebrew</command> see:
https://github.com/whalebrew/whalebrew.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
example = ''
# 'brew tap' with custom Git URL
tap "user/tap-repo", "https://[email protected]/user/homebrew-tap-repo.git"
# set arguments for all 'brew cask install' commands
cask_args appdir: "~/Applications", require_sha: true
# 'brew install --with-rmtp', 'brew services restart' on version changes
brew "denji/nginx/nginx-full", args: ["with-rmtp"], restart_service: :changed
# 'brew install', always 'brew services restart', 'brew link', 'brew unlink mysql' (if it is installed)
brew "[email protected]", restart_service: true, link: true, conflicts_with: ["mysql"]
# 'brew cask install --appdir=~/my-apps/Applications'
cask "firefox", args: { appdir: "~/my-apps/Applications" }
# 'brew cask install' only if '/usr/libexec/java_home --failfast' fails
cask "java" unless system "/usr/libexec/java_home --failfast"
'';
description = "Extra lines to be added verbatim to the generated Brewfile.";
};
};
config = {
homebrew.brews =
optional (cfg.masApps != {}) "mas" ++
optional (cfg.whalebrews != []) "whalebrew";
environment.variables = mkIf cfg.enable (
optionalAttrs cfg.global.brewfile { HOMEBREW_BUNDLE_FILE = "${brewfile}"; } //
optionalAttrs cfg.global.noLock { HOMEBREW_BUNDLE_NO_LOCK = "1"; }
);
system.activationScripts.homebrew.text = mkIf cfg.enable ''
# Homebrew Bundle
echo >&2 "Homebrew bundle..."
if [ -f /usr/local/bin/brew ]; then
PATH=/usr/local/bin:$PATH ${brew-bundle-command}
else
echo -e "\e[1;31merror: Homebrew is not installed, skipping...\e[0m" >&2
fi
'';
};
}