Dotfiles for Product Managers
Craftsman lavish as much attention on their tools as they do on the craft itself. Product managers (at least the good ones) are craftsman and we care a lot about the tools we use. We can debate endlessly on the merits of analytics or design tools. But for some reason, we don’t give much attention to the tool we spend most of our working days on….our computer.
The software equivalent of a whetting stone for your computer is dotfiles. On UNIX based systems, dotfiles help you customize almost every aspect of your computer from terminal commands, shortcuts, system preferences to display preferences. Customizing your computer is great for your productivity and most importantly – comfort (which in the end should make you more productive). And it’s not just for the software developers!
I’ve been actively customizing my computer using dotfiles for many years now. I’ve spent a lot of hours getting things just right in a way that works for me. I’ve become so used to many of them, that I start to feel lost on other computers.
This is my basic dotfiles setup, that I can quickly pull onto other computers I might use. (I’m also working on bootstrapping my entire MacOS setup but that is for a later post)
While there are loads of examples (including mine) of how people have customized their dotfiles, I would caution against lifting these without a good understanding of what they do. Your dotfiles are meant to be a representation of you. Pick and choose wisely and only keep the settings that work for you.
(My current setup is on MacOS, using ZSH as a shell and iTerm as my main terminal program)
Install Homeshick
I use homeshick to make my dotfiles portable.
You can install homeshick via homebrew
brew install homeshick
or by directly cloning it (see here for further instructions)
git clone git://github.com/andsens/homeshick.git $HOME/.homesick/repos/homeshick
printf '\nsource "$HOME/.homesick/repos/homeshick/homeshick.sh"' >> $HOME/.bashrc
Homeshick works by creating a castle in which you store all your dotfiles. The castle is basically a git repository in which one folder (the home folder is symlinked into your ~
or root folder)
homeshick generate dotfiles
You can track any existing dotfiles using homeshick
homeshick track .zshrc
Then add, commit and push to a remote repository
homeshick cd dotfiles
git commit -m "Initial commit, add .bashrc"
git remote add origin git@bitbucket.com:username/dotfiles.git
git push -u origin master
To have this work on a remote machine, all you have to do is install homeshick and clone this repo. After cloning the repo, homeshick will ask you whether you’d like to symlink all files in the dotfiles home folder to the root folder
Getting Homeshick Working with Prezto
In my case, I was already using Prezto as a framework to help me customize zsh to my liking. Getting Prezto to work with homeshick is not straightforward but this is what you need to do.
homeshick cd dotfiles
- Fork prezto from here to the
dotfiles
repo - Ensure you are already tracking
.zshrc
and that.zshrc
includes the Prezto source lines - In the home folder of the
dotfiles
repo create the following symlinks (for e.g.ln -s ../prezto .zprezto
)
.zlogin -> ../prezto/runcoms/zlogin
.zlogout -> ../prezto/runcoms/zlogout
.zprezto -> ../prezto
.zprofile -> ../prezto/runcoms/zprofile
Introducing Abstraction
When I started, my .zshrc
contained a lot of my customizations. Everything from sourcing commands, aliases to functions was stored there. But it was getting difficult to manage.
I decided to use homeshick to help me refactor some of this into seperate files.
I created a new shell
folder in my dotfiles
repository under which I created files like aliases.sh
and functions.sh
The idea was to then source these files in the .zshrc
file.
source "$HOME/.homesick/repos/dotfiles/shell/aliases.sh"
However, I didn’t want to use absolute filepaths but instead reference these from the .zshrc
file in the home
folder.
The challenge here is that as .zshrc
is symlinked, the running directory is difficult to define inside the file itself. However you can do it using
# Define .zshrc running directory
ZSHDIR="$(dirname "$(greadlink -f "${(%):-%N}")")"
# Source Aliases
source "${ZSHDIR}/../shell/aliases.sh"
# Source Functions
source "${ZSHDIR}/../shell/functions.sh"