-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathfresh-install-of-osx.sh
executable file
·397 lines (336 loc) · 17.8 KB
/
fresh-install-of-osx.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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
#!/usr/bin/env zsh
# vim:filetype=zsh syntax=zsh tabstop=2 shiftwidth=2 softtabstop=2 expandtab autoindent fileencoding=utf-8
# This script is idempotent and will restore your local setup to the same state even if run multiple times.
# In most cases, the script will provide warning messages if skipping certain steps. Each such message will be useful to give you a hint about what to do to force rerunning of that step.
# file location: <anywhere; but advisable in the PATH>
# TODO: Need to figure out the scriptable commands for the following settings:
# 1. Auto-adjust Brightness
# 2. Brightness on battery
# 3. Keyboard brightness
script_start_time=$(date +%s)
echo "==> Script started at: $(date)"
#############################################################
# Utility scripts and env vars used only within this script #
#############################################################
export ZSH_CUSTOM="${ZSH_CUSTOM:-"${ZSH:-"${HOME}/.oh-my-zsh"}/custom"}"
# These repos can be alternatively tracked using git submodules, but by doing so, any new change in the submodule, will show up as a new commit in the main (home) repo. To avoid this "noise", I prefer to decouple them
clone_omz_plugin_if_not_present() {
clone_repo_into "${1}" "${ZSH_CUSTOM}/plugins/$(extract_last_segment "${1}")"
}
ensure_safe_load_direnv() {
if [[ "$(pwd)" == "${1}" ]]; then
pushd ..; popd
else
pushd "${1}"; pushd ..; popd; popd
fi
success "Successfully allowed 'direnv' config for '$(yellow "${1}")'"
}
######################################################################################################################
# Set DNS of 8.8.8.8 before proceeding (in some cases, for eg Jio Wifi, github doesn't resolve at all and times out) #
######################################################################################################################
if test -n "$(curl ipinfo.io | \grep -i jio)"; then
echo '==> Setting DNS for WiFi'
sudo networksetup -setdnsservers Wi-Fi 8.8.8.8
fi
#################################################################################################
# Download and source this utility script - so that the functions are available for this script #
#################################################################################################
echo "==> Download the '${HOME}/.shellrc' for loading the utility functions"
if ! type warn &> /dev/null 2>&1; then
! test -f "${HOME}/.shellrc" && curl -fsSL "https://raw.githubusercontent.com/${GH_USERNAME}/dotfiles/refs/heads/${DOTFILES_BRANCH}/files/--HOME--/.shellrc" -o "${HOME}/.shellrc"
FIRST_INSTALL=true source "${HOME}/.shellrc"
else
warn "skipping downloading and sourcing '$(yellow "${HOME}/.shellrc")' since its already loaded"
fi
###############################################################################################
# Ask for the administrator password upfront and keep it alive until this script has finished #
###############################################################################################
keep_sudo_alive
###############################
# Do not allow rootless login #
###############################
# Note: Commented out since I am not sure if we need to do this on the office MBP or not
# section_header 'Verifying rootless status'
# [[ "$(/usr/bin/csrutil status | awk '/status/ {print $5}' | sed 's/\.$//')" == "enabled" ]] && error "csrutil ('rootless') is enabled. Please disable in boot screen and run again!"
#####################
# Turn on FileVault #
#####################
section_header 'Verifying FileVault status'
[[ "$(fdesetup isactive)" != 'true' ]] && error 'FileVault is not turned on. Please encrypt your hard disk!'
##################################
# Install command line dev tools #
##################################
section_header 'Installing xcode command-line tools'
if ! is_directory '/Library/Developer/CommandLineTools/usr/bin'; then
# install using the non-gui cmd-line alone
touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
sudo softwareupdate -ia --agree-to-license --force
rm /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
success 'Successfully installed xcode command-line tools'
else
warn 'skipping installation of xcode command-line tools since its already present'
fi
#################################
# Setup ssh scripts/directories #
#################################
section_header 'Setting ssh config file permissions'
set_ssh_folder_permissions
#################################################################################
# Ensure that some of the directories corresponding to the env vars are created #
#################################################################################
section_header 'Creating directories defined by various env vars'
ensure_dir_exists "${DOTFILES_DIR}"
ensure_dir_exists "${PROJECTS_BASE_DIR}"
ensure_dir_exists "${PERSONAL_BIN_DIR}"
ensure_dir_exists "${PERSONAL_CONFIGS_DIR}"
ensure_dir_exists "${PERSONAL_PROFILES_DIR}"
ensure_dir_exists "${XDG_CACHE_HOME}"
ensure_dir_exists "${XDG_CONFIG_HOME}"
ensure_dir_exists "${XDG_DATA_HOME}"
ensure_dir_exists "${XDG_STATE_HOME}"
############################
# Disable macos gatekeeper #
############################
# section_header 'Disabling macos gatekeeper'
# sudo spectl --master-disable
#####################
# Install oh-my-zsh #
#####################
section_header "Installing oh-my-zsh into '$(yellow "${HOME}/.oh-my-zsh")'"
if ! is_directory "${HOME}/.oh-my-zsh"; then
sh -c "$(ZSH= curl -fsSL https://install.ohmyz.sh/)" "" --unattended
success "Successfully installed oh-my-zsh into '$(yellow "${HOME}/.oh-my-zsh")'"
else
warn "skipping installation of oh-my-zsh since '$(yellow "${HOME}/.oh-my-zsh")' is already present"
fi
##############################
# Install custom omz plugins #
##############################
# Note: Some of these are available via brew, but enabling them will take an additional step and the only other benefit (of keeping them up-to-date using brew can still be achieved by updating the git repos directly)
section_header 'Installing custom omz plugins'
# Note: These are not installed using homebrew since sourcing of the files needs to be explicit in .zshrc
# Also, the order of these being referenced in the zsh session startup (for vanilla OS) will cause a warning to be printed though the rest of the shell startup sequence is still performed. Ultimately, until they become included by default into omz, keep them here as custom plugins
clone_omz_plugin_if_not_present https://github.com/zdharma-continuum/fast-syntax-highlighting
clone_omz_plugin_if_not_present https://github.com/zsh-users/zsh-autosuggestions
clone_omz_plugin_if_not_present https://github.com/zsh-users/zsh-completions
####################
# Install dotfiles #
####################
section_header "Installing dotfiles into '$(yellow "${DOTFILES_DIR}")'"
if is_non_zero_string "${DOTFILES_DIR}" && ! is_git_repo "${DOTFILES_DIR}"; then
# Delete the auto-generated .zshrc since that needs to be replaced by the one in the DOTFILES_DIR repo
rm -rf "${ZDOTDIR}/.zshrc"
# Note: Cloning with https since the ssh keys will not be present at this time
clone_repo_into "https://github.com/${GH_USERNAME}/dotfiles" "${DOTFILES_DIR}" "${DOTFILES_BRANCH}"
# Use the https protocol for pull, but use ssh/git for push
git -C "${DOTFILES_DIR}" config url.ssh://[email protected]/.pushInsteadOf https://github.com/
append_to_path_if_dir_exists "${DOTFILES_DIR}/scripts"
# Setup the DOTFILES_DIR repo's upstream if it doesn't already point to UPSTREAM_GH_USERNAME's repo
add-upstream-git-config.sh "${DOTFILES_DIR}" "${UPSTREAM_GH_USERNAME}"
install-dotfiles.rb
else
warn "skipping cloning the dotfiles repo since '$(yellow "${DOTFILES_DIR}")' is either not defined or is already a git repo"
fi
# Setup any sudo access password from cmd-line to also invoke the gui touchId prompt
approve-fingerprint-sudo.sh
# Load all zsh config files for PATH and other env vars to take effect
FIRST_INSTALL=true load_zsh_configs
####################
# Install homebrew #
####################
section_header "Installing homebrew into '$(yellow "${HOMEBREW_PREFIX}")'"
! is_non_zero_string "${HOMEBREW_PREFIX}" && error "'HOMEBREW_PREFIX' env var is not set; something is wrong. Please correct before retrying!"
if ! command_exists brew; then
# Prep for installing homebrew
sudo mkdir -p "${HOMEBREW_PREFIX}/tmp" "${HOMEBREW_PREFIX}/repository" "${HOMEBREW_PREFIX}/plugins" "${HOMEBREW_PREFIX}/bin"
sudo chown -fR "$(whoami)":admin "${HOMEBREW_PREFIX}"
chmod u+w "${HOMEBREW_PREFIX}"
NONINTERACTIVE=1 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
success 'Successfully installed homebrew'
eval "$(${HOMEBREW_PREFIX}/bin/brew shellenv)"
else
warn "skipping installation of $(yellow 'homebrew') since it's already installed"
fi
# TODO: Need to investigate why this step exits on a vanilla OS's first run of this script
# Note: Do not set the 'HOMEBREW_BASE_INSTALL' in this script - since its supposed to run idempotently. Also, don't run the cleanup of pre-installed brews/casks (for the same reason)
brew bundle check || brew bundle || true
success 'Successfully installed cmd-line and gui apps using homebrew'
# Note: Load all zsh config files for the 2nd time for PATH and other env vars to take effect (due to defensive programming)
load_zsh_configs
if is_non_zero_string "${KEYBASE_USERNAME}"; then
! command_exists keybase && error 'Keybase not found in the PATH. Aborting!!!'
######################
# Login into keybase #
######################
section_header 'Logging into keybase'
! keybase login && error 'Could not login into keybase. Retry after logging in.'
#######################
# Clone the home repo #
#######################
section_header 'Cloning home repo'
if is_non_zero_string "${KEYBASE_HOME_REPO_NAME}"; then
clone_repo_into "$(build_keybase_repo_url "${KEYBASE_HOME_REPO_NAME}")" "${HOME}"
# Reset ssh keys' permissions so that git doesn't complain when using them
set_ssh_folder_permissions
# Fix /etc/hosts file to block facebook
is_file "${PERSONAL_CONFIGS_DIR}/etc.hosts" && sudo cp "${PERSONAL_CONFIGS_DIR}/etc.hosts" /etc/hosts
else
warn "skipping cloning of home repo since the '$(yellow 'KEYBASE_HOME_REPO_NAME')' env var hasn't been set"
fi
###########################
# Clone the profiles repo #
###########################
section_header 'Cloning profiles repo'
if is_non_zero_string "${KEYBASE_PROFILES_REPO_NAME}" && is_non_zero_string "${PERSONAL_PROFILES_DIR}"; then
clone_repo_into "$(build_keybase_repo_url "${KEYBASE_PROFILES_REPO_NAME}")" "${PERSONAL_PROFILES_DIR}"
# Clone the natsumi-browser repo into the ZenProfile/Profiles/DefaultProfile/chrome folder and switch to the 'dev' branch
local folder="${PERSONAL_PROFILES_DIR}/ZenProfile"
if is_directory "${folder}"; then
clone_repo_into "[email protected]:${UPSTREAM_GH_USERNAME}/natsumi-browser" "${folder}/Profiles/DefaultProfile/chrome" dev
else
warn "skipping cloning of natsumi repo into the zen chrome folder since the folder '$(yellow "${folder}/Profiles")' doesn't exist"
fi
unset folder
# HACK: To fix issue where someone does not have any such 'DefaultProfile/chrome'.... (need to find a correct fix)
# otherwise, the next 'for' loop fails and errors out
ensure_dir_exists "${PERSONAL_PROFILES_DIR}/DummyProfile/Profiles/DefaultProfile/chrome"
for folder in "${PERSONAL_PROFILES_DIR}"/*Profile/Profiles/DefaultProfile/chrome; do
# Setup the chrome repo's upstream if it doesn't already point to UPSTREAM_GH_USERNAME's repo
add-upstream-git-config.sh "${folder}" "${UPSTREAM_GH_USERNAME}"
done
unset folder
rm -rf "${PERSONAL_PROFILES_DIR}/DummyProfile/"
else
warn "skipping cloning of profiles repo since either the '$(yellow 'KEYBASE_PROFILES_REPO_NAME')' or the '$(yellow 'PERSONAL_PROFILES_DIR')' env var hasn't been set"
fi
else
warn "skipping cloning of any keybase repo since '$(yellow 'KEYBASE_USERNAME')' has not been set"
fi
if is_non_zero_string "${PERSONAL_CONFIGS_DIR}"; then
########################################################
# Generate the repositories-oss.yml fie if not present #
########################################################
file_name="${PERSONAL_CONFIGS_DIR}/repositories-oss.yml"
section_header "Generating ${file_name}"
if ! is_file "${file_name}"; then
ensure_dir_exists "$(dirname "${file_name}")"
cat <<EOF > "${file_name}"
- folder: "\${PROJECTS_BASE_DIR}/oss/git_scripts"
remote: [email protected]:${UPSTREAM_GH_USERNAME}/git_scripts
active: true
EOF
success "Successfully generated '$(yellow "${file_name}")'"
else
warn "skipping generation of '$(yellow "${file_name}")' since it already exists"
fi
unset file_name
##################################################
# Resurrect repositories that I am interested in #
##################################################
section_header 'Resurrecting repos'
for file in $(ls "${PERSONAL_CONFIGS_DIR}"/repositories-*.yml); do
resurrect-repositories.rb -r "${file}"
done
unset file
success 'Successfully resurrected all tracked git repos'
else
warn "skipping resurrecting of repositories since '$(yellow "${PERSONAL_CONFIGS_DIR}")' doesn't exist"
fi
############################################################
# post-clone operations for installing system dependencies #
############################################################
section_header 'Running post-clone operations'
if command_exists all; then
all restore-mtime -c
all maintenance register --config-file "${HOME}/.gitconfig-oss.inc"
all maintenance start
fi
if command_exists allow_all_direnv_configs; then
allow_all_direnv_configs
else
warn "skipping registering all direnv configs since '$(yellow 'allow_all_direnv_configs')' couldn't be found in the PATH; Please run it manually"
fi
if command_exists install_mise_versions; then
install_mise_versions
else
warn "skipping installation of languages since '$(yellow 'install_mise_versions')' couldn't be found in the PATH; Please run it manually"
fi
rm -rf "${HOME}/.ssh/known_hosts.old"
#####################################################################################
# Load the direnv config for the home folder so that it creates necessary sym-links #
#####################################################################################
ensure_safe_load_direnv "${HOME}"
#########################################################################################
# Load the direnv config for the profiles folder so that it creates necessary sym-links #
#########################################################################################
ensure_safe_load_direnv "${PERSONAL_PROFILES_DIR}"
###################################################################
# Restore the preferences from the older machine into the new one #
###################################################################
section_header 'Restore preferences'
if command_exists 'osx-defaults.sh'; then
osx-defaults.sh -s
success 'Successfully baselines preferences'
else
warn "skipping baselining of preferences since '$(yellow 'osx-defaults.sh')' couldn't be found in the PATH; Please baseline manually and follow it up with re-import of the backed-up preferences"
fi
if command_exists 'capture-defaults.sh'; then
capture-defaults.sh i
success 'Successfully restored preferences from backup'
else
warn "skipping importing of preferences since '$(yellow 'capture-defaults.sh')' couldn't be found in the PATH; Please set it up manually"
fi
################################
# Recreate the zsh completions #
################################
section_header 'Recreate zsh completions'
rm -rf "${XDG_CACHE_HOME}/zcompdump-${ZSH_VERSION}"
autoload -Uz compinit && compinit -C -d "${XDG_CACHE_HOME}/zcompdump-${ZSH_VERSION}"
###################
# Setup cron jobs #
###################
section_header 'Setup cron jobs'
if command_exists recron; then
recron
success 'Successfully setup cron jobs'
else
warn "skipping setting up of cron jobs since '$(yellow 'recron')' couldn't be found in the PATH; Please set it up manually"
fi
###############################
# Cleanup temp functions, etc #
###############################
unfunction clone_omz_plugin_if_not_present
unfunction ensure_safe_load_direnv
# To install the latest versions of the hex, rebar and phoenix packages
# mix local.hex --force && mix local.rebar --force
# mix archive.install hex phx_new 1.4.1
# To install the native-image tool after graalvm is installed
# gu install native-image
# Enabling history for iex shell (might need to be done for each erl that is installed via mise)
# rm -rf tmp
# ensure_dir_exists tmp
# cd tmp || exit
# git clone https://github.com/ferd/erlang-history.git
# cd erlang-history || exit
# sudo make install
# cd ../.. || exit
# rm -rf tmp
# vagrant plugin install vagrant-vbguest
# if installing jhipster for dot-net-core
# TODO: Use the next line since the released version is only for .net 2.2:
# npm i -g generator-jhipster-dotnetcore
# Note: '-g' didnt work. Had to do 'npm init' and then use '--save-dev' to install and link as a local dependency
# npm i -g jhipster/jhipster-dotnetcore
# npm link generator-jhipster-dotnetcore
# jhipster -d --blueprints dotnetcore
# Default tooling for dotnet projects
# dotnet tool install -g dotnet-sonarscanner
# dotnet tool install -g dotnet-format
echo "\n"
success '** Finished auto installation process: Remember to do the following steps! **'
echo "$(yellow "1. set the 'RAYCAST_SETTINGS_PASSWORD' env var, and then run the 'capture-raycast-configs.sh' script to import your Raycast configuration into the new machine.")"
echo "$(yellow "2. Run the 'bupc' alias to finish setting up all other applications managed by homebrew")"
echo "$(yellow "3. MANUALLY QUIT AND RESTART iTerm2 and Terminal apps")"
script_end_time=$(date +%s)
echo "==> Script completed at: $(date)"
echo "==> Total execution time: $((script_end_time - script_start_time)) seconds"