├── bin
├── quality
└── setup
├── modules
├── osx_update.bash
├── projectdir.bash
├── dotfiles.bash
├── osx_security.bash
├── ssh.bash
├── osx_version.bash
├── ruby.bash
├── node.bash
├── functions.bash
├── brew.bash
└── osx_defaults.bash
├── Brewfile
├── .semaphore
└── semaphore.yml
└── README.md
/bin/quality:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | shellcheck --shell bash --exclude=SC1090,SC2086 modules/* bin/setup
6 |
--------------------------------------------------------------------------------
/modules/osx_update.bash:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)"
4 | source "$osx_bootstrap/modules/functions.bash"
5 |
6 | info_echo "Running OS X Software updates"
7 | sudo softwareupdate -i -a
8 |
--------------------------------------------------------------------------------
/modules/projectdir.bash:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)"
4 | source "$osx_bootstrap/modules/functions.bash"
5 |
6 | if ! test -e ~/src ; then
7 | info_echo "Setup project directory at ~/src (also linked from ~/Develop and ~/Projects"
8 | mkdir ~/src
9 | ln -s ~/src ~/Develop
10 | ln -s ~/src ~/Projects
11 | fi
12 |
--------------------------------------------------------------------------------
/modules/dotfiles.bash:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)"
4 | source "$osx_bootstrap/modules/functions.bash"
5 |
6 | info_echo "Installing bash dotfiles to ~/.dotfiles"
7 |
8 | if [ ! -d ~/.dotfiles ]; then
9 | git clone https://github.com/fs/dotfiles.git ~/.dotfiles
10 | (
11 | cd ~/.dotfiles|| exit
12 | bash script/setup
13 | )
14 | fi
15 |
--------------------------------------------------------------------------------
/modules/osx_security.bash:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)"
4 | source "$osx_bootstrap/modules/functions.bash"
5 |
6 | info_echo "Expose hidden files and Library folder in Finder"
7 | defaults write com.apple.finder AppleShowAllFiles -bool true
8 | chflags nohidden ~/Library
9 |
10 | info_echo "Empty Trash securely by default"
11 | defaults write com.apple.finder EmptyTrashSecurely -bool true
12 |
--------------------------------------------------------------------------------
/modules/ssh.bash:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)"
4 | source "$osx_bootstrap/modules/functions.bash"
5 |
6 | info_echo "Checking for SSH key, generating one if it doesn't exist"
7 | [[ -f ~/.ssh/id_rsa.pub ]] || ssh-keygen -t rsa
8 |
9 | info_echo "Copying public key to clipboard. Paste it into your Github account"
10 | [[ -f ~/.ssh/id_rsa.pub ]] && pbcopy < ~/.ssh/id_rsa.pub
11 | open https://github.com/account/ssh
12 |
--------------------------------------------------------------------------------
/modules/osx_version.bash:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)"
4 | source "$osx_bootstrap/modules/functions.bash"
5 |
6 | required_osx_version="10.15.3"
7 | osx_version=$(/usr/bin/sw_vers -productVersion)
8 |
9 | info_echo "Checking OS X version"
10 | if [ "$(version "$osx_version")" -lt "$(version "$required_osx_version")" ]; then
11 | error_echo "Your OS X $osx_version version is older then required $required_osx_version version. Exiting"
12 | exit
13 | fi
14 |
--------------------------------------------------------------------------------
/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | OSX_BOOTSTRAP=${OSX_BOOTSTRAP:-"$HOME/.osx-bootstrap"}
6 |
7 | if [ ! -d "$OSX_BOOTSTRAP" ]
8 | then
9 | git clone -b master https://github.com/fs/osx-bootstrap.git "$OSX_BOOTSTRAP"
10 | fi
11 |
12 | modules=(
13 | osx_version
14 | osx_update
15 | projectdir
16 | ssh
17 | brew
18 | ruby
19 | node
20 | osx_defaults
21 | osx_security
22 | dotfiles
23 | )
24 |
25 | for module in "${modules[@]}"
26 | do
27 | bash "$OSX_BOOTSTRAP/modules/$module.bash"
28 | done
29 |
30 |
--------------------------------------------------------------------------------
/modules/ruby.bash:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)"
6 | source "$osx_bootstrap/modules/functions.bash"
7 |
8 | if test ! "$(command -v rbenv)"
9 | then
10 | info_echo 'Installing rbenv'
11 | # shellcheck disable=SC2016
12 | [ -f "$HOME/.zshrc" ] && echo 'eval "$(rbenv init -)"' >> ~/.zshrc
13 | brew install rbenv
14 | eval "$(rbenv init -)"
15 | /bin/bash -c "curl -fsSL https://github.com/rbenv/rbenv-installer/raw/main/bin/rbenv-doctor | bash"
16 | else
17 | info_echo "Rbenv already installed"
18 | fi
19 |
--------------------------------------------------------------------------------
/modules/node.bash:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)"
4 | source "$osx_bootstrap/modules/functions.bash"
5 |
6 | info_echo "Enable NVM alias"
7 | # we need disable -e during sourcing nvm.sh b/c of
8 | # https://github.com/creationix/nvm/issues/721
9 | # https://github.com/travis-ci/travis-ci/issues/3854#issuecomment-99492695
10 | set +e
11 | # shellcheck disable=SC1091
12 | source "$(brew --prefix nvm)/nvm.sh"
13 |
14 | set -e
15 |
16 | if test -n "$(nvm ls|grep "node"|grep "N/A")"; then
17 | info_echo "Install latest Node.js version"
18 | nvm install node
19 | fi
20 |
21 | info_echo "Set latest Node.js version as global default Node"
22 | nvm use node
23 | nvm alias default node
24 |
--------------------------------------------------------------------------------
/modules/functions.bash:
--------------------------------------------------------------------------------
1 | export HOMEBREW_CASK_OPTS="--appdir=/Applications"
2 | #export RBENV_ROOT=/usr/local/var/rbenv
3 | #export NVM_DIR=/usr/local/var/nvm
4 |
5 | red=$(tput setaf 1)
6 | green=$(tput setaf 2)
7 | color_reset=$(tput sgr0)
8 |
9 | error_echo() {
10 | printf "\\n${red}%s.${color_reset}\\n" "$1"
11 | }
12 |
13 | info_echo() {
14 | printf "\\n${green}%s ...${color_reset}\\n" "$1"
15 | }
16 |
17 | version() {
18 | echo "$@" | awk -F. '{ printf("%d%03d%03d%03d", $1,$2,$3,$4); }'
19 | }
20 |
21 | catch_exit() {
22 | ret=$?
23 | test $ret -ne 0 && error_echo "Installation fails" >&2
24 | exit $ret
25 | }
26 |
27 | # Catch exit
28 | trap catch_exit EXIT
29 |
30 | # Setup logging
31 | exec > >(tee -i "$HOME/.osx-bootstrap.$(date +%Y-%m-%d-%H-%M-%S).log")
32 | exec 2>&1
33 |
--------------------------------------------------------------------------------
/modules/brew.bash:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)"
4 | source "$osx_bootstrap/modules/functions.bash"
5 | export PATH="/opt/homebrew/bin:$PATH"
6 |
7 | # shellcheck disable=SC2016
8 | [ -f "$HOME/.zprofile" ] && echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
9 |
10 | if test ! "$(command -v brew)"; then
11 | info_echo "Install Homebrew, a good OS X package manager"
12 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
13 | else
14 | info_echo "Update Homebrew"
15 | brew update
16 | fi
17 |
18 | info_echo "Install Brew formalue"
19 |
20 | brew tap "Homebrew/bundle" 2> /dev/null
21 | brew bundle install --file="$osx_bootstrap/Brewfile"
22 |
23 | info_echo "Remove outdated versions from the cellar"
24 |
25 | brew cleanup
26 |
--------------------------------------------------------------------------------
/Brewfile:
--------------------------------------------------------------------------------
1 | # Make sure you have following env variables
2 | # when using this Brewfile or use it with modules/brew.bash
3 | #
4 | HOMEBREW_CASK_OPTS="--appdir=/Applications"
5 | # RBENV_ROOT=/usr/local/var/rbenv
6 | # NVM_DIR=/usr/local/var/nvm
7 |
8 | tap "heroku/brew"
9 |
10 | brew "git"
11 | brew "heroku"
12 | brew "imagemagick"
13 | brew "nvm"
14 | brew "openssl"
15 | brew "postgresql", restart_service: true
16 | brew "rbenv"
17 | brew "rbenv-default-gems"
18 | brew "readline", link: true
19 | brew "redis", restart_service: true
20 | brew "ruby-build"
21 | brew "ssh-copy-id"
22 | brew "tmux"
23 | brew "watch"
24 | brew "yarn"
25 | brew "z"
26 |
27 | cask "chromedriver"
28 | cask "google-chrome"
29 | cask "graphiql"
30 | cask "iterm2"
31 | cask "postman"
32 | cask "slack"
33 | cask "the-unarchiver"
34 | cask "visual-studio-code"
35 | cask "zoom"
36 | cask "sublime-text"
37 | cask "1password"
38 |
--------------------------------------------------------------------------------
/.semaphore/semaphore.yml:
--------------------------------------------------------------------------------
1 | # For more Swift information and examples, see:
2 | # https://docs.semaphoreci.com/article/139-language-swift
3 | version: v1.0
4 | name: OSX Bootstrap
5 |
6 | agent:
7 | machine:
8 | type: a1-standard-4
9 | os_image: macos-xcode12
10 |
11 | execution_time_limit:
12 | hours: 1
13 |
14 | auto_cancel:
15 | queued:
16 | when: 'true'
17 |
18 | blocks:
19 | - name: Test
20 | task:
21 | env_vars:
22 | - name: HOMEBREW_NO_AUTO_UPDATE
23 | value: "true"
24 |
25 | prologue:
26 | commands:
27 | - checkout
28 |
29 | jobs:
30 | - name: quality
31 | commands:
32 | - brew install shellcheck
33 | - bin/quality
34 |
35 | - name: workspace
36 | commands:
37 | - modules/projectdir.bash
38 |
39 | - name: dev
40 | commands:
41 | - modules/brew.bash
42 | - modules/ruby.bash
43 | # Disable node test since need to update
44 | # - modules/node.bash
45 |
46 | - name: osx
47 | commands:
48 | - modules/osx_version.bash
49 | - modules/osx_defaults.bash
50 | - modules/osx_security.bash
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OS X Bootstrap
2 |
3 | Script to set up a macOS X for Rails development.
4 |
5 | ## Requirements
6 |
7 | macOS X version >= 10.15
8 |
9 | ## Install
10 |
11 | Run the setup script which will clone repository to `~/.osx-bootstrap` directory
12 | and run `~/.osx-bootstrap/modules/*` scripts.
13 |
14 | ```bash
15 | bash <(curl -s https://raw.githubusercontent.com/fs/osx-bootstrap/master/bin/setup)
16 | ```
17 |
18 | Or you can run each module script one-by-one:
19 |
20 | ```bash
21 | git clone -b master https://github.com/fs/osx-bootstrap.git
22 | ~/.osx-bootstrap/modules/osx_defaults.bash
23 | ```
24 |
25 | ## What it sets up
26 |
27 | * OS X Command Line Tools
28 | * SSH keys
29 | * **Homebrew** for managing operating system libraries (OS X only)
30 | * **git** source code management system
31 | * **Postgresql** for storing relational data
32 | * **Redis** for storing key-value data
33 | * **ImageMagick** for cropping and resizing images
34 | * **watch** for periodically executing a program and displaying the output
35 | * **[Z](https://github.com/rupa/z)** (jump around) for a faster way to navigate your filesystem
36 | * **ssh-copy-id** to deliver your public key in a remote machine's authorized_keys
37 | * **Heroku Toolbelt** for interacting with the Heroku API
38 | * **tmux** for saving project state and switching between projects
39 | * **rbenv** for managing versions of the Ruby programming language in the `/usr/local/var/rbenv`
40 | * **ruby-build** for installing Ruby versions
41 | * **Ruby** programming language, latest stable version
42 | * **NVM** for managing versions of the Node.js
43 | * **Node.js** stable for writing JavaScript general-purpose code
44 | * Software installed with Brew Cask in to `/Applications`:
45 | * Google Chrome
46 | * ChromeDriver
47 | * GraphiQL
48 | * iTerm2
49 | * Java
50 | * Postman
51 | * Skype
52 | * Slack
53 | * Spectacle
54 | * Sublime Text 3
55 | * The Unarchiver
56 | * Visual Studio Code
57 | * Zoom
58 | * Set OS X defaults (faster animation, security settings etc)
59 |
60 | ## Credits
61 |
62 | OS X Bootstrap is maintained by [Timur Vafin](http://github.com/timurvafin).
63 | It was written by [Flatstack](http://www.flatstack.com) with the help of our
64 | [contributors](http://github.com/fs/osx-bootstrap/contributors).
65 |
66 | [
](http://www.flatstack.com)
67 |
--------------------------------------------------------------------------------
/modules/osx_defaults.bash:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)"
4 | source "$osx_bootstrap/modules/functions.bash"
5 |
6 | info_echo "Set OS X defaults"
7 |
8 | ###############################################################################
9 | # General UI/UX #
10 | ###############################################################################
11 |
12 | # Set computer name (as done via System Preferences → Sharing)
13 | hostname=$(whoami)
14 | sudo scutil --set ComputerName "$hostname"
15 | sudo scutil --set HostName "$hostname"
16 | sudo scutil --set LocalHostName "$hostname"
17 | sudo defaults write /Library/Preferences/SystemConfiguration/com.apple.smb.server NetBIOSName -string "$hostname"
18 |
19 | # Disable the sound effects on boot
20 | sudo nvram SystemAudioVolume=" "
21 |
22 | # Menu bar: hide icons
23 | for domain in ~/Library/Preferences/ByHost/com.apple.systemuiserver.*; do
24 | defaults write "${domain}" dontAutoLoad -array \
25 | "/System/Library/CoreServices/Menu Extras/TimeMachine.menu" \
26 | "/System/Library/CoreServices/Menu Extras/Volume.menu" \
27 | "/System/Library/CoreServices/Menu Extras/Bluetooth.menu" \
28 | "/System/Library/CoreServices/Menu Extras/AirPort.menu" \
29 | "/System/Library/CoreServices/Menu Extras/User.menu"
30 | done
31 |
32 | ###############################################################################
33 | # Trackpad, mouse, keyboard, Bluetooth accessories, and input #
34 | ###############################################################################
35 |
36 | # Disable “natural” (Lion-style) scrolling
37 | defaults write NSGlobalDomain com.apple.swipescrolldirection -bool false
38 |
39 | # Set language and text formats
40 | defaults write NSGlobalDomain AppleLanguages -array "en" "ru"
41 | defaults write NSGlobalDomain AppleLocale -string "ru_RU@currency=RUB"
42 | defaults write NSGlobalDomain AppleMeasurementUnits -string "Centimeters"
43 | defaults write NSGlobalDomain AppleMetricUnits -bool true
44 |
45 | # Accelerate cursor
46 | defaults write NSGlobalDomain KeyRepeat -int 0
47 |
48 | # Disable auto-correct
49 | defaults write NSGlobalDomain NSAutomaticSpellingCorrectionEnabled -bool false
50 |
51 | # Enable full keyboard access for all controls
52 | # (e.g. enable Tab in modal dialogs)
53 | defaults write NSGlobalDomain AppleKeyboardUIMode -int 3
54 |
55 | ###############################################################################
56 | # Finder #
57 | ###############################################################################
58 |
59 | # Finder: disable window animations and Get Info animations
60 | defaults write com.apple.finder DisableAllAnimations -bool true
61 |
62 | # Finder: show all filename extensions
63 | defaults write NSGlobalDomain AppleShowAllExtensions -bool true
64 |
65 | # Finder: show status bar
66 | defaults write com.apple.finder ShowStatusBar -bool true
67 |
68 | # Finder: show path bar
69 | defaults write com.apple.finder ShowPathbar -bool true
70 |
71 | # Display full POSIX path as Finder window title
72 | defaults write com.apple.finder _FXShowPosixPathInTitle -bool true
73 |
74 | # When performing a search, search the current folder by default
75 | defaults write com.apple.finder FXDefaultSearchScope -string "SCcf"
76 |
77 | # Disable the warning when changing a file extension
78 | defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false
79 |
80 | # Avoid creating .DS_Store files on network volumes
81 | defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true
82 |
83 | # Use list view in all Finder windows by default
84 | # Four-letter codes for the other view modes: `icnv`, `clmv`, `Flwv`
85 | defaults write com.apple.Finder FXPreferredViewStyle Nlsv
86 |
87 | # # Disable the warning before emptying the Trash
88 | defaults write com.apple.finder WarnOnEmptyTrash -bool false
89 |
90 | # Enable AirDrop over Ethernet and on unsupported Macs running Lion
91 | defaults write com.apple.NetworkBrowser BrowseAllInterfaces -bool true
92 |
93 | # Set $HOME as the default location for new Finder windows
94 | # For other paths, use `PfLo` and `file:///full/path/here/`
95 | defaults write com.apple.finder NewWindowTarget -string "PfLo"
96 | defaults write com.apple.finder NewWindowTargetPath -string "file://${HOME}"
97 |
98 | ###############################################################################
99 | # Dock, Dashboard, and hot corners #
100 | ###############################################################################
101 |
102 | # Wipe all (default) app icons from the Dock
103 | # This is only really useful when setting up a new Mac, or if you don’t use
104 | # the Dock to launch apps.
105 | defaults write com.apple.dock persistent-apps -array
106 |
107 | # Add applications to Dock
108 | for app in \
109 | System\ Preferences \
110 | Safari \
111 | Slack \
112 | iTerm \
113 | Sublime\ Text
114 | do
115 | defaults write com.apple.dock "persistent-apps" -array-add "tile-datafile-data_CFURLString/Applications/$app.app/_CFURLStringType0"
116 | done
117 |
118 | # Disable Dashboard
119 | defaults write com.apple.dashboard mcx-disabled -bool true
120 |
121 | # Don’t show Dashboard as a Space
122 | defaults write com.apple.dock dashboard-in-overlay -bool true
123 |
124 | # Don’t automatically rearrange Spaces based on most recent use
125 | defaults write com.apple.dock mru-spaces -bool false
126 |
127 | # Make Dock icons of hidden applications translucent
128 | defaults write com.apple.dock showhidden -bool true
129 |
130 | # Turn off dock icons magnification
131 | defaults write com.apple.dock magnification -boolean false
132 |
133 | # Show dock on right
134 | defaults write com.apple.dock orientation -string 'right'
135 |
136 | ###############################################################################
137 | # Safari & WebKit #
138 | ###############################################################################
139 |
140 | # Set Safari’s home page to `about:blank` for faster loading
141 | defaults write com.apple.Safari HomePage -string "about:blank"
142 |
143 | # Prevent Safari from opening ‘safe’ files automatically after downloading
144 | defaults write com.apple.Safari AutoOpenSafeDownloads -bool false
145 |
146 | # Hide Safari’s bookmarks bar by default
147 | defaults write com.apple.Safari ShowFavoritesBar -bool false
148 |
149 | # Show status bar
150 | defaults write com.apple.Safari ShowStatusBar -bool true
151 |
152 | # Hide Safari’s sidebar in Top Sites
153 | defaults write com.apple.Safari ShowSidebarInTopSites -bool false
154 |
155 | # Enable the Develop menu and the Web Inspector in Safari
156 | defaults write com.apple.Safari IncludeDevelopMenu -bool true
157 | defaults write com.apple.Safari WebKitDeveloperExtrasEnabledPreferenceKey -bool true
158 | defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled -bool true
159 |
160 | # Add a context menu item for showing the Web Inspector in web views
161 | defaults write NSGlobalDomain WebKitDeveloperExtras -bool true
162 |
163 | ###############################################################################
164 | # Spotlight #
165 | ###############################################################################
166 |
167 | # Disable Spotlight indexing for any volume that gets mounted and has not yet
168 | # been indexed before.
169 | # Use `sudo mdutil -i off "/Volumes/foo"` to stop indexing any volume.
170 | sudo defaults write /.Spotlight-V100/VolumeConfiguration Exclusions -array "/Volumes"
171 |
172 | # Change indexing order and disable some file types
173 | defaults write com.apple.spotlight orderedItems -array \
174 | '{"enabled" = 1;"name" = "APPLICATIONS";}' \
175 | '{"enabled" = 1;"name" = "SYSTEM_PREFS";}' \
176 | '{"enabled" = 1;"name" = "DIRECTORIES";}' \
177 | '{"enabled" = 1;"name" = "PDF";}' \
178 | '{"enabled" = 1;"name" = "FONTS";}' \
179 | '{"enabled" = 0;"name" = "DOCUMENTS";}' \
180 | '{"enabled" = 0;"name" = "MESSAGES";}' \
181 | '{"enabled" = 0;"name" = "CONTACT";}' \
182 | '{"enabled" = 0;"name" = "EVENT_TODO";}' \
183 | '{"enabled" = 0;"name" = "IMAGES";}' \
184 | '{"enabled" = 0;"name" = "BOOKMARKS";}' \
185 | '{"enabled" = 0;"name" = "MUSIC";}' \
186 | '{"enabled" = 0;"name" = "MOVIES";}' \
187 | '{"enabled" = 0;"name" = "PRESENTATIONS";}' \
188 | '{"enabled" = 0;"name" = "SPREADSHEETS";}' \
189 | '{"enabled" = 0;"name" = "SOURCE";}'
190 |
191 | # Make sure indexing is enabled for the main volume
192 | sudo mdutil -i on / > /dev/null
193 |
194 | # Rebuild the index from scratch
195 | sudo mdutil -E / > /dev/null
196 |
197 | ###############################################################################
198 | # Terminal & iTerm 2 #
199 | ###############################################################################
200 |
201 | # Only use UTF-8 in Terminal.app
202 | defaults write com.apple.terminal StringEncodings -array 4
203 |
204 | # Don’t display the annoying prompt when quitting iTerm
205 | defaults write com.googlecode.iterm2 PromptOnQuit -bool false
206 |
207 | ###############################################################################
208 | # Kill affected applications #
209 | ###############################################################################
210 |
211 | for app in "cfprefsd" "Dock" "Finder" "Safari" "SystemUIServer" "iTerm"; do
212 | killall "${app}" > /dev/null 2>&1 || true
213 | done
214 |
--------------------------------------------------------------------------------