This project turns a new (or factory reset) MacBook into a fully installed and fully configured development machine.
Up and running within 30 minutes!
It is based on dotbot.
Before you start using it you may want to know what it does.
NB: This project focuses on Java / JavaScript / Python development. But you can easilly tailor it to your needs.
- internet connection
- credentials
- Apple ID (iCloud & App Store)
- 1Password
- terminal
- preferences > profiles
- choose 'Pro' and make it the default
- Text > Background: opacity 100%
- preferences > profiles
- System Settings
- Bluetooth: Connect wireless mouse and keyboard
- Trackpad > Scroll & Zoom: Uncheck 'Natural Scrolling'
- Fresh macOS install (optional):
- M1 chip: Use the
Erase All Content and Settings
wizard from theSystem Preferences
menu bar.
- M1 chip: Use the
- Install Xcode Command Line Utilities (required by git & homebrew):
xcode-select --install
- Install & execute the .dotfiles project:
This will trigger Dotbot to perform all the steps described in install.conf.yaml.
git clone https://github.com/roelfie/dotfiles.git ~/.dotfiles cd ~/.dotfiles ./install
NB: If this issue #19 still not resolved you may have to place back the 'mas' entries to Brewfile
(either manually, or by reverting 0d56700) before installing.
NB: The installation scripts are idempotent so you can run ~/.dotfiles/install
as many times as you wish.
- Setup bookkeeper as a background job
- System Preferences:
- BlueTooth: pair keyboard, phone & headphone
- Keyboard: Use F1, F2, etc. as standard function keys
- Alfred key bindings:
app menu hotkey value System Preferences Keyboard → Shortcuts → Spotlight Show Spotlight search ^ Space
System Preferences Keyboard → Shortcuts → Spotlight Show Finder search window ⌥ Space
Alfred General Alfred Hotkey ⌘ Space
Alfred Features Clipboard History ⌥ ⌘ C
Alfred Features Snippets ⌥ ⌘ S
- Configure the menu bar:
- Configure the JetBrains Toolbox:
NB: All JetBrains applications should be installed from the JetBrains Toolbox. Do not install them with Homebrew / cask.
Before we dive into the details, let's have a look at a diagram:
Each MacBook comes with pre-installed software:
- in
/bin
: cat, ls, rm, zsh, .. - in
/usr/bin
: git, grep, less, more, .. - in
/Applications
: Mail, Numbers, Pages, Safari, .. - ...
The user can install additional software:
- with Homebrew (into
/opt/homebrew/opt
) - from the App Store (into
/Applications
) - with
npm
orpip
(omitted in diagram) - or otherwise ...
Configuration files are typically stored somewhere in the user's home directory:
- dotfiles, like
~/.zshrc
and~/.gitignore
- dotfolders, like
~/.ssh
and~/.config
- under
~/Library
(like~/Library/Preferences
and~/Library/Application Support
)
Installing all this software and restoring (macOS or application) configurations to the settings you are used to, can be a cumbersome task.
Dotbot is all about automating the installation & configuration of your macOS system. This dotfiles project is based on dotbot and is specifically tailored to my macOS system. But it can be easilly adjusted to your needs.
Dotbot is not about keeping the software on your system up-to-date. It is also not about automatically backing up changes to your system. This is why I have added the 'bookkeeper' to this project.
This dotfiles project does the following:
- Installation
- Configuration
- Backup to GitHub (.dotfiles project) & Dropbox (mackup)
- Update
The instructions for Dotbot are defined in install.conf.yaml.
When you run ~/.dotfiles/install
the following will be installed (or upgraded):
- package managers & packages
version manager package manager backup Homebrew - brew Brewfile Node n npm npm.global.txt Python pyenv pip pip.requirements.txt - Java & jenv
- SSH connection with GitHub
- and step-by-step instructions for the user (example) in case something can not be automated
NB: In zshrc we've configured the Homebrew --no-quarantine
flag. This will disable the macOS Gatekeeper, so that an application can be used immediately after installation.
In Brewfile some GUI macOS applications have the keyword cask
and some mas
(Mac App Store cli).
- A
cask
is downloaded from a Homebrew repository - A
mas
is downloaded from the Mac App Store
Some applications are only available as mas; some only as cask; some as both; and some neither as cask nor mas (these must be downloaded & installed manually).
Only applications that have already been purchased in the App Store can be automatically installed using mas
. If you want to install a paid application for the first time, you have to manually pay for it in & install it from the App Store.
I prefer cask
over mas, since applications stored in the App Store are tied to one (Apple ID) account, and it is not possible to transfer a purchased app from one account to another. The only drawback of installing as cask is that you will have to upload your license manually after installation.
More info: man brew
/ brew help bundle
/ mas help
Some casks are shipped with command line tools. Brew installs (symlinks) them in /opt/homebrew/bin
:
$ ls -la /opt/homebrew/bin | grep /Applications/
bcomp -> /Applications/Beyond Compare.app/Contents/MacOS/bcomp*
code -> /Applications/Visual Studio Code.app/Contents/Resources/app/bin/code*
stree -> /Applications/Sourcetree.app/Contents/Resources/stree*
...
Since this folder is in the $PATH
these tools are automatically available.
Configuration files are scattered all over the system.
- dotfiles & dotfolders under
~
- stuff under
~/Library/...
- system preferences (managed using the
defaults
command) - ...
We use two means of backing up config files (no 100% coverage):
tool | storage | how | example |
---|---|---|---|
.dotfiles | GitHub | symlinks | ~/Library/Preferences/com.apple.Terminal.plist -> ~/Dropbox/Apps/Mackup/Library/Preferences/com.apple.Terminal.plist |
mackup | Dropbox | symlinks | ~/.zshrc -> ~/.dotfiles/zshrc |
Beware that dotfiles
and mackup
can overlap. Always make sure that dot-files stored in this dotfiles
project are excluded from mackup ([applications_to_ignore]
section in mackup.cfg).
Not all changes to the system are automatically (via symlinks) reflected in ~/.dotfiles
or ~/Dropbox/Apps/Mackup
:
- (un)installing packages with homebrew
- (un)installing packages with pip
- (un)installing packages with npm
- (un)installing Visual Studio Code extensions
That's what bookkeeper is for. Bookkeeper periodically re-generates backup files for installed homebrew, pip & npm packages. And commits them to GitHub.
In addition to generating backup files, bookkeeper also updates all outdated homebrew / npm / pip packages and applications. Installing bookkeeper as a background job will automate this for you.
NB: It is still your own responsibility to upgrade applications that were installed from the App Store (or otherwise bypassed the standard package managers).
- avoid manual installation of tools or apps
- if you do, consider adding it to the manual steps section
- use the App Store only if an app is not available as a Homebrew cask
- extend bookkeeper where possible
- for stuff that can not be automatically backed up (like brew/npm/pip packages & vscode extensions)
- use mackup (i.e. Dropbox) to backup configuration files containing sensitive information (passwords, email, etc.)
- do not store them in this .dotfile project!
package manager | install | uninstall | target | |
---|---|---|---|---|
homebrew | brew | brew install <pkg> |
brew uninstall <pkg> |
/opt/homebrew/opt |
node | npm | npm install --global <pkg>[@<version>] |
npm uninstall --global <pkg> |
~/.n/bin |
python | pip | pip install <pkg>[==<version>] |
pip-autoremove <pkg> (*) |
pip show <pkg> |
(*) pip uninstall
does not uninstall (unused) dependencies. pip-autoremove
does.
Useful pip commands:
pip list
pip show <pkg>
# Show package dependencies:
pip show <pkg> | grep ^Required-by
See the 'HOW TO' below on how to install a specific version of a package (instead of the latest version) with brew, npm and pip.
- Java
- use homebrew to (un)install JDKs (see below)
- use jenv to switch versions
- Node
- use n to (un)install Node versions
- use n to switch Node versions
- Python
- use pyenv to (un)install python versions
- use pyenv to switch python versions
- Terraform
- use tfenv to (un)install terraform versions
- use tfenv to switch terraform versions
search | show versions | install version | |
---|---|---|---|
homebrew | brew search <pkg> |
brew search <pkg> |
brew install <pkg>@<version> (*) |
node | npm search <pkg> |
npm show <pkg> versions |
npm install --global <pkg>@<version> (**) |
python | poetry search <pkg> (***) |
pip index versions <pkg> |
pip install <pkg>==<version> (**) |
(*) Homebrew has limited support for installing old versions. It does support multiple versions with a special naming format, but most packages are available only as most recent version. Some packages (like openjdk, postgresql, python, ..) are available in older versions (openjdk@11, openjdk@17, ..).
(**) with npm and pip it's only possible to install one version at a time. If you do npm install --global <pkg>@<2nd_version>
or pip install <pkg>==<2nd_version>
packages that are already installed will be removed.
(***) pip search
is deprecated. You can either use poetry, or search online at https://pypi.org/ (Python Package Index).
MacOS comes with a list of pre-installed tools in /usr/bin
.
For example less
, keytool
, more
, ssh
, zip
, etc ...
You don't want to mess around with the tools in /usr/bin
.
If you want to be able to manage one of these tools with Homebrew (and always use the latest version) you can install the tool alongside the pre-installed one:
which -a <pkg>
<pkg> --version
brew search <pkg>
brew install <pkg>
brew info <pkg>
# open a new shell
zsh
which -a <pkg>
<pkg> --version
As long as /opt/homebrew/bin
appears before /usr/bin
on the $PATH
the brew version will take precedence.
On the last line you should see the newest version (installed with brew) instead of the pre-installed version.
See this example (nano).
Situation May 2022.
Oracle JDK | OpenJDK | ||
---|---|---|---|
1 | choose jdk version | oracle-jdk |
openjdk and openjdk@<lts> (*) |
2 | install jdk | brew install oracle-jdk |
brew install openjdk@<version> |
3 | /Library/Java/JavaVirtualMachines/ | symlink created automatically | create symlink manually (**) |
4 | add jdk to JAVA_HOME_LOCATIONS |
update setup_java.zsh | update setup_java.zsh |
5 | add jdk to jenv |
run setup_java.zsh | run setup_java.zsh |
(*) Oracle JDK comes in just one version (most recent). For OpenJDK also some recent LTS (long term support) versions can be installed (8, 11, 17).
(**) When you install the Oracle JDK a symlink from /Library/Java/JavaVirtualMachines to /opt/homebrew/opt is automatically created. When you install openjdk you will have to create the symlink manually. Do brew info openjdk@17
for more information.
brew uninstall openjdk@17
- remove JDK from JAVA_HOME_LOCATIONS in
setup_java.sh
- remove symlink from
~/.jenv/versions
- remove symlink from
/Library/Java/JavaVirtualMachines
Some Applications come with a command-line launcher:
command | opens | |
---|---|---|
/opt/homebrew/bin/ | bcomp . |
Beyond Compare |
/opt/homebrew/bin/ | code . |
Visual Studio Code |
/opt/homebrew/bin/ | skimpdf help |
Merge/extract PDF with Skim |
/opt/homebrew/bin/ | stree . |
SourceTree |
/usr/local/bin/ | idea . |
IntelliJ IDEA |
- Create a
*.zsh
script to open the web page. For example ~/.dotfiles/bin/asciiflow.zsh:#!/usr/bin/env zsh open https://asciiflow.com/
chmod 755 asciiflow.zsh
- Create an Automator application that
Runs Shell Script
- Save the application to ~/.dotfiles/bin/apps/ASCIIFlow.app
- Add the app to setup_dock.zsh
- Dotbot
- Dotfiles
- Dotfiles from Start to Finish-ish (Udemy)
- Dotfiles repo example (github)
- Youtube
- defaults command:
- macos-defaults.com
- cfprefsd
- macOS Prefs Editor
- Example of a script with lots of defaults
- More info on the defaults command:
man defaults defaults help