Dotfiles: Automating my software setup

about | archive


[ 2014-October-05 19:51 ]

When I joined Twitter nearly two months ago, I decided to use separate accounts for my work and personal lives to make it clearer what is theirs and what is mine. This is a bit paranoid, but I think its prudent. (If I were really legally paranoid, I would use separate computers, but that is way too much work.) I got tired of manually configuring two environments, so I started putting my config files in a dotfiles Git repository, and automating a few things. As XKCD predicts, I got carried away and wasted a bunch of time figuring out how exactly to copy changes from one setup to another. However, I think every programmer probably should store their simple config files in a repository, even if you only have one account. It documents how you set up your environment, which is useful when you change something and notice something broken many days later, or when someone asks you how you set up Sublime or you shell to do that cool thing. I also just like being able to run "git diff" and see what changes I made.

You won't really configure things that many times, so don't waste the time I did. You'll get 99% of the benefit by just keeping the easy things in a single repository. I like moving the real configuration files into a Git repository, then replacing the original file with a symlink. If you do this manually, you'll get most of the benefit. Github's dotfiles guide has some more reasonable suggestions for getting started.

(You can browse my dotfiles repository, if you are curious.)

However, if you do decide to go crazy and save nearly everything in your repository, hopefully these notes will save you some time.

Make it idempotent

It is really annoying when running your auto-configure command twice in a row screws something up. For example, to symlink and copy my configuration files, I wrote a program that checks if the links already exist, and skips them if they do. Now if I add a new file, I change the configuration at the top of the file and re-run it.

Mac OS X: Plists are weird

Mac OS X applications usually store their configuration in a .plist file, in the ~/Library/Preferences directory. These used to be XML files, but became a binary format. XCode comes with a GUI browser, and you can also use defaults, PlistBuddy, or plutil to read and write them on the command line (see the man pages). As of Mavericks (10.9), there is a daemon called cfprefsd that caches these files, so just editing the file is no longer enough, because it will silently overwrite the file with the application's original version. The easiest workaround: replace the configuration files then immediately run killall cfprefsd to force them to be reloaded. The other approach is to make changes through Mac OS X's configuration APIs. The defaults command does this, but you can also use Python, like I do to configure Apple's Terminal.

Mac OS X: hidden defaults

The defaults command can change preferences that are not exposed in the UI. I used this to change the default file open and save dialog view to column view, and to change Finder's default folder to my home folder. Other people have figured out what these options are, so check out my Mac OS X configuration script for some examples. I discovered this because the Kompanee published some really extensive config files that tweak all sorts of preferences. For example, see their Finder and file dialog preferences.