/dotfiles

macOS dotfiles — migrate, backup, config, brew, dev, and a whole lot more.

Primary LanguageShellMIT LicenseMIT

$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:

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 config
  • bash — bash specific config
  • bin — various binaries, symlinked to ~/bin and in $PATH
  • curl — curl config
  • editor — editor config (including linters)
  • git — git config, attributes and ignore files
  • iterm2 — iterm2 themes
  • mackup — config to backup app settings and personal files
  • .mackup.cfg files for custom apps, symlinked to ~/.mackup
  • macos — macOS prefs
  • node — node config
  • ruby — ruby config
  • screen — screen config
  • setup — install, migrate and backup scripts
  • shell — general shell config
  • terminal — terminal themes
  • tmux — tmux config
  • vim — vim config
  • wget — 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:

  1. I can edit files in one place — changes apply to both my current system and this project's repo.
  2. My user directory is clean — no git repo in ~/, no mess, no need for a complex .gitignore.
  3. Symlinks are easy — add, refresh and unlink using a config script.

OK, that's enough theory, let's get things set up.

Setup

⚠️ Scripts in this project perform automated tasks. Review the code first and use at your own risk! ⚠️

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:

Setup screen

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:

  1. Backup directories and files we'll be touching
  2. Create required directories
  3. Install Xcode Command Line Tools
  4. Install Homebrew and all required apps
  5. Create symlinks for directories and files
  6. 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:

  1. Install the Xcode Command Line Tools
  2. Configure the tools
  3. 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:

  1. Install Homebrew
  2. Install Core utils
  3. Install Other useful utils
  4. Install Backup tools
  5. Install Development tools
  6. Install Databases
  7. Install DevOps tools
  8. Install Webfont tools
  9. Install Fonts
  10. Install Applications
  11. 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:

  1. Installs the latest Node release using asdf
  2. Installs the current LTS Node release using asdf
  3. Updates npm
  4. Creates ~/.node-global-modules
  5. Installs global modules to this folder

Vim setup

After this, the script setup/vim.sh is run which:

  1. Creates required vim directories
  2. Installs vim-pathogen
  3. 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:

  1. All directories declared in $dotfilesdirarray
  2. Any file of an accepted type in a directory declared in $dotfilesfilearray
  3. 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 and chmod 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. 🙌

Customising your $PATH

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:

  1. Create a java directory in your dotfiles root.
  2. 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 ⚠️ be very careful using this file ⚠️ — I do not recommend just running it without reviewing and understanding it carefully first.

$ 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.

⚠️ Caution is advised here — see the Migration Guide for more information.

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

:octocat: There's no place like $HOME.