OS X: Automated provisioning using Homebrew and Cask

published on in category OS X , Tags: OS X Homebrew

I’m changing my hardware quite frequently as I often end up unsatisfied with my current setup. Setting up a computer from scratch is a pain in the a** but restoring a backup implies carrying around configuration files, useless software and other stuff for years. So I’ve decided to create a script that would set up a new computer from scratch and configure it the way I want it to be.

Using Homebrew and Cask

Today Homebrew is the most widely adopted package manager for OS X and for a good reason: It provides almost any package you could imagine and let’s you manage your apps in a sane manner. What Homebrew provides for command line tools, does Cask for OS X-native graphical applications. Cask has been developed as a plugin for Homebrew but is now integrated right into Homebrew. This is the perfect solution if you want to install all your applications automatically.

The Script

For my needs I created a shell script which set’s my system up just the way I want it to be. There are also other ways, e.g. using Puppet to provision one or more machines. I will release a guide featuring automated provisioning on OS X using Puppet later on. But for now, here’s the script, all necessary comments can be found inline:

#!/bin/bash

# Homebrew requires Xcode CLI tools to be installed. OS X provides stubs for CLI tools
# that trigger the CLI tools installer when called. So we call `git` to start the installation.
git
echo "Press any key when Xcode CLI tools installation is complete..."
read

# Install Homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

# Install CLI apps
brew install hugo unrar npm packer wget p7zip ctags tmux

# Install graphical apps
brew cask install adium caffeine shiftit owncloud dockertoolbox \
                  vlc chromatic iterm2 transmission virtualbox filezilla \
                  virtualbox-extension-pack vagrant rubymine keepassx \
                  teamviewer openoffice skype gpgtools lightpaper openzfs

# Install the vagrant-hostsupdater plugin
vagrant plugin install vagrant-hostsupdater

# Install Gems
sudo gem install avodeploy sass

# Use my dotfiles
cd
git init
git remote add origin https://github.com/dstapp/.dotfiles.git
git pull origin master

# Set ZSH to be the default shell
sudo chsh -s /bin/zsh david

