A simple strategy for dotfiles
Join the DZone community and get the full member experience.
Join For FreeSimple as in Simple Object Access Protocol. Dotfiles such as .vimrc and .bashrc are at the core of configuring a Unix system. They are usually places in the home folder of a user and, if present, are read by various tools such as the shell and Vim.
After having written (and rewritten) many dotfiles in the last years, I've gathered here a few strategies for storing and porting them between machines.
Versioning
For a while I tried putting my dotfiles into a Dropbox subfolder, symlinking the stored versions to the original place:
ln -s ~/Dropbox/dotfiles/.vimrc ~
However, unless you are always online and never use a pc on a train or on a plane, Dropbox cannot scale as it is not capable of solving conflicts. Given the plain text format of these files, we can treat them as source code and version them with the same tools that store Java and PHP code.
mkdir .dotfiles mv .vimrc .dotfiles ln -s ~/.dotfiles/.vimrc . cd .dotfiles git init git add . git commit -m "Added .vimrc" git remote add origin git@github.com:giorgiosironi/dotfiles.git git push -u origin master
Hosting dotfiles on GitHub is common (I learned it from @bittastic) and we usually do not have trade secrets embedded in them. It's not really an open source move as it's difficult to reuse uncommented tricks embedded in someone else's dotfiles; still, it relieves you from backups and the setup of private Git repositories.
Git submodules
Once you have jumped into Git, you can use its submodule capabilities to pull in other repositories for simpler updating of external dependencies (such as Vim plugins). Here is my Vim Pathogen installation:
[08:04:10][giorgio@Galen:~/.dotfiles]$ git submodule c1646e3c28d75bcc834af4836f4c6e12296ba891 .vim/bundle/ctrlp.vim (1.78-67-gc1646e3) 22b4f2073bf16679b31578bb64289ea304573e47 .vim/bundle/snipmate-snippets.git (heads/master) d209d220358d67d630c6f166d277b88ed9e480c6 .vim/bundle/snipmate.vim (heads/master) ac67114efa4f436a3580f5cbb3168aaa13011fc8 .vim/bundle/syntastic.vim (2.2.0-513-gac67114) ...
Some of these modules were actually dependencies of one of the plugins. I didn't find a better solution than installing them alongside their dependent module as there is no Composer or npm for .vim bundles. Or is there?
Installation script
Once you're porting the dotfiles from one machine to another, it becomes boring to create all the links by hand. Furthermore, you may also have to perform additional actions such as a git submodule update -i.
So store a simple .sh script at the toplevel of your dotfile repository, which does the following:
git submodule update -i ln -s ${PWD}/.vimrc ~ ln -s ${PWD}/.bashrc ~ ...
Linking one or two files may not seem an hassle, but as their number grow and you start producing virtual machines instead of physical ones, it's the only solution that scales.
Template method
Your files aren't probably going to be perfectly identical on all machines. In some you may need to look for commands in different paths; or defining different AVA_HOME variables.
As an example, consider my need for setting up differently colored prompts on different machines (for example red or green). It's a surefire way to distinguish which machine you're logged in and it's faster than reading the hostname in the prompt: one shell with a red prompt next to other 3 with a green prompt really stand out as that production server where you should be careful in running commands.
The Template Method pattern can be applied with dotfiles too; you do not even need to define an hook method to be called in external files, but often just environmental variables.
In the case of coloring prompts, .bashrc contains:
C_RED="\[\033[0;31m\]" C_GREEN="\[\033[0;32m\]" C_LIGHT_GRAY="\[\033[0;37m\]" C_RESET="\[\033[0m\]" COLOR=${C_RESET} source ~/.bash_prompt PS1=$COLOR
The installation script performs a:
touch ~/.bash_prompt
And after an empty file has been produced you can put a customization in there:
COLOR=$C_RED
If you do not need to override the prompt color on that machines, there is still a default (COLOR=${C_RESET)) so that the setup script always creates a valid combination of dotfiles without further intervention being necessary.
Some .bashrc examples
Don't know what to put into your .bashrc? Here are some examples:
# Aliases for frequently used or long commands alias agi='sudo apt-get install' # Adding folders to the path to use some additional binaries PATH="~/bin:${PATH}" # Exporting environmental variables which will be available to all scripts JAVA_HOME=/usr/lib/jvm/java-6-openjdk/ export JAVA_HOME # Grep default options, that you don't have to type with the command export GREP_OPTIONS='--color=auto' GREP_OPTIONS= for PATTERN in .cvs .git .hg .svn .work; do GREP_OPTIONS="$GREP_OPTIONS --exclude-dir=$PATTERN" done export GREP_OPTIONS
The .vimrc would take a lot more to explain, and can be an article (or a book) by itself...
Opinions expressed by DZone contributors are their own.
Comments