$HOME sweet ~/
Your dotfiles are how you personalize your system.
These are mine. Built for Mac OS X. Certified lit 🔥 🔥 🔥
Rationale
Setting up a new developer machine can be ad-hoc, manual, and time-consuming. This project simplifies that process using easy-to-understand instructions, configuration and scripts.
Our goal is to automate at least 80% of any new macOS system setup.
What's in the box?
Setup and config for bash, curl, git, node, ruby, tmux, vim, brew, apps, dev environments and more — there's a lot to list so please see the full Package Contents.
Highlights
- Xcode Command Line Tools with automated install.
- Awesome bash setup: aliases, functions, z, smart prompt, tab completion and more.
- Git done right: aliases, hub, git-friendly and custom scripts.
- Vim for the win via vim-pathogen, vim-sensible and other plugins.
- tmux to the max using config and shortcuts.
- Homebrew package manager to install tools, applications and fonts.
- Must-have tools: GNU core utils, gnupg, quick look plugins, wifi-password, etc.
- Must-have apps: Caffeine, Dropbox, Chrome, Spectacle, Spotify, etc.
- Developer tools: AWS CLI, Docker, MySQL, Postgres, Python, Yarn, etc.
- Developer apps: iTerm2, Slack, VS Code, etc.
- Node development using asdf with global package installer.
- Ruby development using rbenv and ruby-build.
- Goodies in bin including git and tmux tools.
Also, last but not least:
- Setup scripts to manage backup, install, config and symlinking (plus migration).
- Mackup to backup and restore app settings and personal files.
- OS X defaults geared towards developers.
Sounds good? Let's go.
Install
Note: If working on a fresh install I recommend reading my Mac OS X Setup Guide first.
Using Git
Clone the repository wherever you prefer — I like to store the files in ~/projects/dotfiles
and then symlink that to ~/dotfiles
(see Symlinks).
$ git clone https://github.com/aaronbates/dotfiles.git
Structure
To keep the project organised all files are split into directories and grouped around topic areas:
ack
— ack configbash
— bash specific configbin
— various binaries, symlinked to~/bin
and in$PATH
curl
— curl configeditor
— editor config (including linters)git
— git config, attributes and ignore filesiterm2
— iterm2 themesmackup
— config to backup app settings and personal files.mackup
—.cfg
files for custom apps, symlinked to~/.mackup
macos
— macOS prefsnode
— node configruby
— ruby configscreen
— screen configsetup
— install, migrate and backup scriptsshell
— general shell configterminal
— terminal themestmux
— tmux configvim
— vim configwget
— wget config/
— project files and setup script
See Extending for information on adding new topics.
Symlinks
Symbolic links (aka "symlinks") allow you to point one location on a system to another, be that a file or directory. They are similar to aliases and shortcuts, but more "powerful" in the context we'll be using them.
Most dotfiles need to live in the root of a user's directory (~/
) for applications to find them.
Rather than copy files to ~/
or put my entire $HOME
under version control, I prefer to symlink dotfiles to my user directory. This offers several benefits:
- I can edit files in one place — changes apply to both my current system and this project's repo.
- My user directory is clean — no git repo in
~/
, no mess, no need for a complex.gitignore
. - Symlinks are easy — add, refresh and unlink using a config script.
OK, that's enough theory, let's get things set up.
Setup
This projects takes a light-weight approach to automation using a combination of Homebrew, Homebrew Cask, and shell scripts. To setup simply open Terminal then:
$ cd ~/projects/dotfiles # or wherever you cloned to.
$ ./setup.sh
The setup process will start and guide you through:
You'll also be asked to enter your password once at the start — if using on a fresh install, you'll have to restart after the first run applies system updates.
Step-by-step
Setup consists of six steps:
- Backup directories and files we'll be touching
- Create required directories
- Install Xcode Command Line Tools
- Install Homebrew and all required apps
- Create symlinks for directories and files
- Final touches
Step 1: Backup
This step runs the
setup/backup.sh
script.
Creates ~/backup/dotfiles-backup
then takes a copy of all files on the current system which would be replaced by the setup script (as defined here) — it also backs up some other useful local directories and files.
Step 2: Directories
This step runs the
setup/directories.sh
script.
Creates required and preferred directories (if they don't already exist) for example: ~/Applications
, ~/projects
, ~/code
, .ssh/control
, etc.
Step 3: Xcode Command Line Tools
This step runs the
setup/xcodecli.sh
script.
The Xcode Command Line Tools contain tools required by this setup script, this step will:
- Install the Xcode Command Line Tools
- Configure the tools
- Prompt for license agreement
Step 4: Homebrew
This step runs the
setup/brew.sh
script.
Package managers make it easy to install, update and remove software The best package manager for OS X is Homebrew — this step installs Homebrew along with many useful formulae and apps:
- Install Homebrew
- Install Core utils
- Install Other useful utils
- Install Backup tools
- Install Development tools
- Install Databases
- Install DevOps tools
- Install Webfont tools
- Install Fonts
- Install Applications
- Install Quicklook plugins
The script then uses mas
to install some Mac App Store applications unavailable via Homebrew.
Node setup
Post application install the script setup/node.sh
is run which:
- Installs the latest Node release using
asdf
- Installs the current LTS Node release using
asdf
- Updates
npm
- Creates
~/.node-global-modules
- Installs global modules to this folder
Vim setup
After this, the script setup/vim.sh
is run which:
- Creates required vim directories
- Installs vim-pathogen
- Installs plugins
Step 5: Symlinks
This step runs the
setup/symlinks.sh
script.
Creates symlinks for all required directories and files to ~/
. These are defined in setup/files.sh
as:
- All directories declared in
$dotfilesdirarray
- Any file of an accepted type in a directory declared in
$dotfilesfilearray
- Custom manually declared files (git-friendly scripts to
bin
)
This also links the local repository directory to ~/dotfiles
if it was cloned to a different location.
Symlinking directories: If directory bin
is declared in $dotfilesdirarray
then the whole directory will be symlinked to ~/bin
.
Symlinking files: If directory bash
is declared in $dotfilesfilearray
then any file of an accepted type will be symlinked to ~/
. For example:
bash/.aliases
links to~/.aliases
bash/.bash_profile
links to~/.bash_profile
bash/.functions
links to~/.function
- and so on.
Which files will be symlinked?
Only files of type .*
, *.cfg
and *.conf
will be symlinked. Also, certain files are explicitly ignored:
.DS_Store
,.git
,.osx
and.macos
- any file of type
*.sh
Symlink scripts
The symlink script can be run independently from a shell — it performs various checks, asks questions and provides feedback. Equally there is an setup/unlink.sh
which unlinks all created symlinks.
Step 6: Final touches
Finally a number of other tasks are performed:
- Install a better .nanorc config
- Set
chmod 700 ~/.ssh
andchmod 600 ~/.ssh/*
(see here) - Note: see here for more info on Unix style permissions
- Install Solarized Dark Theme for Terminal
- Install Solarized Dark High Contrast Theme for iTerm2
⚡ Congrats, you now have an awesome macOS setup. Open up iTerm2 and explore. 👏
Usage
It's beyond the scope of this readme to fully document all features, but you can find some tips and features of notes in the Getting Started guide.
Customise using "local config"
This project can be easily customised to suit personal settings and local requirements using "local config" files. This allows you to:
- Use custom settings without forking this project.
- Set config you don’t want to commit to a public repo.
- Store credentials that should remain private.
As mentioned, it's very important to avoid storing private data or credentials in a dotfiles repository, using "local config" files that are never committed to public version control is a good way to achieve this.
Adding custom bash commands
If an ~/.extra
file exists, it will be sourced on load after all other bash files. You can use this to store custom aliases, functions, exports and settings.
Example ~/.extra
file:
alias myalias=some-other-command -options
my_function () {
do something here
}
export MY_SETTING=VALUE
You could also use ~/.extra
to override existing settings, functions and aliases — but at that point, it's probably better just to fork and create your own dotfiles. 🙌
$PATH
Customising your The included .path
file is pre-configured and sourced on load. To add custom entries to your path, create a ~/.path.local
file.
Example ~/.path.local
file:
# Add to the start of the path
PATH="/your/path/here:$PATH"
# Add to the end of the path
PATH="$PATH:/your/path/here"
This will also be sourced on load and the final $PATH
will be deduplicated on export.
Customising Git
Customise your Git config by creating a ~/.gitconfig.local
file which will extend .gitconfig
. Use this to store private details such as your user credentials and signing key.
Example ~/.gitconfig.local
file:
[user]
name = "Firstname Lastname"
email = "your@emailaddress.com"
[github]
user = your-github-username
[credential]
helper = osxkeychain
[commit]
signingkey = YOUR-SIGNING-KEY-HERE
Customising Vim
Customise your Vim config by creating a ~/.vimrc.local
file which will extend .vimrc
.
Customising tmux
Customise your tmux config by creating a ~/.tmux.conf.local
file which will extend .tmux.conf
.
Fork
Feel free to fork this repo, hack around, and make it your own 👌
Extending
This project is organised around topics, see Structure for more information.
To add a new topic to your forked dotfiles, you can simply add a /topic-name
directory and put any files in there. Let's use "Java" as an example:
- Create a
java
directory in your dotfiles root. - Inside there, create two files:
java.conf
and.javarc
If you then edit setup/files.sh
you have two options:
A) Symlink the entire folder
This will symlink the java
directory to ~/java
(if that doesn't already exist). Useful if you want access to a number and variety of files within a directory.
To do this, simply add "$dotfilesdir/java"
to the dotfilesdirarray
:
# Declare array of directories we want to symlink.
declare -a dotfilesdirarray=(
"$dotfilesdir/bin"
...
"$dotfilesdir/java"
)
Then run the symlink script to apply the link.
B) Symlink files in the folder
This will symlink files of accepted types in the java
directory to ~/
(if they don't exist already) — so for our example, it would create links to ~/java.conf
and ~/.javarc
.
To do this, add "$dotfilesdir/java"
to the dotfilesfilearray
:
# Declare array of directories we want to symlink files from.
declare -a dotfilesfilearray=(
"$dotfilesdir/bash"
"$dotfilesdir/git"
...
"$dotfilesdir/java"
)
Then run the symlink script to apply the links.
Going further
Sensible Mac OS X defaults
When setting up a new Mac, you may want to set some sensible defaults (as maintained by Mathias).
I have included my tweaked version of these settings in this repository, take a look but
$ cd ~/dotfiles/macos && ./.macos
If in any doubt, don't run this script, rather configure what you can manually.
Mackup for backup
Mackup is a fantastic tool that allows you to: backup personal application settings and private data; sync that data between computers; and then easily restore your configuration to a fresh install — all in a simple command line interface. Seems good!
While by no means a comprehensive backup solution, Mackup keeps things simple, currently supports over 360 applications and can store data on Dropbox, Google Drive, iCloud or any path you can copy to.
How I use Mackup
I store on Dropbox and explicitly declare which apps to sync and which to ignore — anything handled by my dotfiles is ignored (bash, git, vim etc.)
I backup a wide range of other applications including those containing credentials such as aws, gnupg and ssh. I also backup apps not natively supported using custom .cfg
files. For example, to backup Ulysses (an amazing markdown writing app) I created a ~/.mackup
directory and placed a ulysses.cfg
file inside:
[application]
name = Ulysses
[configuration_files]
Library/Preferences/com.soulmen.ulysses3.plist
Library/Preferences/com.ulyssesapp.mac.plist
It is usually straight-forward to find which .plist
files in Library/Preferences
you'll need to list, they always feature the application name.
Taking that a step further we can also declare a "personal files" application using a personal-files.cfg
and then cherry pick any other files we want to backup while keeping them out of a public repo:
[application]
name = Personal Files
[configuration_files]
.gitconfig.local
.extra
When I declare this in my main .mackup.cfg
they are handled with ease:
[storage]
engine = dropbox
directory = mackup
# Apps to sync — if empty, syncs all supported.
# custom: personal-files, break, grammarly, iconjar, iterm2, oversight, ulysses
[applications_to_sync]
personal-files
aws
...
ulysses
A simple $ mackup backup
saves everything to Dropbox and I can later $ mackup restore
on a fresh install to get these settings back (you can also easily $ mackup uninstall
).
These dotfiles symlink my Mackup config into ~/
— take a look 👀.
Migration
In addition to setup, it's possible to use these dotfiles on an configured Mac system to migrate to a new machine using the setup/migrate.sh
script.
Acknowledgements
Credit, inspiration and thanks to:
And too many others to name.
License
MIT © 2017 Aaron Bates (http://aaronbates.me)
TODO
- Install without Git
- Take user info for custom config setup (name/email/url)
- Add BATS test suite
- Ruby config
- Databases config
- Devops config (VM, Docker)
- Consider additional vim plugins
There's no place like $HOME
.