#######################################################################
# Usability enhancements
#######################################################################
#
# Make Dock icons of hidden applications translucent
defaults write com.apple.dock showhidden -bool true
#
# Disable iCloud
defaults write NSGlobalDomain NSDocumentSaveNewDocumentsToCloud -bool NO
sudo defaults write "/System/Library/User Template/Non_localized/Library/Preferences/com.apple.SetupAssistant" DidSeeCloudSetup -bool YES
#
# Enable AppStore debug menu
defaults write com.apple.appstore ShowDebugMenu -bool YES
#
# Disable Photos app to open automatically
defaults -currentHost write com.apple.ImageCapture disableHotPlug -bool YES
#
# Enable shutdown dialog
defaults write com.apple.loginwindow PowerButtonSleepsSystem -bool NO
#
# Accelerated playback on window size adjustment for Cocoa apps
defaults write NSGlobalDomain NSWindowResizeTime -float 0.001
#
# Reduce up safari render delay
defaults write com.apple.Safari WebKitInitialTimedLayoutDelay 0.25
#
# Faster keystroke reactions
defaults write NSGlobalDomain KeyRepeat -int 0
#
# Disable crash reporter
defaults write com.apple.CrashReporter DialogType none
#
# Force Safari to open target links in new tabs
defaults write com.apple.Safari TargetedClicksCreateTabs -bool true
#
# Expand save panel by default
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true
defaults write NSGlobalDomain PMPrintingExpandedStateForPrint -bool true
defaults write NSGlobalDomain PMPrintingExpandedStateForPrint2 -bool true
#
# Quit printer app when job is completed
defaults write com.apple.print.PrintingPrefs "Quit When Finished" -bool true
#
# Disable system-wide resume
defaults write NSGlobalDomain NSQuitAlwaysKeepsWindows -bool false
#
# Disable smart quotes & dashes
defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false
defaults write com.apple.messageshelper.MessageController SOInputLineSettings -dict-add "automaticQuoteSubstitutionEnabled" -bool false
#
# Disable keyboard illumination on 5 minutes standby
defaults write com.apple.BezelServices kDimTime -int 300
#
# Require password after sleep or screensaver
defaults write com.apple.screensaver askForPassword -int 1
defaults write com.apple.screensaver askForPasswordDelay -int 0
#
# Enable subpixel rendering on non-apple lcds
defaults write NSGlobalDomain AppleFontSmoothing -int 2
#
# When performing a search, search the current folder by default
defaults write com.apple.finder FXDefaultSearchScope -string "SCcf"
#
# Enable spring loading for directories
defaults write NSGlobalDomain com.apple.springing.enabled -bool true
#
#
#######################################################################
# Finder
#######################################################################
#
# Automatically open a new Finder window when a volume is mounted
defaults write com.apple.frameworks.diskimages auto-open-ro-root -bool true
defaults write com.apple.frameworks.diskimages auto-open-rw-root -bool true
defaults write com.apple.finder OpenWindowForNewRemovableDisk -bool true
#
# Show status bar
defaults write com.apple.finder ShowStatusBar -bool true
#
# Show path bar
defaults write com.apple.finder ShowPathbar -bool true
#
# Disable disk verification
defaults write com.apple.frameworks.diskimages skip-verify -bool true
defaults write com.apple.frameworks.diskimages skip-verify-locked -bool true
defaults write com.apple.frameworks.diskimages skip-verify-remote -bool true
#
# Show POSIX path as finder window title
defaults write com.apple.finder _FXShowPosixPathInTitle -bool true
#
# Finder status bar originating from $HOME instead of /
defaults write /Library/Preferences/com.apple.finder PathBarRootAtHome -bool YES
#
# Enable AirDrop on all interfaces
defaults write com.apple.NetworkBrowser BrowseAllInterfaces -bool true
#
# Show all file extensions
/usr/bin/defaults write com.apple.finder AppleShowAllExtensions -bool YES
#
# Show icons for hard drives, servers, and removable media on the desktop
defaults write com.apple.finder ShowExternalHardDrivesOnDesktop -bool true
defaults write com.apple.finder ShowHardDrivesOnDesktop -bool true
defaults write com.apple.finder ShowMountedServersOnDesktop -bool true
defaults write com.apple.finder ShowRemovableMediaOnDesktop -bool true
#
# Show warning before changing an extension
/usr/bin/defaults write com.apple.finder FXEnableExtensionChangeWarning -bool YES
#
# Enable snap-to-grid for icons views (desktop & finder)
/usr/libexec/PlistBuddy -c "Set :DesktopViewSettings:IconViewSettings:arrangeBy grid" ~/Library/Preferences/com.apple.finder.plist
/usr/libexec/PlistBuddy -c "Set :FK_StandardViewSettings:IconViewSettings:arrangeBy grid" ~/Library/Preferences/com.apple.finder.plist
/usr/libexec/PlistBuddy -c "Set :StandardViewSettings:IconViewSettings:arrangeBy grid" ~/Library/Preferences/com.apple.finder.plist
#
# 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
chflags nohidden ~/Library
#
# Show the /Volumes folder
sudo chflags nohidden /Volumes
#
# Disable emoji substitution
defaults write com.apple.messageshelper.MessageController SOInputLineSettings -dict-add "automaticEmojiSubstitutionEnablediMessage" -bool false
#
# Disable spell checking
defaults write -g NSAutomaticSpellingCorrectionEnabled -bool false
defaults write NSGlobalDomain WebAutomaticSpellingCorrectionEnabled -bool false
defaults write com.apple.messageshelper.MessageController SOInputLineSettings -dict-add "continuousSpellCheckingEnabled" -bool false
#
# Daily check for software updates
defaults write com.apple.SoftwareUpdate ScheduleFrequency -int 1
#
# Home dir as default finder location
defaults write com.apple.finder NewWindowTarget -string "PfLo"
defaults write com.apple.finder NewWindowTargetPath -string "file://${HOME}/"
#
#
#######################################################################
# Safari
#######################################################################
# Privacy: don’t send search queries to Apple
defaults write com.apple.Safari UniversalSearchEnabled -bool false
defaults write com.apple.Safari SuppressSearchSuggestions -bool true
#
# Press Tab to highlight each item on a web page
defaults write com.apple.Safari WebKitTabToLinksPreferenceKey -bool true
defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2TabsToLinks -bool true
#
# Show the full URL in the address bar (note: this still hides the scheme)
defaults write com.apple.Safari ShowFullURLInSmartSearchField -bool true
#
# Prevent Safari from opening ‘safe’ files automatically after downloading
defaults write com.apple.Safari AutoOpenSafeDownloads -bool false
#
# Disable Safari’s thumbnail cache for History and Top Sites
defaults write com.apple.Safari DebugSnapshotsUpdatePolicy -int 2
#
# Make Safari’s search banners default to Contains instead of Starts With
defaults write com.apple.Safari FindOnPageMatchesWordStartsOnly -bool false
#
# Remove useless icons from Safari’s bookmarks bar
defaults write com.apple.Safari ProxiesInBookmarksBar "()"
#
# Enable the Develop menu and the Web Inspector in Safari
defaults write com.apple.Safari IncludeDevelopMenu -bool true
defaults write com.apple.Safari WebKitDeveloperExtrasEnabledPreferenceKey -bool true
defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled -bool true
#
# Context menu item for safari dev tools
defaults write NSGlobalDomain WebKitDeveloperExtras -bool true
#
#
#######################################################################
# Mail
#######################################################################
#
# Disable send and reply animations in Mail.app
defaults write com.apple.mail DisableReplyAnimations -bool true
defaults write com.apple.mail DisableSendAnimations -bool true
#
# Copy email addresses as `foo@example.com` instead of `Foo Bar <foo@example.com>` in Mail.app
defaults write com.apple.mail AddressesIncludeNameOnPasteboard -bool false
#
# Add the keyboard shortcut ⌘ + Enter to send an email in Mail.app
defaults write com.apple.mail NSUserKeyEquivalents -dict-add "Send" -string "@\\U21a9"
#
# Disable inline attachments (just show the icons)
defaults write com.apple.mail DisableInlineAttachmentViewing -bool true
#
# Disable automatic spell checking
defaults write com.apple.mail SpellCheckingBehavior -string "NoSpellCheckingEnabled"
#
#
#######################################################################
# Dock
#######################################################################
#
# Enable highlight hover effect for the grid view of a stack (Dock)
defaults write com.apple.dock mouse-over-hilite-stack -bool true
#
# Minimize windows into their application’s icon
defaults write com.apple.dock minimize-to-application -bool true
#
# dock tile size
defaults write com.apple.dock tilesize -int 36
#
#
#######################################################################
# Time Machine
#######################################################################
#
# Disable local time machine backups
sudo tmutil disablelocal
#
# Disable time machine selection on new hotplug
defaults write com.apple.TimeMachine DoNotOfferNewDisksForBackup -bool YES
#
# Allow unsupported devices
defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes -bool YES
#
# do not create .DS_Store on network shares
/usr/bin/defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool YES
#
#
########################################################################
# Performance tuning
#######################################################################
#
# Disable animations
defaults write NSGlobalDomain NSAutomaticWindowAnimationsEnabled -bool NO
defaults write -g QLPanelAnimationDuration -float 0
defaults write com.apple.finder DisableAllAnimations -bool YES
defaults write com.apple.dock launchanim -bool NO
defaults write com.apple.mail DisableReplyAnimations -bool YES
defaults write com.apple.mail DisableSendAnimations -bool NO
defaults write com.apple.dock expose-animation-duration -float 0.1
defaults write com.apple.dock "expose-group-by-app" -bool true
#
# Disable dashboard
/usr/bin/defaults write com.apple.dashboard mcx-disabled -bool YES
#
# Don't show Dashboard as a Space
defaults write com.apple.dock dashboard-in-overlay -bool true
#
# Reset Launchpad, but keep the desktop wallpaper intact
find "${HOME}/Library/Application Support/Dock" -name "*-*.db" -maxdepth 1 -delete
#
# Disable sudden motion for ssd
sudo pmset -a sms 0
#
#
########################################################################
# Utilities
#######################################################################
#
# Temrinal: Only use UTF-8 in Terminal.app
defaults write com.apple.terminal StringEncodings -array 4
#
# Enable the debug menu in Address Book
defaults write com.apple.addressbook ABShowDebugMenu -bool true
#
# Enable Dashboard dev mode (allows keeping widgets on the desktop)
defaults write com.apple.dashboard devmode -bool true
#
# Enable the debug menu in iCal (pre-10.8)
defaults write com.apple.iCal IncludeDebugMenu -bool true
#
# Use plain text mode for new TextEdit documents
defaults write com.apple.TextEdit RichText -int 0
#
# Open and save files as UTF-8 in TextEdit
defaults write com.apple.TextEdit PlainTextEncoding -int 4
defaults write com.apple.TextEdit PlainTextEncodingForWrite -int 4
#
# Enable the debug menu in Disk Utility
defaults write com.apple.DiskUtility DUDebugMenuEnabled -bool true
defaults write com.apple.DiskUtility advanced-image-options -bool true
#
# Transmission: Trash original torrent files
defaults write org.m0k.transmission DeleteOriginalTorrent -bool true
#
# Transmission: Hide the donate message
defaults write org.m0k.transmission WarningDonate -bool false

# Transmission: Hide the legal disclaimer
defaults write org.m0k.transmission WarningLegal -bool false
#
#
# Restart Finder & Dock
killall Finder
killall Dock