Fork me on GitHub

I love checkoutmanager and dotfiles

An ode to my OS X development workstation setup [1]

I am big on setting up my development environment, and enjoying the environment I work in. And I'm very thankful to the folks who make my life easier, including the authors of:

I also love repetition. So picture if you will, a new Macbook Air or Pro ready to serve as my development workstation. I like to perform, and study, the steps required to turn a new laptop in to my development workstation. So here we go. In this article, I will walk through the steps required to turn a new machine in to my developer workstation. Do follow along!


One of the first things I do on a new system is change my shell to Zsh in System Preferences -> Users & Groups -> Current User -> Right Click -> Advanced Options.... Don't forget to Click the lock to make changes first.

alternate text


Why Zsh? One of my favorite features is shared history between open sessions. So I can run a command in one window, and then run the same command from another window by fetching it from the history (with CTRL-R).


After I take possession of my new laptop (running Mountain Lion, the newest OS X at the time of this writing), I head to the App Store to download XCode. [2] Among many other things, XCode gives me the GNU C Compiler and allows me to type "gcc" in my Applications -> Utilities -> Terminal.

alternate text


alternate text

Now I need a Python interpreter [3]. For development I use the Collective Python Buildout but I also enjoy using Homebrew's Python 2.7. I use Homebrew for a variety of other things too (e.g. mobile-shell AKA mosh) so here we go:

$ ruby -e "$(curl -fsSL"

… follow instructions …

$ brew install python


I think OS X (or XCode) includes git, but just in case:

$ brew install git

Which reminds me, don't forget that installing the command line utilities in Mountain Lion's XCode requires an additional step in Preferences -> Downloads -> Command Line Tools -> Install:

alternate text


At this point, I can begin to get serious about turning this new machine in to my developer workstation. And that means: installing my private ssh key so I can check out code without typing a password, of course. Normally this would be tedious, but with git and dotfiles it's not so bad. This is what I do from my home directory:

$ git clone https://super_secret_url/dotfiles.git Dotfiles

I use https which requires a password for the first time only. Then I edit Dotfiles/.git/config and change the repository URL to git@super_secret_url/dotfiles.git. So every subsequent pull and push will require no password. And to "install" these dotfiles, I do [6]:

$ pip install dotfiles
$ dotfiles -s --force

Note: the dotfiles command finds my dotfiles in the default directory "Dotfiles" and create symbolic links to them.

Distribute & Pip

Homebrew's Python includes pip, but even if it didn't:

$ curl -O
$ /usr/local/bin/python
$ {easy_install, pip install} dotfiles

In other words, you can always install Distribute [4]. After which you can use easy_install or pip to install dotfiles. (You can read up on the differences. TL;DR: neither is "better" or "worse", it's just a question of which tradeoffs you are willing to make. I tend to use pip just because it's newer and I like its requirements.txt feature, but easy_install is still very well supported as part of the Distribute project.)


Now I need some things to develop. Since I work on a bunch of different projects, I need a way to keep track of what should be checked out at any given time. So I do this [5]:

$ pip install checkoutmanager
$ checkoutmanager co

This creates and populates my ~/Developer directory with code. And it "just works" because I keep a .checkoutmanager.cfg in my Dotfiles repository. It currently looks like this:

basedir = /Users/aclark/Developer/aclark
checkouts = resume
vcs = git

basedir = /Users/aclark/Developer/alt
checkouts =
vcs = git

basedir = /Users/aclark/Developer/buildout
checkouts =
vcs = git

basedir = /Users/aclark/Developer
checkouts = ssh://
vcs = hg

basedir = /Users/aclark/Developer
checkouts =
; Bunch o client repos
vcs = git

basedir = /Users/aclark/Developer
checkouts =
; Bunch o client repos
vcs = hg

basedir = /Users/aclark/Developer/dcpython
checkouts =
vcs = git

basedir = /Users/aclark/Developer
checkouts = blog
vcs = git

basedir = /Users/aclark/Developer/pillow
checkouts =
vcs = git

basedir = /Users/aclark/Developer/plethorasociety
checkouts =
vcs = git

basedir = /Users/aclark/Developer/plone
checkouts =
vcs = git

basedir = /Users/aclark/Developer/pythonpackages
checkouts = vanity_app pythonpackages-github-services pythonpackages-index
vcs = git

basedir = /Users/aclark/Developer/toys
checkouts =
vcs = git

Now it's time to bootstrap the Collective Python Buildout, which gives me all versions of Python, ever [7]. And off we go:

$ cd Developer/buildout.python
$ python

Finally, there is some PATH configuration required to make all of this seemless. The Collective Python Buildout gets installed in /opt while brew's stuff is in /usr/local. My PATH config currently looks like this:

export PATH=/usr/local/bin:/usr/local/sbin:/opt/local/bin:/Users/aclark/Developer/buildout.python/python-2.7/bin:$PATH
export PATH=~/Developer/binfiles:/usr/local/share/npm/bin:$PATH

With the above configuration, I default to the Python 2.7 in the Collective Python Buildout. That means that is the "python" or "virtualenv" I get when I type those commands. I use the full path or expanded binary name when I need them e.g. /usr/local/bin/python or python3.3.

That's it! I hope you will check out dotfiles and checkoutmanager for all your development needs.

[1]Not really an ode:
[2]I know about Kenneth Reitz's XCode Command line Tools only, but if I recall correctly there is some "gotcha" that has bitten me more than once if I use that instead of the full XCode. I wish I could remember what it was now, but it's not coming to me. If it works for you though, great!
[3]I know about the system Python, and for small things like checkoutmanager and dotfiles I don't mind using it. But there is merit in avoiding it because Apple treats it like "their" Python and makes decisions for you that you may prefer to make yourself. E.g. I believe they use a crippled version of the readline library.
[4]Distribute is a more actively maintained fork of the venerable setuptools library (which itself is built on top of the Python standard library's distutils). Are we having fun yet?
[5]I also alias checkoutmanager to cm :-)
[6]I force because I want to replace the newly created .ssh dir with the one I keep in my Dotfiles repository.
[7]Well, 2.4 through 3.3 at last count.

Comments !