-
Notifications
You must be signed in to change notification settings - Fork 2
/
provision-mac.sh
executable file
·450 lines (340 loc) · 15.1 KB
/
provision-mac.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
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
#!/usr/bin/env bash
# Note: This script is designed to only be run once, on a completely
# fresh Mac. If you've already done some setup, it might break
# things. It's not idempotent -- not even a little.
# If you're stumbling across this from elsewhere, don't blindly
# run it without understanding what it does.
function timerData() {
echo $1: $SECONDS >> provision_timing.txt
}
# die on errors
set -e
# set up input
exec </dev/tty >/dev/tty
# make sure we're in the right place...
cd "$(dirname "$0")"
DOTFILES_ROOT=$(pwd -P)
date >> provision_timing.txt
timerData "START"
# copy dotfiles
./install_symlinks.sh
# ssh config
mkdir -p -m 700 ~/.ssh
cp resources/ssh_config.base ~/.ssh/config
# Ask for the administrator password
echo "Now we need sudo access to install {(Rosetta),Homebrew,some GUI apps} and change the shell."
sudo -v
still_need_sudo=1
while [ $still_need_sudo -ne 0 ]; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null &
if [[ $(uname -m) == 'arm64' ]]; then
HBBASE=/opt/homebrew
timerData "PRE-ROSETTA"
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
timerData "POST-ROSETTA"
else
HBBASE=/usr/local
timerData "PRE-BREW"
fi
HBBIN=$HBBASE/bin
# install homebrew
export HOMEBREW_NO_ANALYTICS=1
echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
eval $($HBBIN/brew shellenv)
# Turning off quarantine for casks; assuming I trust any apps that
# made it into the Brewfile. *slightly* perilous, though.
HOMEBREW_CASK_OPTS="--no-quarantine" \
$HBBIN/brew bundle install --no-lock --file=$DOTFILES_ROOT/install_lists/Brewfile
# set fish as user shell
targetShell="$HBBIN/fish"
echo $targetShell | sudo tee -a /etc/shells
sudo chsh -s $targetShell $USER
# homebrew doesn't link OpenJDK by default; do it while we still have sudo
sudo ln -sfn $HBBASE/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk
# no more sudo needed!
still_need_sudo=0
sudo -k
# clean up after homebrew
$HBBIN/brew cleanup -s
rm -rf $($HBBIN/brew --cache)
export HOMEBREW_NO_AUTO_UPDATE=0
timerData "POST-BREW"
# make sure we're running in a local git working copy
# (this hooks us in if we were set up from the bootstrap script)
if [[ ! -d .git ]]; then
git init --initial-branch=main
git remote add origin https://github.com/sjml/dotfiles.git
git fetch
git reset origin/main
git branch --set-upstream-to=origin/main main
git checkout .
fi
# swap to ssh; credentials can get added later
git remote set-url origin git@github.com:sjml/dotfiles.git
# Projects folder is where most code stuff lives; link this there, too,
# because otherwise I'll forget where it is
if [[ ! -d ~/Projects/dotfiles ]]; then
mkdir -p -m 700 ~/Projects
ln -s $DOTFILES_ROOT ~/Projects/dotfiles
fi
# any vim bundles
vim +PluginInstall +qall
# make parallel chill
mkdir -p $HOME/.parallel
touch $HOME/.parallel/will-cite
# setup asdf
source $($HBBIN/brew --prefix asdf)/asdf.sh
shimPath="$HOME/.asdf/shims"
asdf plugin add python
asdf plugin add nodejs
asdf plugin add ruby
# copying version check from envup
env_remVer() {
asdf list all $1 2>&1 \
| grep -vE "\s*[a-zA-Z-]" \
| sort -V \
| grep "^\s*$2" \
| tail -1 \
| xargs
}
# python setup
py3version=$(env_remVer python 3)
LDFLAGS="-L$HBBASE/opt/zlib/lib -L$HBBASE/opt/sqlite/lib" \
CPPFLAGS="-I$HBBASE/opt/zlib/include -I$HBBASE/opt/sqlite/include" \
asdf install python $py3version
asdf global python $py3version
asdf reshim python
$shimPath/python3 -m pip install --upgrade pip
$shimPath/pip3 install wheel
$shimPath/pip3 install -r install_lists/python3-dev-packages.txt
asdf reshim python
# asdf install python miniconda3-latest
# asdf global python $py3version $py2version miniconda3-latest
# $shimPath/conda update --all -y
curl -sSL https://install.python-poetry.org/ | $shimPath/python -
$HOME/.local/bin/poetry config virtualenvs.in-project true
timerData "POST-PYTHON"
# ruby setup
rbversion=$(env_remVer ruby 3)
RUBY_CONFIGURE_OPTS="--with-openssl-dir=$($HBBIN/brew --prefix openssl@1.1)" \
asdf install ruby $rbversion
asdf global ruby $rbversion
asdf reshim ruby
$shimPath/gem update --system
yes | $shimPath/gem update
yes | $shimPath/gem install bundler
$shimPath/gem cleanup
timerData "POST-RUBY"
# node setup
nodeversion=$(env_remVer nodejs "\d*[02468]\.")
NODEJS_CHECK_SIGNATURES="no" asdf install nodejs $nodeversion
asdf global nodejs $nodeversion
asdf reshim nodejs
ASDF_SKIP_RESHIM=1 $shimPath/npm install -g npm
ASDF_SKIP_RESHIM=1 $shimPath/npm install -g $(cat install_lists/node-packages.txt)
asdf reshim nodejs
timerData "POST-NODE"
# rust setup
curl https://sh.rustup.rs -sSf | sh -s -- -y --no-modify-path
timerData "POST-RUST"
# set up Terminal
cp ./resources/FiraMod/* $HOME/Library/Fonts/
osascript 2>/dev/null <<EOD
tell application "Terminal"
local allOpenedWindows
local initialOpenedWindows
local windowID
set initialOpenedWindows to id of every window
do shell script "open './resources/SJML.terminal'"
delay 1
set default settings to settings set "SJML"
delay 5
set allOpenedWindows to id of every window
repeat with windowID in allOpenedWindows
if initialOpenedWindows does not contain windowID then
close (every window whose id is windowID)
else
set current settings of tabs of (every window whose id is windowID) to settings set "SJML"
end if
end repeat
end tell
EOD
# let QuickLook stuff run without Gatekeeper complaining
xattr -cr ~/Library/QuickLook/*
qlmanage -r
qlmanage -r cache
# set up default associations
duti ~/.duti
# this will pop a permissions window, but no way around it
# (this is a good thing to have security around, I will agree)
defaultbrowser firefox
# Turn off unneeded menu bar items
defaults -currentHost write dontAutoLoad -array-add "/System/Library/CoreServices/Menu Extras/Displays.menu"
defaults -currentHost write dontAutoLoad -array-add "/System/Library/CoreServices/Menu Extras/Volume.menu"
defaults -currentHost write dontAutoLoad -array-add "/System/Library/CoreServices/Menu Extras/User.menu"
# Clock formatting: with seconds, 12 hr AM/PM, no flashing separators
defaults write com.apple.menuextra.clock DateFormat -string "h:mm:ss a"
defaults write com.apple.menuextra.clock FlashDateSeparators -bool false
# Always show scrollbars
defaults write NSGlobalDomain AppleShowScrollBars -string "Always"
# Text selection in QuickLook
defaults write com.apple.finder QLEnableTextSelection -bool true
# Don't open folders in tabs
defaults write com.apple.finder FinderSpawnTab -bool false
# Set ~ as the default location for new Finder windows
defaults write com.apple.finder NewWindowTarget -string "PfHm"
defaults write com.apple.finder NewWindowTargetPath -string "file://$HOME/"
# Only show icons for *external* hard drives, servers, and removable media on the desktop
defaults write com.apple.finder ShowExternalHardDrivesOnDesktop -bool true
defaults write com.apple.finder ShowHardDrivesOnDesktop -bool false
defaults write com.apple.finder ShowMountedServersOnDesktop -bool true
defaults write com.apple.finder ShowRemovableMediaOnDesktop -bool true
# Don't bug me about using new hard drives for Time Machine
defaults write com.apple.TimeMachine DoNotOfferNewDisksForBackup -bool "true"
# Finder: show all filename extensions
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
# Finder: show status bar
defaults write com.apple.finder ShowStatusBar -bool true
# Finder: show path bar
defaults write com.apple.finder ShowPathbar -bool true
# Finder: turn off delay on proxy icon display (>= Big Sur)
defaults write com.apple.Finder NSToolbarTitleViewRolloverDelay -float 0
# Finder: show proxy icons all the time (>= Monterey)
defaults write com.apple.universalaccess showWindowTitlebarIcons -bool "true"
# When performing a search, search the current folder by default
defaults write com.apple.finder FXDefaultSearchScope -string "SCcf"
# Disable the warning when changing a file extension
defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false
# Avoid creating .DS_Store files on network or USB volumes
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true
defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true
# Use list view in all Finder windows by default
# Four-letter codes for the other view modes: `icnv`, `clmv`, `Flwv`
defaults write com.apple.finder FXPreferredViewStyle -string "Nlsv"
# Show the ~/Library folder
xattr -d com.apple.FinderInfo ~/Library
chflags nohidden ~/Library
# Expand save and print panels by default
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode2 -bool true
defaults write NSGlobalDomain PMPrintingExpandedStateForPrint -bool true
defaults write NSGlobalDomain PMPrintingExpandedStateForPrint2 -bool true
# Save to disk (not to iCloud) by default
defaults write NSGlobalDomain NSDocumentSaveNewDocumentsToCloud -bool false
# Turn off the "feature" where iCloud offloads files you haven't used in a while
defaults write com.apple.bird optimize-storage -int 0
# Automatically quit printer app once the print jobs complete
defaults write com.apple.print.PrintingPrefs "Quit When Finished" -bool true
# disable tap to click
defaults write com.apple.AppleMultitouchTrackpad Clicking -int 0
# enable two-fingered right-click
defaults write com.apple.AppleMultitouchTrackpad TrackpadRightClick -int 1
# disable three-fingered tap for lookup
defaults write com.apple.AppleMultitouchTrackpad TrackpadThreeFingerTapGesture -int 0
# enable three-finger swipe through pages
defaults write com.apple.AppleMultitouchTrackpad TrackpadThreeFingerVertSwipeGesture -int 1
# enable four-finger swipe through fullscreen apps
defaults write com.apple.AppleMultitouchTrackpad TrackpadFourFingerHorizSwipeGesture -int 2
# enable four-finger-swipes for Mission Control and App Expose
defaults write com.apple.dock showMissionControlGestureEnabled -bool true
defaults write com.apple.dock showAppExposeGestureEnabled -bool true
defaults write com.apple.AppleMultitouchTrackpad TrackpadFourFingerVertSwipeGesture -int 2
# enable four-finger spread to show desktop
defaults write com.apple.AppleMultitouchTrackpad TrackpadFourFingerPinchGesture -int 2
defaults write com.apple.AppleMultitouchTrackpad TrackpadFiveFingerPinchGesture -int 2
defaults write com.apple.dock showDesktopGestureEnabled -bool true
# disable Launchpad gesture
defaults write com.apple.dock showLaunchpadGestureEnabled -bool false
# show the app switcher on every monitor
defaults write com.apple.dock appswitcher-all-displays -bool true
# Enable ⌃-Scroll to zoom screen
defaults write com.apple.universalaccess closeViewScrollWheelToggle -bool true
defaults write com.apple.universalaccess HIDScrollZoomModifierMask -int 262144
# Require password 5 minutes after sleep or screen saver begins
defaults write com.apple.screensaver askForPassword -int 1
defaults write com.apple.screensaver askForPasswordDelay -float 300.0
# Set screen saver to Drift (blue) with visible clock
defaults -currentHost write com.apple.screensaver modulePath -string "/System/Library/Screen Savers/Drift.saver"
defaults -currentHost write com.apple.screensaver moduleName -string "Drift"
defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName "Drift" path "/System/Library/Screen Savers/Drift.saver" type 0
defaults -currentHost write com.apple.ScreenSaver.Drift ColorScheme -string "blues"
defaults -currentHost write com.apple.screensaver showClock -bool true
# Disable shadow in screenshots
defaults write com.apple.screencapture disable-shadow -bool true
# Try to re-enable subpixel anti-aliasing post-Mojave
defaults write -g CGFontRenderingFontSmoothingDisabled -bool false
# Disable Dashboard
defaults write com.apple.dashboard mcx-disabled -bool true
# Set the icon size of Dock items to biggest
defaults write com.apple.dock tilesize -int 128
# Automatically hide and show the Dock
defaults write com.apple.dock autohide -bool true
# Don't show recent apps in the Dock
defaults write com.apple.dock show-recents -bool false
# Turn off Dock magnification
defaults write com.apple.dock magnification -bool false
# Allow slow-motion minimize effects when holding down shift (relic from old OS X :D)
defaults write com.apple.dock slow-motion-allowed -bool true
# Move windows with ⌘-⌃-click anywhere in them
defaults write -g NSWindowShouldDragOnGesture -bool true
# Hot corner, bottom-left: Start screen saver
defaults write com.apple.dock wvous-bl-corner -int 5
defaults write com.apple.dock wvous-bl-modifier -int 0
# Don't rearrange spaces based on my random ⌘-tabbing around
defaults write com.apple.dock mru-spaces -bool false
# Add the keyboard shortcut ⌘ + Enter to send an email in Mail.app
defaults write com.apple.mail NSUserKeyEquivalents -dict-add "Send" "@\U21a9"
# Enable the automatic update check
defaults write com.apple.SoftwareUpdate AutomaticCheckEnabled -bool true
# Check for software updates daily, not just once per week
defaults write com.apple.SoftwareUpdate ScheduleFrequency -int 1
# Download newly available updates in background
defaults write com.apple.SoftwareUpdate AutomaticDownload -int 1
# Do not automatically update apps
defaults write com.apple.commerce AutoUpdate -bool false
# Install System data files & security updates
defaults write com.apple.SoftwareUpdate CriticalUpdateInstall -int 1
# Set archive utility to not open a new window when it extracts things
defaults write com.apple.archiveutility dearchive-reveal-after -int 0
# Have Xcode remember which project I had open last
defaults write com.apple.dt.Xcode NSQuitAlwaysKeepsWindows -bool true
# UGH ads in Xcode? The very name of this setting should be a source of shame to someone at Apple
defaults write com.apple.dt.Xcode XcodeCloudUpsellPromptEnabled -bool false
# Set up Dock
dockutil --remove all --no-restart
declare -a dockList=(\
/Applications/Firefox.app \
/System/Applications/Mail.app \
/System/Applications/Messages.app \
/Applications/WhatsApp.app \
/System/Applications/Calendar.app \
/Applications/Overcast.app \
/System/Applications/Music.app \
/System/Applications/Photos.app \
/Applications/Pixelmator\ Pro.app \
/Applications/Affinity\ Designer\ 2.app \
/Applications/Zotero.app \
/Applications/Sublime\ Text.app \
/Applications/Visual\ Studio\ Code.app \
/Applications/Xcode.app \
/System/Applications/Utilities/Terminal.app \
/System/Applications/System\ Preferences.app \
)
for app in "${dockList[@]}"; do
dockutil --add "$app" --no-restart
done
dockutil --add "~/Downloads" --section others --view grid --display stack --no-restart
# Make iCloud Drive documents somewhat findable from the command line
ln -s $HOME/Library/Mobile\ Documents/com~apple~CloudDocs $HOME/iCloudDocs
# killall complains if there's no instances running, so ignore it
# (and don't error)
killall cfprefsd 2> /dev/null || true
killall SystemUIServer 2> /dev/null || true
killall Finder 2> /dev/null || true
killall Dock 2> /dev/null || true
killall Mail 2> /dev/null || true
timerData "POST-GUI"
timerData "DONE"
cd ~
echo
echo
echo "And that's it! You're good to go, but restarting might be wise."