Configuring a New Pairing Station

We recently had to install a new pairing station, and decided to document the process for the next poor chump who needs to waste a Saturday afternoon. We're not going to take pains to explain alternate tools or installation methods - this is our station, and we're proud of it.

With the preamble out of the way, let's get going!

Initial installation:

This is a pairing station, so it needs a user account that will be shared by all of the developers. We named the user on this machine "pair", and we created an Apple ID just for him.

Purchase from the App Store:

Fire up the AppStore and purchase the following tools: XCode, Witch (We configure the hotkey to be ⌘⇥), and Growl.

The nice thing about having a dedicated Apple ID for the pairing station is that it keeps these charges on the company card.

Download:

The following tools aren't available on the AppStore, and have to be downloaded by hand. Oh the humanity! Download and install SizeUp, MacVim (see our .vim files, Dropbox, Propane, Teleport, and Monofur font.

Monofur is a great font. We use it both in the terminal (you can grab our terminal preferences, and also in vim.

Sublime Text 2

Sublime Text 2 is the new everyman's editor, which is super important on a pairing machine. Once you've installed Sublime, then very next step should be to install the Sublime Package Manager

Type Ctrl-`, paste the following in, and restart Sublime.

import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation'

Also, install the CLI:

ln -s "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl" ~/bin/subl

There's a keyboard shortcut cheat-sheet, but the two most useful commands are ⌘T (fuzzy find files) and ⌘P (fuzzy find commands).

Installed via Homebrew:

Homebrew is the best package manager for OS X we've found so far. Strongly encapsulated, easy to use and well-maintained. Installation is as easy as…

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"

(…as of this post, that is. Be sure to check out the install page in case the gist url changes.)

Once you've installed Homebrew, you can follow it up with some useful packages:

$ brew install ack bash-completion git imagemagick readline wget

There's often some after-install configuration that has to happen for each package. For example, the bash-completion package requires the following:

$ ln -s "/usr/local/Library/Contributions/brew_bash_completion.sh" "/usr/local/etc/bash_completion.d"

And add this to your ~/.bash_profile file:

if [ -f `brew --prefix`/etc/bash_completion ]; then
  . `brew --prefix`/etc/bash_completion
fi

Don't worry if you miss the post-install instructions. You can always reprint them via a quick brew info PACKAGE_NAME.

PostgreSQL

Not only is PostgreSQL the best SQL server out there - it's also the one our primary hosting provider uses. It's important to keep the development environment as close to production as possible.

$ brew install postgresql
$ initdb /usr/local/var/postgres
$ mkdir -p ~/Library/LaunchAgents
$ cp /usr/local/Cellar/postgresql/*/homebrew.mxcl.postgresql.plist ~/Library/LaunchAgents/
$ launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

Redis

Many of our projects use Redis, the AK-47 of NoSQL stores.

$ brew install redis
$ cp /usr/local/Cellar/redis/2.4.7/homebrew.mxcl.redis.plist ~/Library/LaunchAgents/
$ launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.redis.plist

Ruby 1.9.x

XCode recently went LLVM, which is really amazing. Unfortunately, that means you don't get a stock GCC compiler with Lion. We can fix this by using the OS X GCC Installer. Install that, and then run the following:

$ brew install rbenv ruby-build

Follow the installation steps that brew prints to the console, and restart your terminal. Now, we install both ruby 1.9.2 and 1.9.3:

$ rbenv install 1.9.2-p290
$ rbenv shell 1.9.2-p290
$ gem install bundler
$ rbenv install 1.9.3-p0
$ rbenv global 1.9.3-p0
$ gem install bundler

We install them both, since we need 1.9.2 for Heroku compatibility, and 1.9.3 for faster development.

Pow

Pow is a great tool for local development. Installation is as easy as curl get.pow.cx | sh. Since we use rbenv, we also need to add the following to our ~/.powconfig file:
export PATH="/Users/pair/.rbenv/shims:$PATH"
export POW_TIMEOUT=10800 # seconds...  3 hours.
export POW_WORKERS=3

Be sure to change "pair" to your local username above, and restart Pow via Activity Monitor.

Profile:

We've put our pairing dotfiles up on github. There are some good tweaks I'll point out below:

GitHub Pairing Configuration

Pushing to github from the pairing box is made much easier by the edgecase-git-pair gem. It's old, but it still works fine.

  1. Create a shared github user account. Ours is called tbl-pair.
  2. Add that user to any repo you'll be pairing on.
  3. Generate SSH keys, and upload the public one to github under that account.
  4. Install the edgecase-git-pair gem.
  5. Configure ~/.gitconfig to include authors for each of your developers. You can see our version on github.

Now, when starting a pairing session, just be sure to type $ git pair ts rt to set the authors.

Heroku

Much like with GitHub, we invited our pairing user to collaborate on our Heroku projects. The only trick to remember is to upload the ssh keys with heroku keys:add.

…and you're done.

This setup takes quite a while, but it's well worth it in the long run. Hope this helps you in configuring your next pairing station.


*Keep it real, we'll erase shit we don't like.*
comments powered by Disqus


Thunderbolt Labs offers Engineering, Mentoring, and CTO Advising services for those who demand the best.

Follow us on twitter or email us to discuss your next project.


Thunderbolt Labs
Thunderbolt Labs

…The myth and the legend itself