-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathbootstrap.sh
executable file
·209 lines (174 loc) · 7.78 KB
/
bootstrap.sh
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
#!/usr/bin/env bash
set -euo pipefail
# End-user DevX could also be potentially improved through this script: e.g,
# by helping new users to set up Nix using Determinate Systems new installer,
# or detect that it's used in a GitHub Actions context and advise installing Nix with Cachix's
# install Nix action.
verbosity=1
while getopts "v" opt; do
case $opt in
v) verbosity=$((verbosity + 1));;
*) echo "Invalid option: -$OPTARG" >&2; exit 1;;
esac
done
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log() {
local level="$1"
local msg="$2"
local color="$NC"
case "$level" in
DEBUG) color="$BLUE" ;;
INFO) color="$GREEN" ;;
WARN) color="$YELLOW";;
ERROR) color="$RED" ;;
*) echo "Unknown log level: $level" >&2; return 1;;
esac
if [ $verbosity -ge 2 ] || [ "$level" != "DEBUG" ]; then
echo -e "${color}${level}: ${NC}${msg}"
fi
}
log "INFO" "This script will set up nix and direnv, with opinionated default for Haskell development."
log "INFO" "[1/7] Install nix if it's not already installed ..."
if ! which nix >/dev/null 2>&1; then
if [ "$GITHUB_ACTIONS" == "true" ]; then
log "ERROR" "This script requires nix to be installed; you don't appear to have nix available. Since it seems that you're running this inside a GitHub Action, you can set up Nix using https://github.com/cachix/install-nix-action, e.g.:
- name: Install Nix with good defaults
uses: cachix/install-nix-action@v20
with:
extra_nix_config: |
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= loony-tools:pr9m4BkM/5/eSTZlkQyRt57Jz7OMBxNSUiMC4FkcNfk=
substituters = https://cache.iog.io/ https://cache.zw3rk.com/ https://cache.nixos.org/
nix_path: nixpkgs=channel:nixos-unstable"
exit 1
else
log "DEBUG" "nix is not installed. Would you like to install it now? (y/n)"
read -r confirm
if [[ "$confirm" == [yY] || "$confirm" == [yY][eE][sS] ]]; then
log "DEBUG" "Installing nix..."
curl -L https://nixos.org/nix/install | sh
. "$HOME/.nix-profile/etc/profile.d/nix.sh"
log "DEBUG" "nix installed successfully."
else
log "ERROR" "nix is required for the setup process. Please install nix and re-run the script."
exit 1
fi
fi
else
log "DEBUG" "nix is already installed."
fi
log "INFO" "[2/7] Tweak nix.conf with good defaults (may need sudo) ..."
if [ -z "${XDG_CONFIG_HOME:-}" ]; then
XDG_CONFIG_HOME="$HOME/.config"
fi
nix_conf_file="$XDG_CONFIG_HOME/nix/nix.conf"
if grep -q "experimental-features" "$nix_conf_file"; then
log "WARN" "The 'experimental-features' option already exists in '$nix_conf_file'. Please check that it's set to 'experimental-features = nix-command flakes'."
echo "Press ENTER to open $nix_conf_file in $EDITOR:"
read -r confirm
$EDITOR "$nix_conf_file"
else
echo "experimental-features = nix-command flakes" >> "$nix_conf_file"
log "DEBUG" "'experimental-features = nix-command flakes' added to nix configuration."
fi
nix_conf_file="/etc/nix/nix.conf"
check_and_append_config() {
local key="$1"
local value="$2"
if grep -q "^$key" "$nix_conf_file"; then
echo "WARN: The '$key' option already exists in '$nix_conf_file'."
echo "You expected to add '$key = $value'."
echo "Press ENTER to open $nix_conf_file in $EDITOR for manual inspection:"
read -r confirm
sudo $EDITOR "$nix_conf_file"
else
echo "$key = $value" | sudo tee -a "$nix_conf_file" > /dev/null
log "DEBUG" "'$key = $value' added to system-wide nix configuration."
fi
}
check_and_append_config "allow-import-from-derivation" "true"
check_and_append_config "extra-substituters" "https://cache.iog.io https://cache.zw3rk.com"
check_and_append_config "extra-trusted-public-keys" "\"hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=\" \"loony-tools:pr9m4BkM/5/eSTZlkQyRt57Jz7OMBxNSUiMC4FkcNfk=\""
log "INFO" "[3/7] Restart nix-daemon (need sudo) ..."
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
if which systemctl >/dev/null 2>&1 && systemctl is-active --quiet systemd; then
log "DEBUG" "Restarting nix-daemon..."
sudo systemctl restart nix-daemon.service
else
log "WARN" "Please restart nix-daemon manually."
echo "Press ENTER to continue ..."
read -r confirm
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
if which launchctl >/dev/null 2>&1; then
log "DEBUG" "Restarting nix-daemon..."
sudo launchctl kickstart -k system/org.nixos.nix-daemon
else
log "WARN" "Please restart nix-daemon manually."
echo "Press ENTER to continue ..."
read -r confirm
fi
fi
log "INFO" "[4/7] Install direnv if it's not already installed ..."
if ! which direnv >/dev/null 2>&1; then
log "DEBUG" "direnv is not installed. Would you like to install it now? (y/n)"
read -r confirm
if [[ "$confirm" == [yY] || "$confirm" == [yY][eE][sS] ]]; then
log "DEBUG" "Installing direnv..."
nix profile install nixpkgs#direnv
log "DEBUG" "direnv installed successfully."
else
log "ERROR" "direnv is required for the setup process. Please install direnv and re-run the script."
exit 1
fi
else
log "DEBUG" "direnv is already installed."
fi
log "INFO" "[5/7] Hook direnv into the user shell ..."
# shellcheck disable=SC2016
if grep -q 'direnv hook' "$HOME/.bashrc"; then
log "DEBUG" "direnv seems already hooked into '$HOME/.bashrc'."
else
echo 'eval "$(direnv hook bash)"' >> "$HOME/.bashrc"
log "DEBUG" "direnv hook added to '$HOME/.bashrc'."
fi
# shellcheck disable=SC2016
if ! which zsh >/dev/null 2>&1 || grep -q 'direnv hook' "$HOME/.zshrc"; then
log "DEBUG" "zsh isn't in PATH or direnv seems already hooked into '$HOME/.zshrc'."
else
echo 'eval "$(direnv hook zsh)"' >> "$HOME/.zshrc"
log "DEBUG" "direnv hook added to '$HOME/.zshrc'."
fi
# shellcheck disable=SC2016
if ! which fish >/dev/null 2>&1 || grep -q 'direnv hook' "$XDG_CONFIG_HOME/fish/config.fish"; then
log "DEBUG" "fish isn't in PATH or direnv seems already hooked into '$XDG_CONFIG_HOME/fish/config.fish'."
else
echo 'eval "$(direnv hook fish)"' >> "$XDG_CONFIG_HOME/fish/config.fish"
log "DEBUG" "direnv hook added to '$XDG_CONFIG_HOME/fish/config.fish'."
fi
log "INFO" "[6/7] Configure .envrc in the project directory ..."
if [ -f ".envrc" ]; then
log "DEBUG" ".envrc file already exists."
else
echo 'if ! has nix_direnv_version || ! nix_direnv_version 2.3.0; then
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.3.0/direnvrc" "sha256-Dmd+j63L84wuzgyjITIfSxSD57Tx7v51DMxVZOsiUD8="
fi' >> ".envrc"
if [ -f "flake.nix" ]; then
echo "use flake" >> ".envrc"
elif [ -f "shell.nix" ]; then
echo "use nix" >> ".envrc"
else
# FIXME: maybe we could ask interactively what compiler version and shell flavor the user want to use?
echo "use flake \"github:input-output-hk/devx#ghc8107-iog\"" >> ".envrc"
fi
log "DEBUG" "Successfully created and populated .envrc file."
fi
log "INFO" "[7/7] Allow direnv to load the .envrc ..."
direnv allow
log "DEBUG" ".envrc configuration allowed."
log "INFO" "Setup process is complete! 🎉"
# FIXME: maybe directly install VSCode extension with `code --install-extension pinage404.nix-extension-pack; code --install-extension haskell.haskell` if `code` is in PATH?!
log "INFO" "For proper editor integration, you need to install the direnv extension for your specific editor. E.g., if you use VSCode, search for \"direnv\" in the extensions marketplace and install the plugin. Reload your editor and you're all set!"